ActivityManagerService.java revision 93baa0ed9b6b582e28454a4c636b2bfc91d90fcf
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;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.IActivityContainer;
37import android.app.IActivityContainerCallback;
38import android.app.IAppTask;
39import android.app.admin.DevicePolicyManager;
40import android.app.usage.UsageEvents;
41import android.app.usage.UsageStatsManagerInternal;
42import android.appwidget.AppWidgetManager;
43import android.graphics.Rect;
44import android.os.BatteryStats;
45import android.os.PersistableBundle;
46import android.service.voice.IVoiceInteractionSession;
47import android.util.ArrayMap;
48import android.util.ArraySet;
49import android.util.SparseIntArray;
50
51import com.android.internal.R;
52import com.android.internal.annotations.GuardedBy;
53import com.android.internal.app.IAppOpsService;
54import com.android.internal.app.IVoiceInteractor;
55import com.android.internal.app.ProcessMap;
56import com.android.internal.app.ProcessStats;
57import com.android.internal.content.PackageMonitor;
58import com.android.internal.os.BackgroundThread;
59import com.android.internal.os.BatteryStatsImpl;
60import com.android.internal.os.ProcessCpuTracker;
61import com.android.internal.os.TransferPipe;
62import com.android.internal.os.Zygote;
63import com.android.internal.util.FastPrintWriter;
64import com.android.internal.util.FastXmlSerializer;
65import com.android.internal.util.MemInfoReader;
66import com.android.internal.util.Preconditions;
67import com.android.server.AppOpsService;
68import com.android.server.AttributeCache;
69import com.android.server.IntentResolver;
70import com.android.server.LocalServices;
71import com.android.server.ServiceThread;
72import com.android.server.SystemService;
73import com.android.server.SystemServiceManager;
74import com.android.server.Watchdog;
75import com.android.server.am.ActivityStack.ActivityState;
76import com.android.server.firewall.IntentFirewall;
77import com.android.server.pm.UserManagerService;
78import com.android.server.wm.AppTransition;
79import com.android.server.wm.WindowManagerService;
80import com.google.android.collect.Lists;
81import com.google.android.collect.Maps;
82
83import libcore.io.IoUtils;
84
85import org.xmlpull.v1.XmlPullParser;
86import org.xmlpull.v1.XmlPullParserException;
87import org.xmlpull.v1.XmlSerializer;
88
89import android.app.Activity;
90import android.app.ActivityManager;
91import android.app.ActivityManager.RunningTaskInfo;
92import android.app.ActivityManager.StackInfo;
93import android.app.ActivityManagerInternal;
94import android.app.ActivityManagerNative;
95import android.app.ActivityOptions;
96import android.app.ActivityThread;
97import android.app.AlertDialog;
98import android.app.AppGlobals;
99import android.app.ApplicationErrorReport;
100import android.app.Dialog;
101import android.app.IActivityController;
102import android.app.IApplicationThread;
103import android.app.IInstrumentationWatcher;
104import android.app.INotificationManager;
105import android.app.IProcessObserver;
106import android.app.IServiceConnection;
107import android.app.IStopUserCallback;
108import android.app.IUiAutomationConnection;
109import android.app.IUserSwitchObserver;
110import android.app.Instrumentation;
111import android.app.Notification;
112import android.app.NotificationManager;
113import android.app.PendingIntent;
114import android.app.backup.IBackupManager;
115import android.content.ActivityNotFoundException;
116import android.content.BroadcastReceiver;
117import android.content.ClipData;
118import android.content.ComponentCallbacks2;
119import android.content.ComponentName;
120import android.content.ContentProvider;
121import android.content.ContentResolver;
122import android.content.Context;
123import android.content.DialogInterface;
124import android.content.IContentProvider;
125import android.content.IIntentReceiver;
126import android.content.IIntentSender;
127import android.content.Intent;
128import android.content.IntentFilter;
129import android.content.IntentSender;
130import android.content.pm.ActivityInfo;
131import android.content.pm.ApplicationInfo;
132import android.content.pm.ConfigurationInfo;
133import android.content.pm.IPackageDataObserver;
134import android.content.pm.IPackageManager;
135import android.content.pm.InstrumentationInfo;
136import android.content.pm.PackageInfo;
137import android.content.pm.PackageManager;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.UserInfo;
140import android.content.pm.PackageManager.NameNotFoundException;
141import android.content.pm.PathPermission;
142import android.content.pm.ProviderInfo;
143import android.content.pm.ResolveInfo;
144import android.content.pm.ServiceInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.net.Proxy;
148import android.net.ProxyInfo;
149import android.net.Uri;
150import android.os.Binder;
151import android.os.Build;
152import android.os.Bundle;
153import android.os.Debug;
154import android.os.DropBoxManager;
155import android.os.Environment;
156import android.os.FactoryTest;
157import android.os.FileObserver;
158import android.os.FileUtils;
159import android.os.Handler;
160import android.os.IBinder;
161import android.os.IPermissionController;
162import android.os.IRemoteCallback;
163import android.os.IUserManager;
164import android.os.Looper;
165import android.os.Message;
166import android.os.Parcel;
167import android.os.ParcelFileDescriptor;
168import android.os.Process;
169import android.os.RemoteCallbackList;
170import android.os.RemoteException;
171import android.os.SELinux;
172import android.os.ServiceManager;
173import android.os.StrictMode;
174import android.os.SystemClock;
175import android.os.SystemProperties;
176import android.os.UpdateLock;
177import android.os.UserHandle;
178import android.provider.Settings;
179import android.text.format.DateUtils;
180import android.text.format.Time;
181import android.util.AtomicFile;
182import android.util.EventLog;
183import android.util.Log;
184import android.util.Pair;
185import android.util.PrintWriterPrinter;
186import android.util.Slog;
187import android.util.SparseArray;
188import android.util.TimeUtils;
189import android.util.Xml;
190import android.view.Gravity;
191import android.view.LayoutInflater;
192import android.view.View;
193import android.view.WindowManager;
194
195import java.io.BufferedInputStream;
196import java.io.BufferedOutputStream;
197import java.io.DataInputStream;
198import java.io.DataOutputStream;
199import java.io.File;
200import java.io.FileDescriptor;
201import java.io.FileInputStream;
202import java.io.FileNotFoundException;
203import java.io.FileOutputStream;
204import java.io.IOException;
205import java.io.InputStreamReader;
206import java.io.PrintWriter;
207import java.io.StringWriter;
208import java.lang.ref.WeakReference;
209import java.util.ArrayList;
210import java.util.Arrays;
211import java.util.Collections;
212import java.util.Comparator;
213import java.util.HashMap;
214import java.util.HashSet;
215import java.util.Iterator;
216import java.util.List;
217import java.util.Locale;
218import java.util.Map;
219import java.util.Set;
220import java.util.concurrent.atomic.AtomicBoolean;
221import java.util.concurrent.atomic.AtomicLong;
222
223public final class ActivityManagerService extends ActivityManagerNative
224        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
225
226    private static final String USER_DATA_DIR = "/data/user/";
227    // File that stores last updated system version and called preboot receivers
228    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
229
230    static final String TAG = "ActivityManager";
231    static final String TAG_MU = "ActivityManagerServiceMU";
232    static final boolean DEBUG = false;
233    static final boolean localLOGV = DEBUG;
234    static final boolean DEBUG_BACKUP = localLOGV || false;
235    static final boolean DEBUG_BROADCAST = localLOGV || false;
236    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
237    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
238    static final boolean DEBUG_CLEANUP = localLOGV || false;
239    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
240    static final boolean DEBUG_FOCUS = false;
241    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
242    static final boolean DEBUG_MU = localLOGV || false;
243    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
244    static final boolean DEBUG_LRU = localLOGV || false;
245    static final boolean DEBUG_PAUSE = localLOGV || false;
246    static final boolean DEBUG_POWER = localLOGV || false;
247    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
248    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
249    static final boolean DEBUG_PROCESSES = localLOGV || false;
250    static final boolean DEBUG_PROVIDER = localLOGV || false;
251    static final boolean DEBUG_RESULTS = localLOGV || false;
252    static final boolean DEBUG_SERVICE = localLOGV || false;
253    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
254    static final boolean DEBUG_STACK = localLOGV || false;
255    static final boolean DEBUG_SWITCH = localLOGV || false;
256    static final boolean DEBUG_TASKS = localLOGV || false;
257    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
258    static final boolean DEBUG_TRANSITION = localLOGV || false;
259    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
260    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
261    static final boolean DEBUG_VISBILITY = localLOGV || false;
262    static final boolean DEBUG_PSS = localLOGV || false;
263    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
264    static final boolean VALIDATE_TOKENS = false;
265    static final boolean SHOW_ACTIVITY_START_TIME = true;
266
267    // Control over CPU and battery monitoring.
268    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
269    static final boolean MONITOR_CPU_USAGE = true;
270    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
271    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
272    static final boolean MONITOR_THREAD_CPU_USAGE = false;
273
274    // The flags that are set for all calls we make to the package manager.
275    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
276
277    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
278
279    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
280
281    // Maximum number of recent tasks that we can remember.
282    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
283
284    // Maximum number recent bitmaps to keep in memory.
285    static final int MAX_RECENT_BITMAPS = 5;
286
287    // Amount of time after a call to stopAppSwitches() during which we will
288    // prevent further untrusted switches from happening.
289    static final long APP_SWITCH_DELAY_TIME = 5*1000;
290
291    // How long we wait for a launched process to attach to the activity manager
292    // before we decide it's never going to come up for real.
293    static final int PROC_START_TIMEOUT = 10*1000;
294
295    // How long we wait for a launched process to attach to the activity manager
296    // before we decide it's never going to come up for real, when the process was
297    // started with a wrapper for instrumentation (such as Valgrind) because it
298    // could take much longer than usual.
299    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
300
301    // How long to wait after going idle before forcing apps to GC.
302    static final int GC_TIMEOUT = 5*1000;
303
304    // The minimum amount of time between successive GC requests for a process.
305    static final int GC_MIN_INTERVAL = 60*1000;
306
307    // The minimum amount of time between successive PSS requests for a process.
308    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
309
310    // The minimum amount of time between successive PSS requests for a process
311    // when the request is due to the memory state being lowered.
312    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
313
314    // The rate at which we check for apps using excessive power -- 15 mins.
315    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
316
317    // The minimum sample duration we will allow before deciding we have
318    // enough data on wake locks to start killing things.
319    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
320
321    // The minimum sample duration we will allow before deciding we have
322    // enough data on CPU usage to start killing things.
323    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
324
325    // How long we allow a receiver to run before giving up on it.
326    static final int BROADCAST_FG_TIMEOUT = 10*1000;
327    static final int BROADCAST_BG_TIMEOUT = 60*1000;
328
329    // How long we wait until we timeout on key dispatching.
330    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
331
332    // How long we wait until we timeout on key dispatching during instrumentation.
333    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
334
335    // Amount of time we wait for observers to handle a user switch before
336    // giving up on them and unfreezing the screen.
337    static final int USER_SWITCH_TIMEOUT = 2*1000;
338
339    // Maximum number of users we allow to be running at a time.
340    static final int MAX_RUNNING_USERS = 3;
341
342    // How long to wait in getAssistContextExtras for the activity and foreground services
343    // to respond with the result.
344    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
345
346    // Maximum number of persisted Uri grants a package is allowed
347    static final int MAX_PERSISTED_URI_GRANTS = 128;
348
349    static final int MY_PID = Process.myPid();
350
351    static final String[] EMPTY_STRING_ARRAY = new String[0];
352
353    // How many bytes to write into the dropbox log before truncating
354    static final int DROPBOX_MAX_SIZE = 256 * 1024;
355
356    // Access modes for handleIncomingUser.
357    static final int ALLOW_NON_FULL = 0;
358    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
359    static final int ALLOW_FULL_ONLY = 2;
360
361    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
362
363    /** All system services */
364    SystemServiceManager mSystemServiceManager;
365
366    /** Run all ActivityStacks through this */
367    ActivityStackSupervisor mStackSupervisor;
368
369    public IntentFirewall mIntentFirewall;
370
371    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
372    // default actuion automatically.  Important for devices without direct input
373    // devices.
374    private boolean mShowDialogs = true;
375
376    BroadcastQueue mFgBroadcastQueue;
377    BroadcastQueue mBgBroadcastQueue;
378    // Convenient for easy iteration over the queues. Foreground is first
379    // so that dispatch of foreground broadcasts gets precedence.
380    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
381
382    BroadcastQueue broadcastQueueForIntent(Intent intent) {
383        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
384        if (DEBUG_BACKGROUND_BROADCAST) {
385            Slog.i(TAG, "Broadcast intent " + intent + " on "
386                    + (isFg ? "foreground" : "background")
387                    + " queue");
388        }
389        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
390    }
391
392    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
393        for (BroadcastQueue queue : mBroadcastQueues) {
394            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
395            if (r != null) {
396                return r;
397            }
398        }
399        return null;
400    }
401
402    /**
403     * Activity we have told the window manager to have key focus.
404     */
405    ActivityRecord mFocusedActivity = null;
406
407    /**
408     * List of intents that were used to start the most recent tasks.
409     */
410    ArrayList<TaskRecord> mRecentTasks;
411    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
412
413    public class PendingAssistExtras extends Binder implements Runnable {
414        public final ActivityRecord activity;
415        public boolean haveResult = false;
416        public Bundle result = null;
417        public PendingAssistExtras(ActivityRecord _activity) {
418            activity = _activity;
419        }
420        @Override
421        public void run() {
422            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
423            synchronized (this) {
424                haveResult = true;
425                notifyAll();
426            }
427        }
428    }
429
430    final ArrayList<PendingAssistExtras> mPendingAssistExtras
431            = new ArrayList<PendingAssistExtras>();
432
433    /**
434     * Process management.
435     */
436    final ProcessList mProcessList = new ProcessList();
437
438    /**
439     * All of the applications we currently have running organized by name.
440     * The keys are strings of the application package name (as
441     * returned by the package manager), and the keys are ApplicationRecord
442     * objects.
443     */
444    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
445
446    /**
447     * Tracking long-term execution of processes to look for abuse and other
448     * bad app behavior.
449     */
450    final ProcessStatsService mProcessStats;
451
452    /**
453     * The currently running isolated processes.
454     */
455    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
456
457    /**
458     * Counter for assigning isolated process uids, to avoid frequently reusing the
459     * same ones.
460     */
461    int mNextIsolatedProcessUid = 0;
462
463    /**
464     * The currently running heavy-weight process, if any.
465     */
466    ProcessRecord mHeavyWeightProcess = null;
467
468    /**
469     * The last time that various processes have crashed.
470     */
471    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
472
473    /**
474     * Information about a process that is currently marked as bad.
475     */
476    static final class BadProcessInfo {
477        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
478            this.time = time;
479            this.shortMsg = shortMsg;
480            this.longMsg = longMsg;
481            this.stack = stack;
482        }
483
484        final long time;
485        final String shortMsg;
486        final String longMsg;
487        final String stack;
488    }
489
490    /**
491     * Set of applications that we consider to be bad, and will reject
492     * incoming broadcasts from (which the user has no control over).
493     * Processes are added to this set when they have crashed twice within
494     * a minimum amount of time; they are removed from it when they are
495     * later restarted (hopefully due to some user action).  The value is the
496     * time it was added to the list.
497     */
498    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
499
500    /**
501     * All of the processes we currently have running organized by pid.
502     * The keys are the pid running the application.
503     *
504     * <p>NOTE: This object is protected by its own lock, NOT the global
505     * activity manager lock!
506     */
507    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
508
509    /**
510     * All of the processes that have been forced to be foreground.  The key
511     * is the pid of the caller who requested it (we hold a death
512     * link on it).
513     */
514    abstract class ForegroundToken implements IBinder.DeathRecipient {
515        int pid;
516        IBinder token;
517    }
518    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
519
520    /**
521     * List of records for processes that someone had tried to start before the
522     * system was ready.  We don't start them at that point, but ensure they
523     * are started by the time booting is complete.
524     */
525    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
526
527    /**
528     * List of persistent applications that are in the process
529     * of being started.
530     */
531    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
532
533    /**
534     * Processes that are being forcibly torn down.
535     */
536    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
537
538    /**
539     * List of running applications, sorted by recent usage.
540     * The first entry in the list is the least recently used.
541     */
542    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
543
544    /**
545     * Where in mLruProcesses that the processes hosting activities start.
546     */
547    int mLruProcessActivityStart = 0;
548
549    /**
550     * Where in mLruProcesses that the processes hosting services start.
551     * This is after (lower index) than mLruProcessesActivityStart.
552     */
553    int mLruProcessServiceStart = 0;
554
555    /**
556     * List of processes that should gc as soon as things are idle.
557     */
558    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
559
560    /**
561     * Processes we want to collect PSS data from.
562     */
563    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
564
565    /**
566     * Last time we requested PSS data of all processes.
567     */
568    long mLastFullPssTime = SystemClock.uptimeMillis();
569
570    /**
571     * If set, the next time we collect PSS data we should do a full collection
572     * with data from native processes and the kernel.
573     */
574    boolean mFullPssPending = false;
575
576    /**
577     * This is the process holding what we currently consider to be
578     * the "home" activity.
579     */
580    ProcessRecord mHomeProcess;
581
582    /**
583     * This is the process holding the activity the user last visited that
584     * is in a different process from the one they are currently in.
585     */
586    ProcessRecord mPreviousProcess;
587
588    /**
589     * The time at which the previous process was last visible.
590     */
591    long mPreviousProcessVisibleTime;
592
593    /**
594     * Which uses have been started, so are allowed to run code.
595     */
596    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
597
598    /**
599     * LRU list of history of current users.  Most recently current is at the end.
600     */
601    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
602
603    /**
604     * Constant array of the users that are currently started.
605     */
606    int[] mStartedUserArray = new int[] { 0 };
607
608    /**
609     * Registered observers of the user switching mechanics.
610     */
611    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
612            = new RemoteCallbackList<IUserSwitchObserver>();
613
614    /**
615     * Currently active user switch.
616     */
617    Object mCurUserSwitchCallback;
618
619    /**
620     * Packages that the user has asked to have run in screen size
621     * compatibility mode instead of filling the screen.
622     */
623    final CompatModePackages mCompatModePackages;
624
625    /**
626     * Set of IntentSenderRecord objects that are currently active.
627     */
628    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
629            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
630
631    /**
632     * Fingerprints (hashCode()) of stack traces that we've
633     * already logged DropBox entries for.  Guarded by itself.  If
634     * something (rogue user app) forces this over
635     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
636     */
637    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
638    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
639
640    /**
641     * Strict Mode background batched logging state.
642     *
643     * The string buffer is guarded by itself, and its lock is also
644     * used to determine if another batched write is already
645     * in-flight.
646     */
647    private final StringBuilder mStrictModeBuffer = new StringBuilder();
648
649    /**
650     * Keeps track of all IIntentReceivers that have been registered for
651     * broadcasts.  Hash keys are the receiver IBinder, hash value is
652     * a ReceiverList.
653     */
654    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
655            new HashMap<IBinder, ReceiverList>();
656
657    /**
658     * Resolver for broadcast intents to registered receivers.
659     * Holds BroadcastFilter (subclass of IntentFilter).
660     */
661    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
662            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
663        @Override
664        protected boolean allowFilterResult(
665                BroadcastFilter filter, List<BroadcastFilter> dest) {
666            IBinder target = filter.receiverList.receiver.asBinder();
667            for (int i=dest.size()-1; i>=0; i--) {
668                if (dest.get(i).receiverList.receiver.asBinder() == target) {
669                    return false;
670                }
671            }
672            return true;
673        }
674
675        @Override
676        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
677            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
678                    || userId == filter.owningUserId) {
679                return super.newResult(filter, match, userId);
680            }
681            return null;
682        }
683
684        @Override
685        protected BroadcastFilter[] newArray(int size) {
686            return new BroadcastFilter[size];
687        }
688
689        @Override
690        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
691            return packageName.equals(filter.packageName);
692        }
693    };
694
695    /**
696     * State of all active sticky broadcasts per user.  Keys are the action of the
697     * sticky Intent, values are an ArrayList of all broadcasted intents with
698     * that action (which should usually be one).  The SparseArray is keyed
699     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
700     * for stickies that are sent to all users.
701     */
702    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
703            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
704
705    final ActiveServices mServices;
706
707    /**
708     * Backup/restore process management
709     */
710    String mBackupAppName = null;
711    BackupRecord mBackupTarget = null;
712
713    final ProviderMap mProviderMap;
714
715    /**
716     * List of content providers who have clients waiting for them.  The
717     * application is currently being launched and the provider will be
718     * removed from this list once it is published.
719     */
720    final ArrayList<ContentProviderRecord> mLaunchingProviders
721            = new ArrayList<ContentProviderRecord>();
722
723    /**
724     * File storing persisted {@link #mGrantedUriPermissions}.
725     */
726    private final AtomicFile mGrantFile;
727
728    /** XML constants used in {@link #mGrantFile} */
729    private static final String TAG_URI_GRANTS = "uri-grants";
730    private static final String TAG_URI_GRANT = "uri-grant";
731    private static final String ATTR_USER_HANDLE = "userHandle";
732    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
733    private static final String ATTR_TARGET_USER_ID = "targetUserId";
734    private static final String ATTR_SOURCE_PKG = "sourcePkg";
735    private static final String ATTR_TARGET_PKG = "targetPkg";
736    private static final String ATTR_URI = "uri";
737    private static final String ATTR_MODE_FLAGS = "modeFlags";
738    private static final String ATTR_CREATED_TIME = "createdTime";
739    private static final String ATTR_PREFIX = "prefix";
740
741    /**
742     * Global set of specific {@link Uri} permissions that have been granted.
743     * This optimized lookup structure maps from {@link UriPermission#targetUid}
744     * to {@link UriPermission#uri} to {@link UriPermission}.
745     */
746    @GuardedBy("this")
747    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
748            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
749
750    public static class GrantUri {
751        public final int sourceUserId;
752        public final Uri uri;
753        public boolean prefix;
754
755        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
756            this.sourceUserId = sourceUserId;
757            this.uri = uri;
758            this.prefix = prefix;
759        }
760
761        @Override
762        public int hashCode() {
763            return toString().hashCode();
764        }
765
766        @Override
767        public boolean equals(Object o) {
768            if (o instanceof GrantUri) {
769                GrantUri other = (GrantUri) o;
770                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
771                        && prefix == other.prefix;
772            }
773            return false;
774        }
775
776        @Override
777        public String toString() {
778            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
779            if (prefix) result += " [prefix]";
780            return result;
781        }
782
783        public String toSafeString() {
784            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
785            if (prefix) result += " [prefix]";
786            return result;
787        }
788
789        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
790            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
791                    ContentProvider.getUriWithoutUserId(uri), false);
792        }
793    }
794
795    CoreSettingsObserver mCoreSettingsObserver;
796
797    /**
798     * Thread-local storage used to carry caller permissions over through
799     * indirect content-provider access.
800     */
801    private class Identity {
802        public int pid;
803        public int uid;
804
805        Identity(int _pid, int _uid) {
806            pid = _pid;
807            uid = _uid;
808        }
809    }
810
811    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
812
813    /**
814     * All information we have collected about the runtime performance of
815     * any user id that can impact battery performance.
816     */
817    final BatteryStatsService mBatteryStatsService;
818
819    /**
820     * Information about component usage
821     */
822    UsageStatsManagerInternal mUsageStatsService;
823
824    /**
825     * Information about and control over application operations
826     */
827    final AppOpsService mAppOpsService;
828
829    /**
830     * Save recent tasks information across reboots.
831     */
832    final TaskPersister mTaskPersister;
833
834    /**
835     * Current configuration information.  HistoryRecord objects are given
836     * a reference to this object to indicate which configuration they are
837     * currently running in, so this object must be kept immutable.
838     */
839    Configuration mConfiguration = new Configuration();
840
841    /**
842     * Current sequencing integer of the configuration, for skipping old
843     * configurations.
844     */
845    int mConfigurationSeq = 0;
846
847    /**
848     * Hardware-reported OpenGLES version.
849     */
850    final int GL_ES_VERSION;
851
852    /**
853     * List of initialization arguments to pass to all processes when binding applications to them.
854     * For example, references to the commonly used services.
855     */
856    HashMap<String, IBinder> mAppBindArgs;
857
858    /**
859     * Temporary to avoid allocations.  Protected by main lock.
860     */
861    final StringBuilder mStringBuilder = new StringBuilder(256);
862
863    /**
864     * Used to control how we initialize the service.
865     */
866    ComponentName mTopComponent;
867    String mTopAction = Intent.ACTION_MAIN;
868    String mTopData;
869    boolean mProcessesReady = false;
870    boolean mSystemReady = false;
871    boolean mBooting = false;
872    boolean mWaitingUpdate = false;
873    boolean mDidUpdate = false;
874    boolean mOnBattery = false;
875    boolean mLaunchWarningShown = false;
876
877    Context mContext;
878
879    int mFactoryTest;
880
881    boolean mCheckedForSetup;
882
883    /**
884     * The time at which we will allow normal application switches again,
885     * after a call to {@link #stopAppSwitches()}.
886     */
887    long mAppSwitchesAllowedTime;
888
889    /**
890     * This is set to true after the first switch after mAppSwitchesAllowedTime
891     * is set; any switches after that will clear the time.
892     */
893    boolean mDidAppSwitch;
894
895    /**
896     * Last time (in realtime) at which we checked for power usage.
897     */
898    long mLastPowerCheckRealtime;
899
900    /**
901     * Last time (in uptime) at which we checked for power usage.
902     */
903    long mLastPowerCheckUptime;
904
905    /**
906     * Set while we are wanting to sleep, to prevent any
907     * activities from being started/resumed.
908     */
909    private boolean mSleeping = false;
910
911    /**
912     * Set while we are running a voice interaction.  This overrides
913     * sleeping while it is active.
914     */
915    private boolean mRunningVoice = false;
916
917    /**
918     * State of external calls telling us if the device is asleep.
919     */
920    private boolean mWentToSleep = false;
921
922    /**
923     * State of external call telling us if the lock screen is shown.
924     */
925    private boolean mLockScreenShown = false;
926
927    /**
928     * Set if we are shutting down the system, similar to sleeping.
929     */
930    boolean mShuttingDown = false;
931
932    /**
933     * Current sequence id for oom_adj computation traversal.
934     */
935    int mAdjSeq = 0;
936
937    /**
938     * Current sequence id for process LRU updating.
939     */
940    int mLruSeq = 0;
941
942    /**
943     * Keep track of the non-cached/empty process we last found, to help
944     * determine how to distribute cached/empty processes next time.
945     */
946    int mNumNonCachedProcs = 0;
947
948    /**
949     * Keep track of the number of cached hidden procs, to balance oom adj
950     * distribution between those and empty procs.
951     */
952    int mNumCachedHiddenProcs = 0;
953
954    /**
955     * Keep track of the number of service processes we last found, to
956     * determine on the next iteration which should be B services.
957     */
958    int mNumServiceProcs = 0;
959    int mNewNumAServiceProcs = 0;
960    int mNewNumServiceProcs = 0;
961
962    /**
963     * Allow the current computed overall memory level of the system to go down?
964     * This is set to false when we are killing processes for reasons other than
965     * memory management, so that the now smaller process list will not be taken as
966     * an indication that memory is tighter.
967     */
968    boolean mAllowLowerMemLevel = false;
969
970    /**
971     * The last computed memory level, for holding when we are in a state that
972     * processes are going away for other reasons.
973     */
974    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
975
976    /**
977     * The last total number of process we have, to determine if changes actually look
978     * like a shrinking number of process due to lower RAM.
979     */
980    int mLastNumProcesses;
981
982    /**
983     * The uptime of the last time we performed idle maintenance.
984     */
985    long mLastIdleTime = SystemClock.uptimeMillis();
986
987    /**
988     * Total time spent with RAM that has been added in the past since the last idle time.
989     */
990    long mLowRamTimeSinceLastIdle = 0;
991
992    /**
993     * If RAM is currently low, when that horrible situation started.
994     */
995    long mLowRamStartTime = 0;
996
997    /**
998     * For reporting to battery stats the current top application.
999     */
1000    private String mCurResumedPackage = null;
1001    private int mCurResumedUid = -1;
1002
1003    /**
1004     * For reporting to battery stats the apps currently running foreground
1005     * service.  The ProcessMap is package/uid tuples; each of these contain
1006     * an array of the currently foreground processes.
1007     */
1008    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1009            = new ProcessMap<ArrayList<ProcessRecord>>();
1010
1011    /**
1012     * This is set if we had to do a delayed dexopt of an app before launching
1013     * it, to increase the ANR timeouts in that case.
1014     */
1015    boolean mDidDexOpt;
1016
1017    /**
1018     * Set if the systemServer made a call to enterSafeMode.
1019     */
1020    boolean mSafeMode;
1021
1022    String mDebugApp = null;
1023    boolean mWaitForDebugger = false;
1024    boolean mDebugTransient = false;
1025    String mOrigDebugApp = null;
1026    boolean mOrigWaitForDebugger = false;
1027    boolean mAlwaysFinishActivities = false;
1028    IActivityController mController = null;
1029    String mProfileApp = null;
1030    ProcessRecord mProfileProc = null;
1031    String mProfileFile;
1032    ParcelFileDescriptor mProfileFd;
1033    int mProfileType = 0;
1034    boolean mAutoStopProfiler = false;
1035    String mOpenGlTraceApp = null;
1036
1037    static class ProcessChangeItem {
1038        static final int CHANGE_ACTIVITIES = 1<<0;
1039        static final int CHANGE_PROCESS_STATE = 1<<1;
1040        int changes;
1041        int uid;
1042        int pid;
1043        int processState;
1044        boolean foregroundActivities;
1045    }
1046
1047    final RemoteCallbackList<IProcessObserver> mProcessObservers
1048            = new RemoteCallbackList<IProcessObserver>();
1049    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1050
1051    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1052            = new ArrayList<ProcessChangeItem>();
1053    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1054            = new ArrayList<ProcessChangeItem>();
1055
1056    /**
1057     * Runtime CPU use collection thread.  This object's lock is used to
1058     * protect all related state.
1059     */
1060    final Thread mProcessCpuThread;
1061
1062    /**
1063     * Used to collect process stats when showing not responding dialog.
1064     * Protected by mProcessCpuThread.
1065     */
1066    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1067            MONITOR_THREAD_CPU_USAGE);
1068    final AtomicLong mLastCpuTime = new AtomicLong(0);
1069    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1070
1071    long mLastWriteTime = 0;
1072
1073    /**
1074     * Used to retain an update lock when the foreground activity is in
1075     * immersive mode.
1076     */
1077    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1078
1079    /**
1080     * Set to true after the system has finished booting.
1081     */
1082    boolean mBooted = false;
1083
1084    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1085    int mProcessLimitOverride = -1;
1086
1087    WindowManagerService mWindowManager;
1088
1089    final ActivityThread mSystemThread;
1090
1091    int mCurrentUserId = 0;
1092    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1093
1094    /**
1095     * Mapping from each known user ID to the profile group ID it is associated with.
1096     */
1097    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1098
1099    private UserManagerService mUserManager;
1100
1101    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1102        final ProcessRecord mApp;
1103        final int mPid;
1104        final IApplicationThread mAppThread;
1105
1106        AppDeathRecipient(ProcessRecord app, int pid,
1107                IApplicationThread thread) {
1108            if (localLOGV) Slog.v(
1109                TAG, "New death recipient " + this
1110                + " for thread " + thread.asBinder());
1111            mApp = app;
1112            mPid = pid;
1113            mAppThread = thread;
1114        }
1115
1116        @Override
1117        public void binderDied() {
1118            if (localLOGV) Slog.v(
1119                TAG, "Death received in " + this
1120                + " for thread " + mAppThread.asBinder());
1121            synchronized(ActivityManagerService.this) {
1122                appDiedLocked(mApp, mPid, mAppThread);
1123            }
1124        }
1125    }
1126
1127    static final int SHOW_ERROR_MSG = 1;
1128    static final int SHOW_NOT_RESPONDING_MSG = 2;
1129    static final int SHOW_FACTORY_ERROR_MSG = 3;
1130    static final int UPDATE_CONFIGURATION_MSG = 4;
1131    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1132    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1133    static final int SERVICE_TIMEOUT_MSG = 12;
1134    static final int UPDATE_TIME_ZONE = 13;
1135    static final int SHOW_UID_ERROR_MSG = 14;
1136    static final int IM_FEELING_LUCKY_MSG = 15;
1137    static final int PROC_START_TIMEOUT_MSG = 20;
1138    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1139    static final int KILL_APPLICATION_MSG = 22;
1140    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1141    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1142    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1143    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1144    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1145    static final int CLEAR_DNS_CACHE_MSG = 28;
1146    static final int UPDATE_HTTP_PROXY_MSG = 29;
1147    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1148    static final int DISPATCH_PROCESSES_CHANGED = 31;
1149    static final int DISPATCH_PROCESS_DIED = 32;
1150    static final int REPORT_MEM_USAGE_MSG = 33;
1151    static final int REPORT_USER_SWITCH_MSG = 34;
1152    static final int CONTINUE_USER_SWITCH_MSG = 35;
1153    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1154    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1155    static final int PERSIST_URI_GRANTS_MSG = 38;
1156    static final int REQUEST_ALL_PSS_MSG = 39;
1157    static final int START_PROFILES_MSG = 40;
1158    static final int UPDATE_TIME = 41;
1159    static final int SYSTEM_USER_START_MSG = 42;
1160    static final int SYSTEM_USER_CURRENT_MSG = 43;
1161    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1162    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1163
1164    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1165    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1166    static final int FIRST_COMPAT_MODE_MSG = 300;
1167    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1168
1169    AlertDialog mUidAlert;
1170    CompatModeDialog mCompatModeDialog;
1171    long mLastMemUsageReportTime = 0;
1172
1173    private LockToAppRequestDialog mLockToAppRequest;
1174
1175    /**
1176     * Flag whether the current user is a "monkey", i.e. whether
1177     * the UI is driven by a UI automation tool.
1178     */
1179    private boolean mUserIsMonkey;
1180
1181    /** Flag whether the device has a recents UI */
1182    final boolean mHasRecents;
1183
1184    final ServiceThread mHandlerThread;
1185    final MainHandler mHandler;
1186
1187    final class MainHandler extends Handler {
1188        public MainHandler(Looper looper) {
1189            super(looper, null, true);
1190        }
1191
1192        @Override
1193        public void handleMessage(Message msg) {
1194            switch (msg.what) {
1195            case SHOW_ERROR_MSG: {
1196                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1197                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1198                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1199                synchronized (ActivityManagerService.this) {
1200                    ProcessRecord proc = (ProcessRecord)data.get("app");
1201                    AppErrorResult res = (AppErrorResult) data.get("result");
1202                    if (proc != null && proc.crashDialog != null) {
1203                        Slog.e(TAG, "App already has crash dialog: " + proc);
1204                        if (res != null) {
1205                            res.set(0);
1206                        }
1207                        return;
1208                    }
1209                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1210                            >= Process.FIRST_APPLICATION_UID
1211                            && proc.pid != MY_PID);
1212                    for (int userId : mCurrentProfileIds) {
1213                        isBackground &= (proc.userId != userId);
1214                    }
1215                    if (isBackground && !showBackground) {
1216                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1217                        if (res != null) {
1218                            res.set(0);
1219                        }
1220                        return;
1221                    }
1222                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1223                        Dialog d = new AppErrorDialog(mContext,
1224                                ActivityManagerService.this, res, proc);
1225                        d.show();
1226                        proc.crashDialog = d;
1227                    } else {
1228                        // The device is asleep, so just pretend that the user
1229                        // saw a crash dialog and hit "force quit".
1230                        if (res != null) {
1231                            res.set(0);
1232                        }
1233                    }
1234                }
1235
1236                ensureBootCompleted();
1237            } break;
1238            case SHOW_NOT_RESPONDING_MSG: {
1239                synchronized (ActivityManagerService.this) {
1240                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1241                    ProcessRecord proc = (ProcessRecord)data.get("app");
1242                    if (proc != null && proc.anrDialog != null) {
1243                        Slog.e(TAG, "App already has anr dialog: " + proc);
1244                        return;
1245                    }
1246
1247                    Intent intent = new Intent("android.intent.action.ANR");
1248                    if (!mProcessesReady) {
1249                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1250                                | Intent.FLAG_RECEIVER_FOREGROUND);
1251                    }
1252                    broadcastIntentLocked(null, null, intent,
1253                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1254                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1255
1256                    if (mShowDialogs) {
1257                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1258                                mContext, proc, (ActivityRecord)data.get("activity"),
1259                                msg.arg1 != 0);
1260                        d.show();
1261                        proc.anrDialog = d;
1262                    } else {
1263                        // Just kill the app if there is no dialog to be shown.
1264                        killAppAtUsersRequest(proc, null);
1265                    }
1266                }
1267
1268                ensureBootCompleted();
1269            } break;
1270            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1271                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1272                synchronized (ActivityManagerService.this) {
1273                    ProcessRecord proc = (ProcessRecord) data.get("app");
1274                    if (proc == null) {
1275                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1276                        break;
1277                    }
1278                    if (proc.crashDialog != null) {
1279                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1280                        return;
1281                    }
1282                    AppErrorResult res = (AppErrorResult) data.get("result");
1283                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1284                        Dialog d = new StrictModeViolationDialog(mContext,
1285                                ActivityManagerService.this, res, proc);
1286                        d.show();
1287                        proc.crashDialog = d;
1288                    } else {
1289                        // The device is asleep, so just pretend that the user
1290                        // saw a crash dialog and hit "force quit".
1291                        res.set(0);
1292                    }
1293                }
1294                ensureBootCompleted();
1295            } break;
1296            case SHOW_FACTORY_ERROR_MSG: {
1297                Dialog d = new FactoryErrorDialog(
1298                    mContext, msg.getData().getCharSequence("msg"));
1299                d.show();
1300                ensureBootCompleted();
1301            } break;
1302            case UPDATE_CONFIGURATION_MSG: {
1303                final ContentResolver resolver = mContext.getContentResolver();
1304                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1305            } break;
1306            case GC_BACKGROUND_PROCESSES_MSG: {
1307                synchronized (ActivityManagerService.this) {
1308                    performAppGcsIfAppropriateLocked();
1309                }
1310            } break;
1311            case WAIT_FOR_DEBUGGER_MSG: {
1312                synchronized (ActivityManagerService.this) {
1313                    ProcessRecord app = (ProcessRecord)msg.obj;
1314                    if (msg.arg1 != 0) {
1315                        if (!app.waitedForDebugger) {
1316                            Dialog d = new AppWaitingForDebuggerDialog(
1317                                    ActivityManagerService.this,
1318                                    mContext, app);
1319                            app.waitDialog = d;
1320                            app.waitedForDebugger = true;
1321                            d.show();
1322                        }
1323                    } else {
1324                        if (app.waitDialog != null) {
1325                            app.waitDialog.dismiss();
1326                            app.waitDialog = null;
1327                        }
1328                    }
1329                }
1330            } break;
1331            case SERVICE_TIMEOUT_MSG: {
1332                if (mDidDexOpt) {
1333                    mDidDexOpt = false;
1334                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1335                    nmsg.obj = msg.obj;
1336                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1337                    return;
1338                }
1339                mServices.serviceTimeout((ProcessRecord)msg.obj);
1340            } break;
1341            case UPDATE_TIME_ZONE: {
1342                synchronized (ActivityManagerService.this) {
1343                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1344                        ProcessRecord r = mLruProcesses.get(i);
1345                        if (r.thread != null) {
1346                            try {
1347                                r.thread.updateTimeZone();
1348                            } catch (RemoteException ex) {
1349                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1350                            }
1351                        }
1352                    }
1353                }
1354            } break;
1355            case CLEAR_DNS_CACHE_MSG: {
1356                synchronized (ActivityManagerService.this) {
1357                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1358                        ProcessRecord r = mLruProcesses.get(i);
1359                        if (r.thread != null) {
1360                            try {
1361                                r.thread.clearDnsCache();
1362                            } catch (RemoteException ex) {
1363                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1364                            }
1365                        }
1366                    }
1367                }
1368            } break;
1369            case UPDATE_HTTP_PROXY_MSG: {
1370                ProxyInfo proxy = (ProxyInfo)msg.obj;
1371                String host = "";
1372                String port = "";
1373                String exclList = "";
1374                Uri pacFileUrl = Uri.EMPTY;
1375                if (proxy != null) {
1376                    host = proxy.getHost();
1377                    port = Integer.toString(proxy.getPort());
1378                    exclList = proxy.getExclusionListAsString();
1379                    pacFileUrl = proxy.getPacFileUrl();
1380                }
1381                synchronized (ActivityManagerService.this) {
1382                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1383                        ProcessRecord r = mLruProcesses.get(i);
1384                        if (r.thread != null) {
1385                            try {
1386                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1387                            } catch (RemoteException ex) {
1388                                Slog.w(TAG, "Failed to update http proxy for: " +
1389                                        r.info.processName);
1390                            }
1391                        }
1392                    }
1393                }
1394            } break;
1395            case SHOW_UID_ERROR_MSG: {
1396                String title = "System UIDs Inconsistent";
1397                String text = "UIDs on the system are inconsistent, you need to wipe your"
1398                        + " data partition or your device will be unstable.";
1399                Log.e(TAG, title + ": " + text);
1400                if (mShowDialogs) {
1401                    // XXX This is a temporary dialog, no need to localize.
1402                    AlertDialog d = new BaseErrorDialog(mContext);
1403                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1404                    d.setCancelable(false);
1405                    d.setTitle(title);
1406                    d.setMessage(text);
1407                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1408                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1409                    mUidAlert = d;
1410                    d.show();
1411                }
1412            } break;
1413            case IM_FEELING_LUCKY_MSG: {
1414                if (mUidAlert != null) {
1415                    mUidAlert.dismiss();
1416                    mUidAlert = null;
1417                }
1418            } break;
1419            case PROC_START_TIMEOUT_MSG: {
1420                if (mDidDexOpt) {
1421                    mDidDexOpt = false;
1422                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1423                    nmsg.obj = msg.obj;
1424                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1425                    return;
1426                }
1427                ProcessRecord app = (ProcessRecord)msg.obj;
1428                synchronized (ActivityManagerService.this) {
1429                    processStartTimedOutLocked(app);
1430                }
1431            } break;
1432            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1433                synchronized (ActivityManagerService.this) {
1434                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1435                }
1436            } break;
1437            case KILL_APPLICATION_MSG: {
1438                synchronized (ActivityManagerService.this) {
1439                    int appid = msg.arg1;
1440                    boolean restart = (msg.arg2 == 1);
1441                    Bundle bundle = (Bundle)msg.obj;
1442                    String pkg = bundle.getString("pkg");
1443                    String reason = bundle.getString("reason");
1444                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1445                            false, UserHandle.USER_ALL, reason);
1446                }
1447            } break;
1448            case FINALIZE_PENDING_INTENT_MSG: {
1449                ((PendingIntentRecord)msg.obj).completeFinalize();
1450            } break;
1451            case POST_HEAVY_NOTIFICATION_MSG: {
1452                INotificationManager inm = NotificationManager.getService();
1453                if (inm == null) {
1454                    return;
1455                }
1456
1457                ActivityRecord root = (ActivityRecord)msg.obj;
1458                ProcessRecord process = root.app;
1459                if (process == null) {
1460                    return;
1461                }
1462
1463                try {
1464                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1465                    String text = mContext.getString(R.string.heavy_weight_notification,
1466                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1467                    Notification notification = new Notification();
1468                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1469                    notification.when = 0;
1470                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1471                    notification.tickerText = text;
1472                    notification.defaults = 0; // please be quiet
1473                    notification.sound = null;
1474                    notification.vibrate = null;
1475                    notification.setLatestEventInfo(context, text,
1476                            mContext.getText(R.string.heavy_weight_notification_detail),
1477                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1478                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1479                                    new UserHandle(root.userId)));
1480
1481                    try {
1482                        int[] outId = new int[1];
1483                        inm.enqueueNotificationWithTag("android", "android", null,
1484                                R.string.heavy_weight_notification,
1485                                notification, outId, root.userId);
1486                    } catch (RuntimeException e) {
1487                        Slog.w(ActivityManagerService.TAG,
1488                                "Error showing notification for heavy-weight app", e);
1489                    } catch (RemoteException e) {
1490                    }
1491                } catch (NameNotFoundException e) {
1492                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1493                }
1494            } break;
1495            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1496                INotificationManager inm = NotificationManager.getService();
1497                if (inm == null) {
1498                    return;
1499                }
1500                try {
1501                    inm.cancelNotificationWithTag("android", null,
1502                            R.string.heavy_weight_notification,  msg.arg1);
1503                } catch (RuntimeException e) {
1504                    Slog.w(ActivityManagerService.TAG,
1505                            "Error canceling notification for service", e);
1506                } catch (RemoteException e) {
1507                }
1508            } break;
1509            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1510                synchronized (ActivityManagerService.this) {
1511                    checkExcessivePowerUsageLocked(true);
1512                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1513                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1514                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1515                }
1516            } break;
1517            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1518                synchronized (ActivityManagerService.this) {
1519                    ActivityRecord ar = (ActivityRecord)msg.obj;
1520                    if (mCompatModeDialog != null) {
1521                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1522                                ar.info.applicationInfo.packageName)) {
1523                            return;
1524                        }
1525                        mCompatModeDialog.dismiss();
1526                        mCompatModeDialog = null;
1527                    }
1528                    if (ar != null && false) {
1529                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1530                                ar.packageName)) {
1531                            int mode = mCompatModePackages.computeCompatModeLocked(
1532                                    ar.info.applicationInfo);
1533                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1534                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1535                                mCompatModeDialog = new CompatModeDialog(
1536                                        ActivityManagerService.this, mContext,
1537                                        ar.info.applicationInfo);
1538                                mCompatModeDialog.show();
1539                            }
1540                        }
1541                    }
1542                }
1543                break;
1544            }
1545            case DISPATCH_PROCESSES_CHANGED: {
1546                dispatchProcessesChanged();
1547                break;
1548            }
1549            case DISPATCH_PROCESS_DIED: {
1550                final int pid = msg.arg1;
1551                final int uid = msg.arg2;
1552                dispatchProcessDied(pid, uid);
1553                break;
1554            }
1555            case REPORT_MEM_USAGE_MSG: {
1556                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1557                Thread thread = new Thread() {
1558                    @Override public void run() {
1559                        final SparseArray<ProcessMemInfo> infoMap
1560                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1561                        for (int i=0, N=memInfos.size(); i<N; i++) {
1562                            ProcessMemInfo mi = memInfos.get(i);
1563                            infoMap.put(mi.pid, mi);
1564                        }
1565                        updateCpuStatsNow();
1566                        synchronized (mProcessCpuThread) {
1567                            final int N = mProcessCpuTracker.countStats();
1568                            for (int i=0; i<N; i++) {
1569                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1570                                if (st.vsize > 0) {
1571                                    long pss = Debug.getPss(st.pid, null);
1572                                    if (pss > 0) {
1573                                        if (infoMap.indexOfKey(st.pid) < 0) {
1574                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1575                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1576                                            mi.pss = pss;
1577                                            memInfos.add(mi);
1578                                        }
1579                                    }
1580                                }
1581                            }
1582                        }
1583
1584                        long totalPss = 0;
1585                        for (int i=0, N=memInfos.size(); i<N; i++) {
1586                            ProcessMemInfo mi = memInfos.get(i);
1587                            if (mi.pss == 0) {
1588                                mi.pss = Debug.getPss(mi.pid, null);
1589                            }
1590                            totalPss += mi.pss;
1591                        }
1592                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1593                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1594                                if (lhs.oomAdj != rhs.oomAdj) {
1595                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1596                                }
1597                                if (lhs.pss != rhs.pss) {
1598                                    return lhs.pss < rhs.pss ? 1 : -1;
1599                                }
1600                                return 0;
1601                            }
1602                        });
1603
1604                        StringBuilder tag = new StringBuilder(128);
1605                        StringBuilder stack = new StringBuilder(128);
1606                        tag.append("Low on memory -- ");
1607                        appendMemBucket(tag, totalPss, "total", false);
1608                        appendMemBucket(stack, totalPss, "total", true);
1609
1610                        StringBuilder logBuilder = new StringBuilder(1024);
1611                        logBuilder.append("Low on memory:\n");
1612
1613                        boolean firstLine = true;
1614                        int lastOomAdj = Integer.MIN_VALUE;
1615                        for (int i=0, N=memInfos.size(); i<N; i++) {
1616                            ProcessMemInfo mi = memInfos.get(i);
1617
1618                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1619                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1620                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1621                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1622                                if (lastOomAdj != mi.oomAdj) {
1623                                    lastOomAdj = mi.oomAdj;
1624                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1625                                        tag.append(" / ");
1626                                    }
1627                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1628                                        if (firstLine) {
1629                                            stack.append(":");
1630                                            firstLine = false;
1631                                        }
1632                                        stack.append("\n\t at ");
1633                                    } else {
1634                                        stack.append("$");
1635                                    }
1636                                } else {
1637                                    tag.append(" ");
1638                                    stack.append("$");
1639                                }
1640                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1641                                    appendMemBucket(tag, mi.pss, mi.name, false);
1642                                }
1643                                appendMemBucket(stack, mi.pss, mi.name, true);
1644                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1645                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1646                                    stack.append("(");
1647                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1648                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1649                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1650                                            stack.append(":");
1651                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1652                                        }
1653                                    }
1654                                    stack.append(")");
1655                                }
1656                            }
1657
1658                            logBuilder.append("  ");
1659                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1660                            logBuilder.append(' ');
1661                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1662                            logBuilder.append(' ');
1663                            ProcessList.appendRamKb(logBuilder, mi.pss);
1664                            logBuilder.append(" kB: ");
1665                            logBuilder.append(mi.name);
1666                            logBuilder.append(" (");
1667                            logBuilder.append(mi.pid);
1668                            logBuilder.append(") ");
1669                            logBuilder.append(mi.adjType);
1670                            logBuilder.append('\n');
1671                            if (mi.adjReason != null) {
1672                                logBuilder.append("                      ");
1673                                logBuilder.append(mi.adjReason);
1674                                logBuilder.append('\n');
1675                            }
1676                        }
1677
1678                        logBuilder.append("           ");
1679                        ProcessList.appendRamKb(logBuilder, totalPss);
1680                        logBuilder.append(" kB: TOTAL\n");
1681
1682                        long[] infos = new long[Debug.MEMINFO_COUNT];
1683                        Debug.getMemInfo(infos);
1684                        logBuilder.append("  MemInfo: ");
1685                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1686                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1687                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1688                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1689                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1690                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1691                            logBuilder.append("  ZRAM: ");
1692                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1693                            logBuilder.append(" kB RAM, ");
1694                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1695                            logBuilder.append(" kB swap total, ");
1696                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1697                            logBuilder.append(" kB swap free\n");
1698                        }
1699                        Slog.i(TAG, logBuilder.toString());
1700
1701                        StringBuilder dropBuilder = new StringBuilder(1024);
1702                        /*
1703                        StringWriter oomSw = new StringWriter();
1704                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1705                        StringWriter catSw = new StringWriter();
1706                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1707                        String[] emptyArgs = new String[] { };
1708                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1709                        oomPw.flush();
1710                        String oomString = oomSw.toString();
1711                        */
1712                        dropBuilder.append(stack);
1713                        dropBuilder.append('\n');
1714                        dropBuilder.append('\n');
1715                        dropBuilder.append(logBuilder);
1716                        dropBuilder.append('\n');
1717                        /*
1718                        dropBuilder.append(oomString);
1719                        dropBuilder.append('\n');
1720                        */
1721                        StringWriter catSw = new StringWriter();
1722                        synchronized (ActivityManagerService.this) {
1723                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1724                            String[] emptyArgs = new String[] { };
1725                            catPw.println();
1726                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1727                            catPw.println();
1728                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1729                                    false, false, null);
1730                            catPw.println();
1731                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1732                            catPw.flush();
1733                        }
1734                        dropBuilder.append(catSw.toString());
1735                        addErrorToDropBox("lowmem", null, "system_server", null,
1736                                null, tag.toString(), dropBuilder.toString(), null, null);
1737                        //Slog.i(TAG, "Sent to dropbox:");
1738                        //Slog.i(TAG, dropBuilder.toString());
1739                        synchronized (ActivityManagerService.this) {
1740                            long now = SystemClock.uptimeMillis();
1741                            if (mLastMemUsageReportTime < now) {
1742                                mLastMemUsageReportTime = now;
1743                            }
1744                        }
1745                    }
1746                };
1747                thread.start();
1748                break;
1749            }
1750            case REPORT_USER_SWITCH_MSG: {
1751                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1752                break;
1753            }
1754            case CONTINUE_USER_SWITCH_MSG: {
1755                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1756                break;
1757            }
1758            case USER_SWITCH_TIMEOUT_MSG: {
1759                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1760                break;
1761            }
1762            case IMMERSIVE_MODE_LOCK_MSG: {
1763                final boolean nextState = (msg.arg1 != 0);
1764                if (mUpdateLock.isHeld() != nextState) {
1765                    if (DEBUG_IMMERSIVE) {
1766                        final ActivityRecord r = (ActivityRecord) msg.obj;
1767                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1768                    }
1769                    if (nextState) {
1770                        mUpdateLock.acquire();
1771                    } else {
1772                        mUpdateLock.release();
1773                    }
1774                }
1775                break;
1776            }
1777            case PERSIST_URI_GRANTS_MSG: {
1778                writeGrantedUriPermissions();
1779                break;
1780            }
1781            case REQUEST_ALL_PSS_MSG: {
1782                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1783                break;
1784            }
1785            case START_PROFILES_MSG: {
1786                synchronized (ActivityManagerService.this) {
1787                    startProfilesLocked();
1788                }
1789                break;
1790            }
1791            case UPDATE_TIME: {
1792                synchronized (ActivityManagerService.this) {
1793                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1794                        ProcessRecord r = mLruProcesses.get(i);
1795                        if (r.thread != null) {
1796                            try {
1797                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1798                            } catch (RemoteException ex) {
1799                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1800                            }
1801                        }
1802                    }
1803                }
1804                break;
1805            }
1806            case SYSTEM_USER_START_MSG: {
1807                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1808                        Integer.toString(msg.arg1), msg.arg1);
1809                mSystemServiceManager.startUser(msg.arg1);
1810                break;
1811            }
1812            case SYSTEM_USER_CURRENT_MSG: {
1813                mBatteryStatsService.noteEvent(
1814                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1815                        Integer.toString(msg.arg2), msg.arg2);
1816                mBatteryStatsService.noteEvent(
1817                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1818                        Integer.toString(msg.arg1), msg.arg1);
1819                mSystemServiceManager.switchUser(msg.arg1);
1820                break;
1821            }
1822            case ENTER_ANIMATION_COMPLETE_MSG: {
1823                synchronized (ActivityManagerService.this) {
1824                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1825                    if (r != null && r.app != null && r.app.thread != null) {
1826                        try {
1827                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1828                        } catch (RemoteException e) {
1829                        }
1830                    }
1831                }
1832                break;
1833            }
1834            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1835                enableScreenAfterBoot();
1836                break;
1837            }
1838            }
1839        }
1840    };
1841
1842    static final int COLLECT_PSS_BG_MSG = 1;
1843
1844    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1845        @Override
1846        public void handleMessage(Message msg) {
1847            switch (msg.what) {
1848            case COLLECT_PSS_BG_MSG: {
1849                long start = SystemClock.uptimeMillis();
1850                MemInfoReader memInfo = null;
1851                synchronized (ActivityManagerService.this) {
1852                    if (mFullPssPending) {
1853                        mFullPssPending = false;
1854                        memInfo = new MemInfoReader();
1855                    }
1856                }
1857                if (memInfo != null) {
1858                    updateCpuStatsNow();
1859                    long nativeTotalPss = 0;
1860                    synchronized (mProcessCpuThread) {
1861                        final int N = mProcessCpuTracker.countStats();
1862                        for (int j=0; j<N; j++) {
1863                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1864                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1865                                // This is definitely an application process; skip it.
1866                                continue;
1867                            }
1868                            synchronized (mPidsSelfLocked) {
1869                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1870                                    // This is one of our own processes; skip it.
1871                                    continue;
1872                                }
1873                            }
1874                            nativeTotalPss += Debug.getPss(st.pid, null);
1875                        }
1876                    }
1877                    memInfo.readMemInfo();
1878                    synchronized (this) {
1879                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1880                                + (SystemClock.uptimeMillis()-start) + "ms");
1881                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1882                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1883                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1884                                        +memInfo.getSlabSizeKb(),
1885                                nativeTotalPss);
1886                    }
1887                }
1888
1889                int i=0, num=0;
1890                long[] tmp = new long[1];
1891                do {
1892                    ProcessRecord proc;
1893                    int procState;
1894                    int pid;
1895                    synchronized (ActivityManagerService.this) {
1896                        if (i >= mPendingPssProcesses.size()) {
1897                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1898                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1899                            mPendingPssProcesses.clear();
1900                            return;
1901                        }
1902                        proc = mPendingPssProcesses.get(i);
1903                        procState = proc.pssProcState;
1904                        if (proc.thread != null && procState == proc.setProcState) {
1905                            pid = proc.pid;
1906                        } else {
1907                            proc = null;
1908                            pid = 0;
1909                        }
1910                        i++;
1911                    }
1912                    if (proc != null) {
1913                        long pss = Debug.getPss(pid, tmp);
1914                        synchronized (ActivityManagerService.this) {
1915                            if (proc.thread != null && proc.setProcState == procState
1916                                    && proc.pid == pid) {
1917                                num++;
1918                                proc.lastPssTime = SystemClock.uptimeMillis();
1919                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1920                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1921                                        + ": " + pss + " lastPss=" + proc.lastPss
1922                                        + " state=" + ProcessList.makeProcStateString(procState));
1923                                if (proc.initialIdlePss == 0) {
1924                                    proc.initialIdlePss = pss;
1925                                }
1926                                proc.lastPss = pss;
1927                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1928                                    proc.lastCachedPss = pss;
1929                                }
1930                            }
1931                        }
1932                    }
1933                } while (true);
1934            }
1935            }
1936        }
1937    };
1938
1939    /**
1940     * Monitor for package changes and update our internal state.
1941     */
1942    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1943        @Override
1944        public void onPackageRemoved(String packageName, int uid) {
1945            // Remove all tasks with activities in the specified package from the list of recent tasks
1946            synchronized (ActivityManagerService.this) {
1947                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1948                    TaskRecord tr = mRecentTasks.get(i);
1949                    ComponentName cn = tr.intent.getComponent();
1950                    if (cn != null && cn.getPackageName().equals(packageName)) {
1951                        // If the package name matches, remove the task and kill the process
1952                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1953                    }
1954                }
1955            }
1956        }
1957
1958        @Override
1959        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1960            onPackageModified(packageName);
1961            return true;
1962        }
1963
1964        @Override
1965        public void onPackageModified(String packageName) {
1966            final PackageManager pm = mContext.getPackageManager();
1967            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1968                    new ArrayList<Pair<Intent, Integer>>();
1969            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1970            // Copy the list of recent tasks so that we don't hold onto the lock on
1971            // ActivityManagerService for long periods while checking if components exist.
1972            synchronized (ActivityManagerService.this) {
1973                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1974                    TaskRecord tr = mRecentTasks.get(i);
1975                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1976                }
1977            }
1978            // Check the recent tasks and filter out all tasks with components that no longer exist.
1979            Intent tmpI = new Intent();
1980            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1981                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1982                ComponentName cn = p.first.getComponent();
1983                if (cn != null && cn.getPackageName().equals(packageName)) {
1984                    try {
1985                        // Add the task to the list to remove if the component no longer exists
1986                        tmpI.setComponent(cn);
1987                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1988                            tasksToRemove.add(p.second);
1989                        }
1990                    } catch (Exception e) {}
1991                }
1992            }
1993            // Prune all the tasks with removed components from the list of recent tasks
1994            synchronized (ActivityManagerService.this) {
1995                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1996                    // Remove the task but don't kill the process (since other components in that
1997                    // package may still be running and in the background)
1998                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1999                }
2000            }
2001        }
2002
2003        @Override
2004        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2005            // Force stop the specified packages
2006            if (packages != null) {
2007                for (String pkg : packages) {
2008                    synchronized (ActivityManagerService.this) {
2009                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2010                                "finished booting")) {
2011                            return true;
2012                        }
2013                    }
2014                }
2015            }
2016            return false;
2017        }
2018    };
2019
2020    public void setSystemProcess() {
2021        try {
2022            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2023            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2024            ServiceManager.addService("meminfo", new MemBinder(this));
2025            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2026            ServiceManager.addService("dbinfo", new DbBinder(this));
2027            if (MONITOR_CPU_USAGE) {
2028                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2029            }
2030            ServiceManager.addService("permission", new PermissionController(this));
2031
2032            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2033                    "android", STOCK_PM_FLAGS);
2034            mSystemThread.installSystemApplicationInfo(info);
2035
2036            synchronized (this) {
2037                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2038                app.persistent = true;
2039                app.pid = MY_PID;
2040                app.maxAdj = ProcessList.SYSTEM_ADJ;
2041                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2042                mProcessNames.put(app.processName, app.uid, app);
2043                synchronized (mPidsSelfLocked) {
2044                    mPidsSelfLocked.put(app.pid, app);
2045                }
2046                updateLruProcessLocked(app, false, null);
2047                updateOomAdjLocked();
2048            }
2049        } catch (PackageManager.NameNotFoundException e) {
2050            throw new RuntimeException(
2051                    "Unable to find android system package", e);
2052        }
2053    }
2054
2055    public void setWindowManager(WindowManagerService wm) {
2056        mWindowManager = wm;
2057        mStackSupervisor.setWindowManager(wm);
2058    }
2059
2060    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2061        mUsageStatsService = usageStatsManager;
2062    }
2063
2064    public void startObservingNativeCrashes() {
2065        final NativeCrashListener ncl = new NativeCrashListener(this);
2066        ncl.start();
2067    }
2068
2069    public IAppOpsService getAppOpsService() {
2070        return mAppOpsService;
2071    }
2072
2073    static class MemBinder extends Binder {
2074        ActivityManagerService mActivityManagerService;
2075        MemBinder(ActivityManagerService activityManagerService) {
2076            mActivityManagerService = activityManagerService;
2077        }
2078
2079        @Override
2080        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2081            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2082                    != PackageManager.PERMISSION_GRANTED) {
2083                pw.println("Permission Denial: can't dump meminfo from from pid="
2084                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2085                        + " without permission " + android.Manifest.permission.DUMP);
2086                return;
2087            }
2088
2089            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2090        }
2091    }
2092
2093    static class GraphicsBinder extends Binder {
2094        ActivityManagerService mActivityManagerService;
2095        GraphicsBinder(ActivityManagerService activityManagerService) {
2096            mActivityManagerService = activityManagerService;
2097        }
2098
2099        @Override
2100        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2101            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2102                    != PackageManager.PERMISSION_GRANTED) {
2103                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2104                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2105                        + " without permission " + android.Manifest.permission.DUMP);
2106                return;
2107            }
2108
2109            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2110        }
2111    }
2112
2113    static class DbBinder extends Binder {
2114        ActivityManagerService mActivityManagerService;
2115        DbBinder(ActivityManagerService activityManagerService) {
2116            mActivityManagerService = activityManagerService;
2117        }
2118
2119        @Override
2120        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2121            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2122                    != PackageManager.PERMISSION_GRANTED) {
2123                pw.println("Permission Denial: can't dump dbinfo from from pid="
2124                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2125                        + " without permission " + android.Manifest.permission.DUMP);
2126                return;
2127            }
2128
2129            mActivityManagerService.dumpDbInfo(fd, pw, args);
2130        }
2131    }
2132
2133    static class CpuBinder extends Binder {
2134        ActivityManagerService mActivityManagerService;
2135        CpuBinder(ActivityManagerService activityManagerService) {
2136            mActivityManagerService = activityManagerService;
2137        }
2138
2139        @Override
2140        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2141            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2142                    != PackageManager.PERMISSION_GRANTED) {
2143                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2144                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2145                        + " without permission " + android.Manifest.permission.DUMP);
2146                return;
2147            }
2148
2149            synchronized (mActivityManagerService.mProcessCpuThread) {
2150                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2151                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2152                        SystemClock.uptimeMillis()));
2153            }
2154        }
2155    }
2156
2157    public static final class Lifecycle extends SystemService {
2158        private final ActivityManagerService mService;
2159
2160        public Lifecycle(Context context) {
2161            super(context);
2162            mService = new ActivityManagerService(context);
2163        }
2164
2165        @Override
2166        public void onStart() {
2167            mService.start();
2168        }
2169
2170        public ActivityManagerService getService() {
2171            return mService;
2172        }
2173    }
2174
2175    // Note: This method is invoked on the main thread but may need to attach various
2176    // handlers to other threads.  So take care to be explicit about the looper.
2177    public ActivityManagerService(Context systemContext) {
2178        mContext = systemContext;
2179        mFactoryTest = FactoryTest.getMode();
2180        mSystemThread = ActivityThread.currentActivityThread();
2181
2182        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2183
2184        mHandlerThread = new ServiceThread(TAG,
2185                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2186        mHandlerThread.start();
2187        mHandler = new MainHandler(mHandlerThread.getLooper());
2188
2189        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2190                "foreground", BROADCAST_FG_TIMEOUT, false);
2191        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2192                "background", BROADCAST_BG_TIMEOUT, true);
2193        mBroadcastQueues[0] = mFgBroadcastQueue;
2194        mBroadcastQueues[1] = mBgBroadcastQueue;
2195
2196        mServices = new ActiveServices(this);
2197        mProviderMap = new ProviderMap(this);
2198
2199        // TODO: Move creation of battery stats service outside of activity manager service.
2200        File dataDir = Environment.getDataDirectory();
2201        File systemDir = new File(dataDir, "system");
2202        systemDir.mkdirs();
2203        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2204        mBatteryStatsService.getActiveStatistics().readLocked();
2205        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2206        mOnBattery = DEBUG_POWER ? true
2207                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2208        mBatteryStatsService.getActiveStatistics().setCallback(this);
2209
2210        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2211
2212        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2213
2214        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2215
2216        // User 0 is the first and only user that runs at boot.
2217        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2218        mUserLru.add(Integer.valueOf(0));
2219        updateStartedUserArrayLocked();
2220
2221        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2222            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2223
2224        mConfiguration.setToDefaults();
2225        mConfiguration.setLocale(Locale.getDefault());
2226
2227        mConfigurationSeq = mConfiguration.seq = 1;
2228        mProcessCpuTracker.init();
2229
2230        mHasRecents = mContext.getResources().getBoolean(
2231                com.android.internal.R.bool.config_hasRecents);
2232
2233        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2234        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2235        mStackSupervisor = new ActivityStackSupervisor(this);
2236        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2237
2238        mProcessCpuThread = new Thread("CpuTracker") {
2239            @Override
2240            public void run() {
2241                while (true) {
2242                    try {
2243                        try {
2244                            synchronized(this) {
2245                                final long now = SystemClock.uptimeMillis();
2246                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2247                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2248                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2249                                //        + ", write delay=" + nextWriteDelay);
2250                                if (nextWriteDelay < nextCpuDelay) {
2251                                    nextCpuDelay = nextWriteDelay;
2252                                }
2253                                if (nextCpuDelay > 0) {
2254                                    mProcessCpuMutexFree.set(true);
2255                                    this.wait(nextCpuDelay);
2256                                }
2257                            }
2258                        } catch (InterruptedException e) {
2259                        }
2260                        updateCpuStatsNow();
2261                    } catch (Exception e) {
2262                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2263                    }
2264                }
2265            }
2266        };
2267
2268        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2269
2270        Watchdog.getInstance().addMonitor(this);
2271        Watchdog.getInstance().addThread(mHandler);
2272    }
2273
2274    public void setSystemServiceManager(SystemServiceManager mgr) {
2275        mSystemServiceManager = mgr;
2276    }
2277
2278    private void start() {
2279        Process.removeAllProcessGroups();
2280        mProcessCpuThread.start();
2281
2282        mBatteryStatsService.publish(mContext);
2283        mAppOpsService.publish(mContext);
2284        Slog.d("AppOps", "AppOpsService published");
2285        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2286    }
2287
2288    public void initPowerManagement() {
2289        mStackSupervisor.initPowerManagement();
2290        mBatteryStatsService.initPowerManagement();
2291    }
2292
2293    @Override
2294    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2295            throws RemoteException {
2296        if (code == SYSPROPS_TRANSACTION) {
2297            // We need to tell all apps about the system property change.
2298            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2299            synchronized(this) {
2300                final int NP = mProcessNames.getMap().size();
2301                for (int ip=0; ip<NP; ip++) {
2302                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2303                    final int NA = apps.size();
2304                    for (int ia=0; ia<NA; ia++) {
2305                        ProcessRecord app = apps.valueAt(ia);
2306                        if (app.thread != null) {
2307                            procs.add(app.thread.asBinder());
2308                        }
2309                    }
2310                }
2311            }
2312
2313            int N = procs.size();
2314            for (int i=0; i<N; i++) {
2315                Parcel data2 = Parcel.obtain();
2316                try {
2317                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2318                } catch (RemoteException e) {
2319                }
2320                data2.recycle();
2321            }
2322        }
2323        try {
2324            return super.onTransact(code, data, reply, flags);
2325        } catch (RuntimeException e) {
2326            // The activity manager only throws security exceptions, so let's
2327            // log all others.
2328            if (!(e instanceof SecurityException)) {
2329                Slog.wtf(TAG, "Activity Manager Crash", e);
2330            }
2331            throw e;
2332        }
2333    }
2334
2335    void updateCpuStats() {
2336        final long now = SystemClock.uptimeMillis();
2337        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2338            return;
2339        }
2340        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2341            synchronized (mProcessCpuThread) {
2342                mProcessCpuThread.notify();
2343            }
2344        }
2345    }
2346
2347    void updateCpuStatsNow() {
2348        synchronized (mProcessCpuThread) {
2349            mProcessCpuMutexFree.set(false);
2350            final long now = SystemClock.uptimeMillis();
2351            boolean haveNewCpuStats = false;
2352
2353            if (MONITOR_CPU_USAGE &&
2354                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2355                mLastCpuTime.set(now);
2356                haveNewCpuStats = true;
2357                mProcessCpuTracker.update();
2358                //Slog.i(TAG, mProcessCpu.printCurrentState());
2359                //Slog.i(TAG, "Total CPU usage: "
2360                //        + mProcessCpu.getTotalCpuPercent() + "%");
2361
2362                // Slog the cpu usage if the property is set.
2363                if ("true".equals(SystemProperties.get("events.cpu"))) {
2364                    int user = mProcessCpuTracker.getLastUserTime();
2365                    int system = mProcessCpuTracker.getLastSystemTime();
2366                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2367                    int irq = mProcessCpuTracker.getLastIrqTime();
2368                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2369                    int idle = mProcessCpuTracker.getLastIdleTime();
2370
2371                    int total = user + system + iowait + irq + softIrq + idle;
2372                    if (total == 0) total = 1;
2373
2374                    EventLog.writeEvent(EventLogTags.CPU,
2375                            ((user+system+iowait+irq+softIrq) * 100) / total,
2376                            (user * 100) / total,
2377                            (system * 100) / total,
2378                            (iowait * 100) / total,
2379                            (irq * 100) / total,
2380                            (softIrq * 100) / total);
2381                }
2382            }
2383
2384            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2385            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2386            synchronized(bstats) {
2387                synchronized(mPidsSelfLocked) {
2388                    if (haveNewCpuStats) {
2389                        if (mOnBattery) {
2390                            int perc = bstats.startAddingCpuLocked();
2391                            int totalUTime = 0;
2392                            int totalSTime = 0;
2393                            final int N = mProcessCpuTracker.countStats();
2394                            for (int i=0; i<N; i++) {
2395                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2396                                if (!st.working) {
2397                                    continue;
2398                                }
2399                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2400                                int otherUTime = (st.rel_utime*perc)/100;
2401                                int otherSTime = (st.rel_stime*perc)/100;
2402                                totalUTime += otherUTime;
2403                                totalSTime += otherSTime;
2404                                if (pr != null) {
2405                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2406                                    if (ps == null || !ps.isActive()) {
2407                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2408                                                pr.info.uid, pr.processName);
2409                                    }
2410                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2411                                            st.rel_stime-otherSTime);
2412                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2413                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2414                                } else {
2415                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2416                                    if (ps == null || !ps.isActive()) {
2417                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2418                                                bstats.mapUid(st.uid), st.name);
2419                                    }
2420                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2421                                            st.rel_stime-otherSTime);
2422                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2423                                }
2424                            }
2425                            bstats.finishAddingCpuLocked(perc, totalUTime,
2426                                    totalSTime, cpuSpeedTimes);
2427                        }
2428                    }
2429                }
2430
2431                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2432                    mLastWriteTime = now;
2433                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2434                }
2435            }
2436        }
2437    }
2438
2439    @Override
2440    public void batteryNeedsCpuUpdate() {
2441        updateCpuStatsNow();
2442    }
2443
2444    @Override
2445    public void batteryPowerChanged(boolean onBattery) {
2446        // When plugging in, update the CPU stats first before changing
2447        // the plug state.
2448        updateCpuStatsNow();
2449        synchronized (this) {
2450            synchronized(mPidsSelfLocked) {
2451                mOnBattery = DEBUG_POWER ? true : onBattery;
2452            }
2453        }
2454    }
2455
2456    /**
2457     * Initialize the application bind args. These are passed to each
2458     * process when the bindApplication() IPC is sent to the process. They're
2459     * lazily setup to make sure the services are running when they're asked for.
2460     */
2461    private HashMap<String, IBinder> getCommonServicesLocked() {
2462        if (mAppBindArgs == null) {
2463            mAppBindArgs = new HashMap<String, IBinder>();
2464
2465            // Setup the application init args
2466            mAppBindArgs.put("package", ServiceManager.getService("package"));
2467            mAppBindArgs.put("window", ServiceManager.getService("window"));
2468            mAppBindArgs.put(Context.ALARM_SERVICE,
2469                    ServiceManager.getService(Context.ALARM_SERVICE));
2470        }
2471        return mAppBindArgs;
2472    }
2473
2474    final void setFocusedActivityLocked(ActivityRecord r) {
2475        if (mFocusedActivity != r) {
2476            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2477            mFocusedActivity = r;
2478            if (r.task != null && r.task.voiceInteractor != null) {
2479                startRunningVoiceLocked();
2480            } else {
2481                finishRunningVoiceLocked();
2482            }
2483            mStackSupervisor.setFocusedStack(r);
2484            if (r != null) {
2485                mWindowManager.setFocusedApp(r.appToken, true);
2486            }
2487            applyUpdateLockStateLocked(r);
2488        }
2489    }
2490
2491    final void clearFocusedActivity(ActivityRecord r) {
2492        if (mFocusedActivity == r) {
2493            mFocusedActivity = null;
2494        }
2495    }
2496
2497    @Override
2498    public void setFocusedStack(int stackId) {
2499        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2500        synchronized (ActivityManagerService.this) {
2501            ActivityStack stack = mStackSupervisor.getStack(stackId);
2502            if (stack != null) {
2503                ActivityRecord r = stack.topRunningActivityLocked(null);
2504                if (r != null) {
2505                    setFocusedActivityLocked(r);
2506                }
2507            }
2508        }
2509    }
2510
2511    @Override
2512    public void notifyActivityDrawn(IBinder token) {
2513        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2514        synchronized (this) {
2515            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2516            if (r != null) {
2517                r.task.stack.notifyActivityDrawnLocked(r);
2518            }
2519        }
2520    }
2521
2522    final void applyUpdateLockStateLocked(ActivityRecord r) {
2523        // Modifications to the UpdateLock state are done on our handler, outside
2524        // the activity manager's locks.  The new state is determined based on the
2525        // state *now* of the relevant activity record.  The object is passed to
2526        // the handler solely for logging detail, not to be consulted/modified.
2527        final boolean nextState = r != null && r.immersive;
2528        mHandler.sendMessage(
2529                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2530    }
2531
2532    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2533        Message msg = Message.obtain();
2534        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2535        msg.obj = r.task.askedCompatMode ? null : r;
2536        mHandler.sendMessage(msg);
2537    }
2538
2539    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2540            String what, Object obj, ProcessRecord srcApp) {
2541        app.lastActivityTime = now;
2542
2543        if (app.activities.size() > 0) {
2544            // Don't want to touch dependent processes that are hosting activities.
2545            return index;
2546        }
2547
2548        int lrui = mLruProcesses.lastIndexOf(app);
2549        if (lrui < 0) {
2550            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2551                    + what + " " + obj + " from " + srcApp);
2552            return index;
2553        }
2554
2555        if (lrui >= index) {
2556            // Don't want to cause this to move dependent processes *back* in the
2557            // list as if they were less frequently used.
2558            return index;
2559        }
2560
2561        if (lrui >= mLruProcessActivityStart) {
2562            // Don't want to touch dependent processes that are hosting activities.
2563            return index;
2564        }
2565
2566        mLruProcesses.remove(lrui);
2567        if (index > 0) {
2568            index--;
2569        }
2570        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2571                + " in LRU list: " + app);
2572        mLruProcesses.add(index, app);
2573        return index;
2574    }
2575
2576    final void removeLruProcessLocked(ProcessRecord app) {
2577        int lrui = mLruProcesses.lastIndexOf(app);
2578        if (lrui >= 0) {
2579            if (lrui <= mLruProcessActivityStart) {
2580                mLruProcessActivityStart--;
2581            }
2582            if (lrui <= mLruProcessServiceStart) {
2583                mLruProcessServiceStart--;
2584            }
2585            mLruProcesses.remove(lrui);
2586        }
2587    }
2588
2589    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2590            ProcessRecord client) {
2591        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2592                || app.treatLikeActivity;
2593        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2594        if (!activityChange && hasActivity) {
2595            // The process has activities, so we are only allowing activity-based adjustments
2596            // to move it.  It should be kept in the front of the list with other
2597            // processes that have activities, and we don't want those to change their
2598            // order except due to activity operations.
2599            return;
2600        }
2601
2602        mLruSeq++;
2603        final long now = SystemClock.uptimeMillis();
2604        app.lastActivityTime = now;
2605
2606        // First a quick reject: if the app is already at the position we will
2607        // put it, then there is nothing to do.
2608        if (hasActivity) {
2609            final int N = mLruProcesses.size();
2610            if (N > 0 && mLruProcesses.get(N-1) == app) {
2611                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2612                return;
2613            }
2614        } else {
2615            if (mLruProcessServiceStart > 0
2616                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2617                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2618                return;
2619            }
2620        }
2621
2622        int lrui = mLruProcesses.lastIndexOf(app);
2623
2624        if (app.persistent && lrui >= 0) {
2625            // We don't care about the position of persistent processes, as long as
2626            // they are in the list.
2627            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2628            return;
2629        }
2630
2631        /* In progress: compute new position first, so we can avoid doing work
2632           if the process is not actually going to move.  Not yet working.
2633        int addIndex;
2634        int nextIndex;
2635        boolean inActivity = false, inService = false;
2636        if (hasActivity) {
2637            // Process has activities, put it at the very tipsy-top.
2638            addIndex = mLruProcesses.size();
2639            nextIndex = mLruProcessServiceStart;
2640            inActivity = true;
2641        } else if (hasService) {
2642            // Process has services, put it at the top of the service list.
2643            addIndex = mLruProcessActivityStart;
2644            nextIndex = mLruProcessServiceStart;
2645            inActivity = true;
2646            inService = true;
2647        } else  {
2648            // Process not otherwise of interest, it goes to the top of the non-service area.
2649            addIndex = mLruProcessServiceStart;
2650            if (client != null) {
2651                int clientIndex = mLruProcesses.lastIndexOf(client);
2652                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2653                        + app);
2654                if (clientIndex >= 0 && addIndex > clientIndex) {
2655                    addIndex = clientIndex;
2656                }
2657            }
2658            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2659        }
2660
2661        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2662                + mLruProcessActivityStart + "): " + app);
2663        */
2664
2665        if (lrui >= 0) {
2666            if (lrui < mLruProcessActivityStart) {
2667                mLruProcessActivityStart--;
2668            }
2669            if (lrui < mLruProcessServiceStart) {
2670                mLruProcessServiceStart--;
2671            }
2672            /*
2673            if (addIndex > lrui) {
2674                addIndex--;
2675            }
2676            if (nextIndex > lrui) {
2677                nextIndex--;
2678            }
2679            */
2680            mLruProcesses.remove(lrui);
2681        }
2682
2683        /*
2684        mLruProcesses.add(addIndex, app);
2685        if (inActivity) {
2686            mLruProcessActivityStart++;
2687        }
2688        if (inService) {
2689            mLruProcessActivityStart++;
2690        }
2691        */
2692
2693        int nextIndex;
2694        if (hasActivity) {
2695            final int N = mLruProcesses.size();
2696            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2697                // Process doesn't have activities, but has clients with
2698                // activities...  move it up, but one below the top (the top
2699                // should always have a real activity).
2700                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2701                mLruProcesses.add(N-1, app);
2702                // To keep it from spamming the LRU list (by making a bunch of clients),
2703                // we will push down any other entries owned by the app.
2704                final int uid = app.info.uid;
2705                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2706                    ProcessRecord subProc = mLruProcesses.get(i);
2707                    if (subProc.info.uid == uid) {
2708                        // We want to push this one down the list.  If the process after
2709                        // it is for the same uid, however, don't do so, because we don't
2710                        // want them internally to be re-ordered.
2711                        if (mLruProcesses.get(i-1).info.uid != uid) {
2712                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2713                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2714                            ProcessRecord tmp = mLruProcesses.get(i);
2715                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2716                            mLruProcesses.set(i-1, tmp);
2717                            i--;
2718                        }
2719                    } else {
2720                        // A gap, we can stop here.
2721                        break;
2722                    }
2723                }
2724            } else {
2725                // Process has activities, put it at the very tipsy-top.
2726                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2727                mLruProcesses.add(app);
2728            }
2729            nextIndex = mLruProcessServiceStart;
2730        } else if (hasService) {
2731            // Process has services, put it at the top of the service list.
2732            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2733            mLruProcesses.add(mLruProcessActivityStart, app);
2734            nextIndex = mLruProcessServiceStart;
2735            mLruProcessActivityStart++;
2736        } else  {
2737            // Process not otherwise of interest, it goes to the top of the non-service area.
2738            int index = mLruProcessServiceStart;
2739            if (client != null) {
2740                // If there is a client, don't allow the process to be moved up higher
2741                // in the list than that client.
2742                int clientIndex = mLruProcesses.lastIndexOf(client);
2743                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2744                        + " when updating " + app);
2745                if (clientIndex <= lrui) {
2746                    // Don't allow the client index restriction to push it down farther in the
2747                    // list than it already is.
2748                    clientIndex = lrui;
2749                }
2750                if (clientIndex >= 0 && index > clientIndex) {
2751                    index = clientIndex;
2752                }
2753            }
2754            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2755            mLruProcesses.add(index, app);
2756            nextIndex = index-1;
2757            mLruProcessActivityStart++;
2758            mLruProcessServiceStart++;
2759        }
2760
2761        // If the app is currently using a content provider or service,
2762        // bump those processes as well.
2763        for (int j=app.connections.size()-1; j>=0; j--) {
2764            ConnectionRecord cr = app.connections.valueAt(j);
2765            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2766                    && cr.binding.service.app != null
2767                    && cr.binding.service.app.lruSeq != mLruSeq
2768                    && !cr.binding.service.app.persistent) {
2769                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2770                        "service connection", cr, app);
2771            }
2772        }
2773        for (int j=app.conProviders.size()-1; j>=0; j--) {
2774            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2775            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2776                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2777                        "provider reference", cpr, app);
2778            }
2779        }
2780    }
2781
2782    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2783        if (uid == Process.SYSTEM_UID) {
2784            // The system gets to run in any process.  If there are multiple
2785            // processes with the same uid, just pick the first (this
2786            // should never happen).
2787            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2788            if (procs == null) return null;
2789            final int N = procs.size();
2790            for (int i = 0; i < N; i++) {
2791                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2792            }
2793        }
2794        ProcessRecord proc = mProcessNames.get(processName, uid);
2795        if (false && proc != null && !keepIfLarge
2796                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2797                && proc.lastCachedPss >= 4000) {
2798            // Turn this condition on to cause killing to happen regularly, for testing.
2799            if (proc.baseProcessTracker != null) {
2800                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2801            }
2802            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2803                    + "k from cached");
2804        } else if (proc != null && !keepIfLarge
2805                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2806                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2807            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2808            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2809                if (proc.baseProcessTracker != null) {
2810                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2811                }
2812                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2813                        + "k from cached");
2814            }
2815        }
2816        return proc;
2817    }
2818
2819    void ensurePackageDexOpt(String packageName) {
2820        IPackageManager pm = AppGlobals.getPackageManager();
2821        try {
2822            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2823                mDidDexOpt = true;
2824            }
2825        } catch (RemoteException e) {
2826        }
2827    }
2828
2829    boolean isNextTransitionForward() {
2830        int transit = mWindowManager.getPendingAppTransition();
2831        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2832                || transit == AppTransition.TRANSIT_TASK_OPEN
2833                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2834    }
2835
2836    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2837            String processName, String abiOverride, int uid, Runnable crashHandler) {
2838        synchronized(this) {
2839            ApplicationInfo info = new ApplicationInfo();
2840            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2841            // For isolated processes, the former contains the parent's uid and the latter the
2842            // actual uid of the isolated process.
2843            // In the special case introduced by this method (which is, starting an isolated
2844            // process directly from the SystemServer without an actual parent app process) the
2845            // closest thing to a parent's uid is SYSTEM_UID.
2846            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2847            // the |isolated| logic in the ProcessRecord constructor.
2848            info.uid = Process.SYSTEM_UID;
2849            info.processName = processName;
2850            info.className = entryPoint;
2851            info.packageName = "android";
2852            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2853                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2854                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2855                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2856                    crashHandler);
2857            return proc != null ? proc.pid : 0;
2858        }
2859    }
2860
2861    final ProcessRecord startProcessLocked(String processName,
2862            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2863            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2864            boolean isolated, boolean keepIfLarge) {
2865        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2866                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2867                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2868                null /* crashHandler */);
2869    }
2870
2871    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2872            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2873            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2874            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2875        ProcessRecord app;
2876        if (!isolated) {
2877            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2878        } else {
2879            // If this is an isolated process, it can't re-use an existing process.
2880            app = null;
2881        }
2882        // We don't have to do anything more if:
2883        // (1) There is an existing application record; and
2884        // (2) The caller doesn't think it is dead, OR there is no thread
2885        //     object attached to it so we know it couldn't have crashed; and
2886        // (3) There is a pid assigned to it, so it is either starting or
2887        //     already running.
2888        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2889                + " app=" + app + " knownToBeDead=" + knownToBeDead
2890                + " thread=" + (app != null ? app.thread : null)
2891                + " pid=" + (app != null ? app.pid : -1));
2892        if (app != null && app.pid > 0) {
2893            if (!knownToBeDead || app.thread == null) {
2894                // We already have the app running, or are waiting for it to
2895                // come up (we have a pid but not yet its thread), so keep it.
2896                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2897                // If this is a new package in the process, add the package to the list
2898                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2899                return app;
2900            }
2901
2902            // An application record is attached to a previous process,
2903            // clean it up now.
2904            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2905            Process.killProcessGroup(app.info.uid, app.pid);
2906            handleAppDiedLocked(app, true, true);
2907        }
2908
2909        String hostingNameStr = hostingName != null
2910                ? hostingName.flattenToShortString() : null;
2911
2912        if (!isolated) {
2913            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2914                // If we are in the background, then check to see if this process
2915                // is bad.  If so, we will just silently fail.
2916                if (mBadProcesses.get(info.processName, info.uid) != null) {
2917                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2918                            + "/" + info.processName);
2919                    return null;
2920                }
2921            } else {
2922                // When the user is explicitly starting a process, then clear its
2923                // crash count so that we won't make it bad until they see at
2924                // least one crash dialog again, and make the process good again
2925                // if it had been bad.
2926                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2927                        + "/" + info.processName);
2928                mProcessCrashTimes.remove(info.processName, info.uid);
2929                if (mBadProcesses.get(info.processName, info.uid) != null) {
2930                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2931                            UserHandle.getUserId(info.uid), info.uid,
2932                            info.processName);
2933                    mBadProcesses.remove(info.processName, info.uid);
2934                    if (app != null) {
2935                        app.bad = false;
2936                    }
2937                }
2938            }
2939        }
2940
2941        if (app == null) {
2942            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2943            app.crashHandler = crashHandler;
2944            if (app == null) {
2945                Slog.w(TAG, "Failed making new process record for "
2946                        + processName + "/" + info.uid + " isolated=" + isolated);
2947                return null;
2948            }
2949            mProcessNames.put(processName, app.uid, app);
2950            if (isolated) {
2951                mIsolatedProcesses.put(app.uid, app);
2952            }
2953        } else {
2954            // If this is a new package in the process, add the package to the list
2955            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2956        }
2957
2958        // If the system is not ready yet, then hold off on starting this
2959        // process until it is.
2960        if (!mProcessesReady
2961                && !isAllowedWhileBooting(info)
2962                && !allowWhileBooting) {
2963            if (!mProcessesOnHold.contains(app)) {
2964                mProcessesOnHold.add(app);
2965            }
2966            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2967            return app;
2968        }
2969
2970        startProcessLocked(
2971                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2972        return (app.pid != 0) ? app : null;
2973    }
2974
2975    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2976        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2977    }
2978
2979    private final void startProcessLocked(ProcessRecord app,
2980            String hostingType, String hostingNameStr) {
2981        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2982                null /* entryPoint */, null /* entryPointArgs */);
2983    }
2984
2985    private final void startProcessLocked(ProcessRecord app, String hostingType,
2986            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2987        if (app.pid > 0 && app.pid != MY_PID) {
2988            synchronized (mPidsSelfLocked) {
2989                mPidsSelfLocked.remove(app.pid);
2990                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2991            }
2992            app.setPid(0);
2993        }
2994
2995        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2996                "startProcessLocked removing on hold: " + app);
2997        mProcessesOnHold.remove(app);
2998
2999        updateCpuStats();
3000
3001        try {
3002            int uid = app.uid;
3003
3004            int[] gids = null;
3005            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3006            if (!app.isolated) {
3007                int[] permGids = null;
3008                try {
3009                    final PackageManager pm = mContext.getPackageManager();
3010                    permGids = pm.getPackageGids(app.info.packageName);
3011
3012                    if (Environment.isExternalStorageEmulated()) {
3013                        if (pm.checkPermission(
3014                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3015                                app.info.packageName) == PERMISSION_GRANTED) {
3016                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3017                        } else {
3018                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3019                        }
3020                    }
3021                } catch (PackageManager.NameNotFoundException e) {
3022                    Slog.w(TAG, "Unable to retrieve gids", e);
3023                }
3024
3025                /*
3026                 * Add shared application and profile GIDs so applications can share some
3027                 * resources like shared libraries and access user-wide resources
3028                 */
3029                if (permGids == null) {
3030                    gids = new int[2];
3031                } else {
3032                    gids = new int[permGids.length + 2];
3033                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3034                }
3035                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3036                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3037            }
3038            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3039                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3040                        && mTopComponent != null
3041                        && app.processName.equals(mTopComponent.getPackageName())) {
3042                    uid = 0;
3043                }
3044                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3045                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3046                    uid = 0;
3047                }
3048            }
3049            int debugFlags = 0;
3050            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3051                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3052                // Also turn on CheckJNI for debuggable apps. It's quite
3053                // awkward to turn on otherwise.
3054                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3055            }
3056            // Run the app in safe mode if its manifest requests so or the
3057            // system is booted in safe mode.
3058            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3059                mSafeMode == true) {
3060                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3061            }
3062            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3063                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3064            }
3065            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3066                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3067            }
3068            if ("1".equals(SystemProperties.get("debug.assert"))) {
3069                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3070            }
3071
3072            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3073            if (requiredAbi == null) {
3074                requiredAbi = Build.SUPPORTED_ABIS[0];
3075            }
3076
3077            // Start the process.  It will either succeed and return a result containing
3078            // the PID of the new process, or else throw a RuntimeException.
3079            boolean isActivityProcess = (entryPoint == null);
3080            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3081            Process.ProcessStartResult startResult = Process.start(entryPoint,
3082                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3083                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
3084
3085            if (app.isolated) {
3086                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3087            }
3088            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3089
3090            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3091                    UserHandle.getUserId(uid), startResult.pid, uid,
3092                    app.processName, hostingType,
3093                    hostingNameStr != null ? hostingNameStr : "");
3094
3095            if (app.persistent) {
3096                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3097            }
3098
3099            StringBuilder buf = mStringBuilder;
3100            buf.setLength(0);
3101            buf.append("Start proc ");
3102            buf.append(app.processName);
3103            if (!isActivityProcess) {
3104                buf.append(" [");
3105                buf.append(entryPoint);
3106                buf.append("]");
3107            }
3108            buf.append(" for ");
3109            buf.append(hostingType);
3110            if (hostingNameStr != null) {
3111                buf.append(" ");
3112                buf.append(hostingNameStr);
3113            }
3114            buf.append(": pid=");
3115            buf.append(startResult.pid);
3116            buf.append(" uid=");
3117            buf.append(uid);
3118            buf.append(" gids={");
3119            if (gids != null) {
3120                for (int gi=0; gi<gids.length; gi++) {
3121                    if (gi != 0) buf.append(", ");
3122                    buf.append(gids[gi]);
3123
3124                }
3125            }
3126            buf.append("}");
3127            if (requiredAbi != null) {
3128                buf.append(" abi=");
3129                buf.append(requiredAbi);
3130            }
3131            Slog.i(TAG, buf.toString());
3132            app.setPid(startResult.pid);
3133            app.usingWrapper = startResult.usingWrapper;
3134            app.removed = false;
3135            app.killedByAm = false;
3136            synchronized (mPidsSelfLocked) {
3137                this.mPidsSelfLocked.put(startResult.pid, app);
3138                if (isActivityProcess) {
3139                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3140                    msg.obj = app;
3141                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3142                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3143                }
3144            }
3145        } catch (RuntimeException e) {
3146            // XXX do better error recovery.
3147            app.setPid(0);
3148            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3149            if (app.isolated) {
3150                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3151            }
3152            Slog.e(TAG, "Failure starting process " + app.processName, e);
3153        }
3154    }
3155
3156    void updateUsageStats(ActivityRecord component, boolean resumed) {
3157        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3158        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3159        if (resumed) {
3160            if (mUsageStatsService != null) {
3161                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3162                        System.currentTimeMillis(),
3163                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3164            }
3165            synchronized (stats) {
3166                stats.noteActivityResumedLocked(component.app.uid);
3167            }
3168        } else {
3169            if (mUsageStatsService != null) {
3170                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3171                        System.currentTimeMillis(),
3172                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3173            }
3174            synchronized (stats) {
3175                stats.noteActivityPausedLocked(component.app.uid);
3176            }
3177        }
3178    }
3179
3180    Intent getHomeIntent() {
3181        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3182        intent.setComponent(mTopComponent);
3183        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3184            intent.addCategory(Intent.CATEGORY_HOME);
3185        }
3186        return intent;
3187    }
3188
3189    boolean startHomeActivityLocked(int userId) {
3190        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3191                && mTopAction == null) {
3192            // We are running in factory test mode, but unable to find
3193            // the factory test app, so just sit around displaying the
3194            // error message and don't try to start anything.
3195            return false;
3196        }
3197        Intent intent = getHomeIntent();
3198        ActivityInfo aInfo =
3199            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3200        if (aInfo != null) {
3201            intent.setComponent(new ComponentName(
3202                    aInfo.applicationInfo.packageName, aInfo.name));
3203            // Don't do this if the home app is currently being
3204            // instrumented.
3205            aInfo = new ActivityInfo(aInfo);
3206            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3207            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3208                    aInfo.applicationInfo.uid, true);
3209            if (app == null || app.instrumentationClass == null) {
3210                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3211                mStackSupervisor.startHomeActivity(intent, aInfo);
3212            }
3213        }
3214
3215        return true;
3216    }
3217
3218    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3219        ActivityInfo ai = null;
3220        ComponentName comp = intent.getComponent();
3221        try {
3222            if (comp != null) {
3223                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3224            } else {
3225                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3226                        intent,
3227                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3228                            flags, userId);
3229
3230                if (info != null) {
3231                    ai = info.activityInfo;
3232                }
3233            }
3234        } catch (RemoteException e) {
3235            // ignore
3236        }
3237
3238        return ai;
3239    }
3240
3241    /**
3242     * Starts the "new version setup screen" if appropriate.
3243     */
3244    void startSetupActivityLocked() {
3245        // Only do this once per boot.
3246        if (mCheckedForSetup) {
3247            return;
3248        }
3249
3250        // We will show this screen if the current one is a different
3251        // version than the last one shown, and we are not running in
3252        // low-level factory test mode.
3253        final ContentResolver resolver = mContext.getContentResolver();
3254        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3255                Settings.Global.getInt(resolver,
3256                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3257            mCheckedForSetup = true;
3258
3259            // See if we should be showing the platform update setup UI.
3260            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3261            List<ResolveInfo> ris = mContext.getPackageManager()
3262                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3263
3264            // We don't allow third party apps to replace this.
3265            ResolveInfo ri = null;
3266            for (int i=0; ris != null && i<ris.size(); i++) {
3267                if ((ris.get(i).activityInfo.applicationInfo.flags
3268                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3269                    ri = ris.get(i);
3270                    break;
3271                }
3272            }
3273
3274            if (ri != null) {
3275                String vers = ri.activityInfo.metaData != null
3276                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3277                        : null;
3278                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3279                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3280                            Intent.METADATA_SETUP_VERSION);
3281                }
3282                String lastVers = Settings.Secure.getString(
3283                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3284                if (vers != null && !vers.equals(lastVers)) {
3285                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3286                    intent.setComponent(new ComponentName(
3287                            ri.activityInfo.packageName, ri.activityInfo.name));
3288                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3289                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3290                }
3291            }
3292        }
3293    }
3294
3295    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3296        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3297    }
3298
3299    void enforceNotIsolatedCaller(String caller) {
3300        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3301            throw new SecurityException("Isolated process not allowed to call " + caller);
3302        }
3303    }
3304
3305    @Override
3306    public int getFrontActivityScreenCompatMode() {
3307        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3308        synchronized (this) {
3309            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3310        }
3311    }
3312
3313    @Override
3314    public void setFrontActivityScreenCompatMode(int mode) {
3315        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3316                "setFrontActivityScreenCompatMode");
3317        synchronized (this) {
3318            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3319        }
3320    }
3321
3322    @Override
3323    public int getPackageScreenCompatMode(String packageName) {
3324        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3325        synchronized (this) {
3326            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3327        }
3328    }
3329
3330    @Override
3331    public void setPackageScreenCompatMode(String packageName, int mode) {
3332        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3333                "setPackageScreenCompatMode");
3334        synchronized (this) {
3335            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3336        }
3337    }
3338
3339    @Override
3340    public boolean getPackageAskScreenCompat(String packageName) {
3341        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3342        synchronized (this) {
3343            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3344        }
3345    }
3346
3347    @Override
3348    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3349        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3350                "setPackageAskScreenCompat");
3351        synchronized (this) {
3352            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3353        }
3354    }
3355
3356    private void dispatchProcessesChanged() {
3357        int N;
3358        synchronized (this) {
3359            N = mPendingProcessChanges.size();
3360            if (mActiveProcessChanges.length < N) {
3361                mActiveProcessChanges = new ProcessChangeItem[N];
3362            }
3363            mPendingProcessChanges.toArray(mActiveProcessChanges);
3364            mAvailProcessChanges.addAll(mPendingProcessChanges);
3365            mPendingProcessChanges.clear();
3366            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3367        }
3368
3369        int i = mProcessObservers.beginBroadcast();
3370        while (i > 0) {
3371            i--;
3372            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3373            if (observer != null) {
3374                try {
3375                    for (int j=0; j<N; j++) {
3376                        ProcessChangeItem item = mActiveProcessChanges[j];
3377                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3378                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3379                                    + item.pid + " uid=" + item.uid + ": "
3380                                    + item.foregroundActivities);
3381                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3382                                    item.foregroundActivities);
3383                        }
3384                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3385                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3386                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3387                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3388                        }
3389                    }
3390                } catch (RemoteException e) {
3391                }
3392            }
3393        }
3394        mProcessObservers.finishBroadcast();
3395    }
3396
3397    private void dispatchProcessDied(int pid, int uid) {
3398        int i = mProcessObservers.beginBroadcast();
3399        while (i > 0) {
3400            i--;
3401            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3402            if (observer != null) {
3403                try {
3404                    observer.onProcessDied(pid, uid);
3405                } catch (RemoteException e) {
3406                }
3407            }
3408        }
3409        mProcessObservers.finishBroadcast();
3410    }
3411
3412    @Override
3413    public final int startActivity(IApplicationThread caller, String callingPackage,
3414            Intent intent, String resolvedType, IBinder resultTo,
3415            String resultWho, int requestCode, int startFlags,
3416            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3417        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3418                resultWho, requestCode,
3419                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3420    }
3421
3422    @Override
3423    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3424            Intent intent, String resolvedType, IBinder resultTo,
3425            String resultWho, int requestCode, int startFlags,
3426            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3427        enforceNotIsolatedCaller("startActivity");
3428        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3429                false, ALLOW_FULL_ONLY, "startActivity", null);
3430        // TODO: Switch to user app stacks here.
3431        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3432                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3433                null, null, options, userId, null);
3434    }
3435
3436    @Override
3437    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3438            Intent intent, String resolvedType, IBinder resultTo,
3439            String resultWho, int requestCode, int startFlags, String profileFile,
3440            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3441        enforceNotIsolatedCaller("startActivityAndWait");
3442        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3443                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3444        WaitResult res = new WaitResult();
3445        // TODO: Switch to user app stacks here.
3446        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3447                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3448                res, null, options, userId, null);
3449        return res;
3450    }
3451
3452    @Override
3453    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3454            Intent intent, String resolvedType, IBinder resultTo,
3455            String resultWho, int requestCode, int startFlags, Configuration config,
3456            Bundle options, int userId) {
3457        enforceNotIsolatedCaller("startActivityWithConfig");
3458        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3459                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3460        // TODO: Switch to user app stacks here.
3461        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3462                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3463                null, null, null, config, options, userId, null);
3464        return ret;
3465    }
3466
3467    @Override
3468    public int startActivityIntentSender(IApplicationThread caller,
3469            IntentSender intent, Intent fillInIntent, String resolvedType,
3470            IBinder resultTo, String resultWho, int requestCode,
3471            int flagsMask, int flagsValues, Bundle options) {
3472        enforceNotIsolatedCaller("startActivityIntentSender");
3473        // Refuse possible leaked file descriptors
3474        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3475            throw new IllegalArgumentException("File descriptors passed in Intent");
3476        }
3477
3478        IIntentSender sender = intent.getTarget();
3479        if (!(sender instanceof PendingIntentRecord)) {
3480            throw new IllegalArgumentException("Bad PendingIntent object");
3481        }
3482
3483        PendingIntentRecord pir = (PendingIntentRecord)sender;
3484
3485        synchronized (this) {
3486            // If this is coming from the currently resumed activity, it is
3487            // effectively saying that app switches are allowed at this point.
3488            final ActivityStack stack = getFocusedStack();
3489            if (stack.mResumedActivity != null &&
3490                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3491                mAppSwitchesAllowedTime = 0;
3492            }
3493        }
3494        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3495                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3496        return ret;
3497    }
3498
3499    @Override
3500    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3501            Intent intent, String resolvedType, IVoiceInteractionSession session,
3502            IVoiceInteractor interactor, int startFlags, String profileFile,
3503            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3504        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3505                != PackageManager.PERMISSION_GRANTED) {
3506            String msg = "Permission Denial: startVoiceActivity() from pid="
3507                    + Binder.getCallingPid()
3508                    + ", uid=" + Binder.getCallingUid()
3509                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3510            Slog.w(TAG, msg);
3511            throw new SecurityException(msg);
3512        }
3513        if (session == null || interactor == null) {
3514            throw new NullPointerException("null session or interactor");
3515        }
3516        userId = handleIncomingUser(callingPid, callingUid, userId,
3517                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3518        // TODO: Switch to user app stacks here.
3519        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3520                resolvedType, session, interactor, null, null, 0, startFlags,
3521                profileFile, profileFd, null, null, options, userId, null);
3522    }
3523
3524    @Override
3525    public boolean startNextMatchingActivity(IBinder callingActivity,
3526            Intent intent, Bundle options) {
3527        // Refuse possible leaked file descriptors
3528        if (intent != null && intent.hasFileDescriptors() == true) {
3529            throw new IllegalArgumentException("File descriptors passed in Intent");
3530        }
3531
3532        synchronized (this) {
3533            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3534            if (r == null) {
3535                ActivityOptions.abort(options);
3536                return false;
3537            }
3538            if (r.app == null || r.app.thread == null) {
3539                // The caller is not running...  d'oh!
3540                ActivityOptions.abort(options);
3541                return false;
3542            }
3543            intent = new Intent(intent);
3544            // The caller is not allowed to change the data.
3545            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3546            // And we are resetting to find the next component...
3547            intent.setComponent(null);
3548
3549            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3550
3551            ActivityInfo aInfo = null;
3552            try {
3553                List<ResolveInfo> resolves =
3554                    AppGlobals.getPackageManager().queryIntentActivities(
3555                            intent, r.resolvedType,
3556                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3557                            UserHandle.getCallingUserId());
3558
3559                // Look for the original activity in the list...
3560                final int N = resolves != null ? resolves.size() : 0;
3561                for (int i=0; i<N; i++) {
3562                    ResolveInfo rInfo = resolves.get(i);
3563                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3564                            && rInfo.activityInfo.name.equals(r.info.name)) {
3565                        // We found the current one...  the next matching is
3566                        // after it.
3567                        i++;
3568                        if (i<N) {
3569                            aInfo = resolves.get(i).activityInfo;
3570                        }
3571                        if (debug) {
3572                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3573                                    + "/" + r.info.name);
3574                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3575                                    + "/" + aInfo.name);
3576                        }
3577                        break;
3578                    }
3579                }
3580            } catch (RemoteException e) {
3581            }
3582
3583            if (aInfo == null) {
3584                // Nobody who is next!
3585                ActivityOptions.abort(options);
3586                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3587                return false;
3588            }
3589
3590            intent.setComponent(new ComponentName(
3591                    aInfo.applicationInfo.packageName, aInfo.name));
3592            intent.setFlags(intent.getFlags()&~(
3593                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3594                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3595                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3596                    Intent.FLAG_ACTIVITY_NEW_TASK));
3597
3598            // Okay now we need to start the new activity, replacing the
3599            // currently running activity.  This is a little tricky because
3600            // we want to start the new one as if the current one is finished,
3601            // but not finish the current one first so that there is no flicker.
3602            // And thus...
3603            final boolean wasFinishing = r.finishing;
3604            r.finishing = true;
3605
3606            // Propagate reply information over to the new activity.
3607            final ActivityRecord resultTo = r.resultTo;
3608            final String resultWho = r.resultWho;
3609            final int requestCode = r.requestCode;
3610            r.resultTo = null;
3611            if (resultTo != null) {
3612                resultTo.removeResultsLocked(r, resultWho, requestCode);
3613            }
3614
3615            final long origId = Binder.clearCallingIdentity();
3616            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3617                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3618                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3619                    options, false, null, null);
3620            Binder.restoreCallingIdentity(origId);
3621
3622            r.finishing = wasFinishing;
3623            if (res != ActivityManager.START_SUCCESS) {
3624                return false;
3625            }
3626            return true;
3627        }
3628    }
3629
3630    @Override
3631    public final int startActivityFromRecents(int taskId, Bundle options) {
3632        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3633            String msg = "Permission Denial: startActivityFromRecents called without " +
3634                    START_TASKS_FROM_RECENTS;
3635            Slog.w(TAG, msg);
3636            throw new SecurityException(msg);
3637        }
3638        final int callingUid;
3639        final String callingPackage;
3640        final Intent intent;
3641        final int userId;
3642        synchronized (this) {
3643            final TaskRecord task = recentTaskForIdLocked(taskId);
3644            if (task == null) {
3645                throw new ActivityNotFoundException("Task " + taskId + " not found.");
3646            }
3647            callingUid = task.mCallingUid;
3648            callingPackage = task.mCallingPackage;
3649            intent = task.intent;
3650            userId = task.userId;
3651        }
3652        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3653                options, userId, null);
3654    }
3655
3656    final int startActivityInPackage(int uid, String callingPackage,
3657            Intent intent, String resolvedType, IBinder resultTo,
3658            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3659                    IActivityContainer container) {
3660
3661        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3662                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3663
3664        // TODO: Switch to user app stacks here.
3665        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3666                null, null, resultTo, resultWho, requestCode, startFlags,
3667                null, null, null, null, options, userId, container);
3668        return ret;
3669    }
3670
3671    @Override
3672    public final int startActivities(IApplicationThread caller, String callingPackage,
3673            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3674            int userId) {
3675        enforceNotIsolatedCaller("startActivities");
3676        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3677                false, ALLOW_FULL_ONLY, "startActivity", null);
3678        // TODO: Switch to user app stacks here.
3679        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3680                resolvedTypes, resultTo, options, userId);
3681        return ret;
3682    }
3683
3684    final int startActivitiesInPackage(int uid, String callingPackage,
3685            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3686            Bundle options, int userId) {
3687
3688        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3689                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3690        // TODO: Switch to user app stacks here.
3691        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3692                resultTo, options, userId);
3693        return ret;
3694    }
3695
3696    //explicitly remove thd old information in mRecentTasks when removing existing user.
3697    private void removeRecentTasksForUserLocked(int userId) {
3698        if(userId <= 0) {
3699            Slog.i(TAG, "Can't remove recent task on user " + userId);
3700            return;
3701        }
3702
3703        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3704            TaskRecord tr = mRecentTasks.get(i);
3705            if (tr.userId == userId) {
3706                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3707                        + " when finishing user" + userId);
3708                tr.disposeThumbnail();
3709                mRecentTasks.remove(i);
3710            }
3711        }
3712
3713        // Remove tasks from persistent storage.
3714        mTaskPersister.wakeup(null, true);
3715    }
3716
3717    final void addRecentTaskLocked(TaskRecord task) {
3718        int N = mRecentTasks.size();
3719        // Quick case: check if the top-most recent task is the same.
3720        if (N > 0 && mRecentTasks.get(0) == task) {
3721            return;
3722        }
3723        // Another quick case: never add voice sessions.
3724        if (task.voiceSession != null) {
3725            return;
3726        }
3727        // Remove any existing entries that are the same kind of task.
3728        final Intent intent = task.intent;
3729        final boolean document = intent != null && intent.isDocument();
3730        final ComponentName comp = intent.getComponent();
3731
3732        int maxRecents = task.maxRecents - 1;
3733        for (int i=0; i<N; i++) {
3734            final TaskRecord tr = mRecentTasks.get(i);
3735            if (task != tr) {
3736                if (task.userId != tr.userId) {
3737                    continue;
3738                }
3739                if (i > MAX_RECENT_BITMAPS) {
3740                    tr.freeLastThumbnail();
3741                }
3742                final Intent trIntent = tr.intent;
3743                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3744                    (intent == null || !intent.filterEquals(trIntent))) {
3745                    continue;
3746                }
3747                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3748                if (document && trIsDocument) {
3749                    // These are the same document activity (not necessarily the same doc).
3750                    if (maxRecents > 0) {
3751                        --maxRecents;
3752                        continue;
3753                    }
3754                    // Hit the maximum number of documents for this task. Fall through
3755                    // and remove this document from recents.
3756                } else if (document || trIsDocument) {
3757                    // Only one of these is a document. Not the droid we're looking for.
3758                    continue;
3759                }
3760            }
3761
3762            // Either task and tr are the same or, their affinities match or their intents match
3763            // and neither of them is a document, or they are documents using the same activity
3764            // and their maxRecents has been reached.
3765            tr.disposeThumbnail();
3766            mRecentTasks.remove(i);
3767            if (task != tr) {
3768                tr.closeRecentsChain();
3769            }
3770            i--;
3771            N--;
3772            if (task.intent == null) {
3773                // If the new recent task we are adding is not fully
3774                // specified, then replace it with the existing recent task.
3775                task = tr;
3776            }
3777            notifyTaskPersisterLocked(tr, false);
3778        }
3779        if (N >= MAX_RECENT_TASKS) {
3780            final TaskRecord tr = mRecentTasks.remove(N - 1);
3781            tr.disposeThumbnail();
3782            tr.closeRecentsChain();
3783        }
3784        mRecentTasks.add(0, task);
3785    }
3786
3787    @Override
3788    public void reportActivityFullyDrawn(IBinder token) {
3789        synchronized (this) {
3790            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3791            if (r == null) {
3792                return;
3793            }
3794            r.reportFullyDrawnLocked();
3795        }
3796    }
3797
3798    @Override
3799    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3800        synchronized (this) {
3801            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3802            if (r == null) {
3803                return;
3804            }
3805            final long origId = Binder.clearCallingIdentity();
3806            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3807            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3808                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3809            if (config != null) {
3810                r.frozenBeforeDestroy = true;
3811                if (!updateConfigurationLocked(config, r, false, false)) {
3812                    mStackSupervisor.resumeTopActivitiesLocked();
3813                }
3814            }
3815            Binder.restoreCallingIdentity(origId);
3816        }
3817    }
3818
3819    @Override
3820    public int getRequestedOrientation(IBinder token) {
3821        synchronized (this) {
3822            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3823            if (r == null) {
3824                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3825            }
3826            return mWindowManager.getAppOrientation(r.appToken);
3827        }
3828    }
3829
3830    /**
3831     * This is the internal entry point for handling Activity.finish().
3832     *
3833     * @param token The Binder token referencing the Activity we want to finish.
3834     * @param resultCode Result code, if any, from this Activity.
3835     * @param resultData Result data (Intent), if any, from this Activity.
3836     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3837     *            the root Activity in the task.
3838     *
3839     * @return Returns true if the activity successfully finished, or false if it is still running.
3840     */
3841    @Override
3842    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3843            boolean finishTask) {
3844        // Refuse possible leaked file descriptors
3845        if (resultData != null && resultData.hasFileDescriptors() == true) {
3846            throw new IllegalArgumentException("File descriptors passed in Intent");
3847        }
3848
3849        synchronized(this) {
3850            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3851            if (r == null) {
3852                return true;
3853            }
3854            // Keep track of the root activity of the task before we finish it
3855            TaskRecord tr = r.task;
3856            ActivityRecord rootR = tr.getRootActivity();
3857            // Do not allow task to finish in Lock Task mode.
3858            if (tr == mStackSupervisor.mLockTaskModeTask) {
3859                if (rootR == r) {
3860                    mStackSupervisor.showLockTaskToast();
3861                    return false;
3862                }
3863            }
3864            if (mController != null) {
3865                // Find the first activity that is not finishing.
3866                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3867                if (next != null) {
3868                    // ask watcher if this is allowed
3869                    boolean resumeOK = true;
3870                    try {
3871                        resumeOK = mController.activityResuming(next.packageName);
3872                    } catch (RemoteException e) {
3873                        mController = null;
3874                        Watchdog.getInstance().setActivityController(null);
3875                    }
3876
3877                    if (!resumeOK) {
3878                        return false;
3879                    }
3880                }
3881            }
3882            final long origId = Binder.clearCallingIdentity();
3883            try {
3884                boolean res;
3885                if (finishTask && r == rootR) {
3886                    // If requested, remove the task that is associated to this activity only if it
3887                    // was the root activity in the task.  The result code and data is ignored because
3888                    // we don't support returning them across task boundaries.
3889                    res = removeTaskByIdLocked(tr.taskId, 0);
3890                } else {
3891                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3892                            resultData, "app-request", true);
3893                }
3894                return res;
3895            } finally {
3896                Binder.restoreCallingIdentity(origId);
3897            }
3898        }
3899    }
3900
3901    @Override
3902    public final void finishHeavyWeightApp() {
3903        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3904                != PackageManager.PERMISSION_GRANTED) {
3905            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3906                    + Binder.getCallingPid()
3907                    + ", uid=" + Binder.getCallingUid()
3908                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3909            Slog.w(TAG, msg);
3910            throw new SecurityException(msg);
3911        }
3912
3913        synchronized(this) {
3914            if (mHeavyWeightProcess == null) {
3915                return;
3916            }
3917
3918            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3919                    mHeavyWeightProcess.activities);
3920            for (int i=0; i<activities.size(); i++) {
3921                ActivityRecord r = activities.get(i);
3922                if (!r.finishing) {
3923                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3924                            null, "finish-heavy", true);
3925                }
3926            }
3927
3928            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3929                    mHeavyWeightProcess.userId, 0));
3930            mHeavyWeightProcess = null;
3931        }
3932    }
3933
3934    @Override
3935    public void crashApplication(int uid, int initialPid, String packageName,
3936            String message) {
3937        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3938                != PackageManager.PERMISSION_GRANTED) {
3939            String msg = "Permission Denial: crashApplication() from pid="
3940                    + Binder.getCallingPid()
3941                    + ", uid=" + Binder.getCallingUid()
3942                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3943            Slog.w(TAG, msg);
3944            throw new SecurityException(msg);
3945        }
3946
3947        synchronized(this) {
3948            ProcessRecord proc = null;
3949
3950            // Figure out which process to kill.  We don't trust that initialPid
3951            // still has any relation to current pids, so must scan through the
3952            // list.
3953            synchronized (mPidsSelfLocked) {
3954                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3955                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3956                    if (p.uid != uid) {
3957                        continue;
3958                    }
3959                    if (p.pid == initialPid) {
3960                        proc = p;
3961                        break;
3962                    }
3963                    if (p.pkgList.containsKey(packageName)) {
3964                        proc = p;
3965                    }
3966                }
3967            }
3968
3969            if (proc == null) {
3970                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3971                        + " initialPid=" + initialPid
3972                        + " packageName=" + packageName);
3973                return;
3974            }
3975
3976            if (proc.thread != null) {
3977                if (proc.pid == Process.myPid()) {
3978                    Log.w(TAG, "crashApplication: trying to crash self!");
3979                    return;
3980                }
3981                long ident = Binder.clearCallingIdentity();
3982                try {
3983                    proc.thread.scheduleCrash(message);
3984                } catch (RemoteException e) {
3985                }
3986                Binder.restoreCallingIdentity(ident);
3987            }
3988        }
3989    }
3990
3991    @Override
3992    public final void finishSubActivity(IBinder token, String resultWho,
3993            int requestCode) {
3994        synchronized(this) {
3995            final long origId = Binder.clearCallingIdentity();
3996            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3997            if (r != null) {
3998                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3999            }
4000            Binder.restoreCallingIdentity(origId);
4001        }
4002    }
4003
4004    @Override
4005    public boolean finishActivityAffinity(IBinder token) {
4006        synchronized(this) {
4007            final long origId = Binder.clearCallingIdentity();
4008            try {
4009                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4010
4011                ActivityRecord rootR = r.task.getRootActivity();
4012                // Do not allow task to finish in Lock Task mode.
4013                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4014                    if (rootR == r) {
4015                        mStackSupervisor.showLockTaskToast();
4016                        return false;
4017                    }
4018                }
4019                boolean res = false;
4020                if (r != null) {
4021                    res = r.task.stack.finishActivityAffinityLocked(r);
4022                }
4023                return res;
4024            } finally {
4025                Binder.restoreCallingIdentity(origId);
4026            }
4027        }
4028    }
4029
4030    @Override
4031    public void finishVoiceTask(IVoiceInteractionSession session) {
4032        synchronized(this) {
4033            final long origId = Binder.clearCallingIdentity();
4034            try {
4035                mStackSupervisor.finishVoiceTask(session);
4036            } finally {
4037                Binder.restoreCallingIdentity(origId);
4038            }
4039        }
4040
4041    }
4042
4043    @Override
4044    public boolean willActivityBeVisible(IBinder token) {
4045        synchronized(this) {
4046            ActivityStack stack = ActivityRecord.getStackLocked(token);
4047            if (stack != null) {
4048                return stack.willActivityBeVisibleLocked(token);
4049            }
4050            return false;
4051        }
4052    }
4053
4054    @Override
4055    public void overridePendingTransition(IBinder token, String packageName,
4056            int enterAnim, int exitAnim) {
4057        synchronized(this) {
4058            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4059            if (self == null) {
4060                return;
4061            }
4062
4063            final long origId = Binder.clearCallingIdentity();
4064
4065            if (self.state == ActivityState.RESUMED
4066                    || self.state == ActivityState.PAUSING) {
4067                mWindowManager.overridePendingAppTransition(packageName,
4068                        enterAnim, exitAnim, null);
4069            }
4070
4071            Binder.restoreCallingIdentity(origId);
4072        }
4073    }
4074
4075    /**
4076     * Main function for removing an existing process from the activity manager
4077     * as a result of that process going away.  Clears out all connections
4078     * to the process.
4079     */
4080    private final void handleAppDiedLocked(ProcessRecord app,
4081            boolean restarting, boolean allowRestart) {
4082        int pid = app.pid;
4083        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4084        if (!restarting) {
4085            removeLruProcessLocked(app);
4086            if (pid > 0) {
4087                ProcessList.remove(pid);
4088            }
4089        }
4090
4091        if (mProfileProc == app) {
4092            clearProfilerLocked();
4093        }
4094
4095        // Remove this application's activities from active lists.
4096        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4097
4098        app.activities.clear();
4099
4100        if (app.instrumentationClass != null) {
4101            Slog.w(TAG, "Crash of app " + app.processName
4102                  + " running instrumentation " + app.instrumentationClass);
4103            Bundle info = new Bundle();
4104            info.putString("shortMsg", "Process crashed.");
4105            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4106        }
4107
4108        if (!restarting) {
4109            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4110                // If there was nothing to resume, and we are not already
4111                // restarting this process, but there is a visible activity that
4112                // is hosted by the process...  then make sure all visible
4113                // activities are running, taking care of restarting this
4114                // process.
4115                if (hasVisibleActivities) {
4116                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4117                }
4118            }
4119        }
4120    }
4121
4122    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4123        IBinder threadBinder = thread.asBinder();
4124        // Find the application record.
4125        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4126            ProcessRecord rec = mLruProcesses.get(i);
4127            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4128                return i;
4129            }
4130        }
4131        return -1;
4132    }
4133
4134    final ProcessRecord getRecordForAppLocked(
4135            IApplicationThread thread) {
4136        if (thread == null) {
4137            return null;
4138        }
4139
4140        int appIndex = getLRURecordIndexForAppLocked(thread);
4141        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4142    }
4143
4144    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4145        // If there are no longer any background processes running,
4146        // and the app that died was not running instrumentation,
4147        // then tell everyone we are now low on memory.
4148        boolean haveBg = false;
4149        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4150            ProcessRecord rec = mLruProcesses.get(i);
4151            if (rec.thread != null
4152                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4153                haveBg = true;
4154                break;
4155            }
4156        }
4157
4158        if (!haveBg) {
4159            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4160            if (doReport) {
4161                long now = SystemClock.uptimeMillis();
4162                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4163                    doReport = false;
4164                } else {
4165                    mLastMemUsageReportTime = now;
4166                }
4167            }
4168            final ArrayList<ProcessMemInfo> memInfos
4169                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4170            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4171            long now = SystemClock.uptimeMillis();
4172            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4173                ProcessRecord rec = mLruProcesses.get(i);
4174                if (rec == dyingProc || rec.thread == null) {
4175                    continue;
4176                }
4177                if (doReport) {
4178                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4179                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4180                }
4181                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4182                    // The low memory report is overriding any current
4183                    // state for a GC request.  Make sure to do
4184                    // heavy/important/visible/foreground processes first.
4185                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4186                        rec.lastRequestedGc = 0;
4187                    } else {
4188                        rec.lastRequestedGc = rec.lastLowMemory;
4189                    }
4190                    rec.reportLowMemory = true;
4191                    rec.lastLowMemory = now;
4192                    mProcessesToGc.remove(rec);
4193                    addProcessToGcListLocked(rec);
4194                }
4195            }
4196            if (doReport) {
4197                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4198                mHandler.sendMessage(msg);
4199            }
4200            scheduleAppGcsLocked();
4201        }
4202    }
4203
4204    final void appDiedLocked(ProcessRecord app, int pid,
4205            IApplicationThread thread) {
4206
4207        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4208        synchronized (stats) {
4209            stats.noteProcessDiedLocked(app.info.uid, pid);
4210        }
4211
4212        Process.killProcessGroup(app.info.uid, pid);
4213
4214        // Clean up already done if the process has been re-started.
4215        if (app.pid == pid && app.thread != null &&
4216                app.thread.asBinder() == thread.asBinder()) {
4217            boolean doLowMem = app.instrumentationClass == null;
4218            boolean doOomAdj = doLowMem;
4219            if (!app.killedByAm) {
4220                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4221                        + ") has died.");
4222                mAllowLowerMemLevel = true;
4223            } else {
4224                // Note that we always want to do oom adj to update our state with the
4225                // new number of procs.
4226                mAllowLowerMemLevel = false;
4227                doLowMem = false;
4228            }
4229            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4230            if (DEBUG_CLEANUP) Slog.v(
4231                TAG, "Dying app: " + app + ", pid: " + pid
4232                + ", thread: " + thread.asBinder());
4233            handleAppDiedLocked(app, false, true);
4234
4235            if (doOomAdj) {
4236                updateOomAdjLocked();
4237            }
4238            if (doLowMem) {
4239                doLowMemReportIfNeededLocked(app);
4240            }
4241        } else if (app.pid != pid) {
4242            // A new process has already been started.
4243            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4244                    + ") has died and restarted (pid " + app.pid + ").");
4245            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4246        } else if (DEBUG_PROCESSES) {
4247            Slog.d(TAG, "Received spurious death notification for thread "
4248                    + thread.asBinder());
4249        }
4250    }
4251
4252    /**
4253     * If a stack trace dump file is configured, dump process stack traces.
4254     * @param clearTraces causes the dump file to be erased prior to the new
4255     *    traces being written, if true; when false, the new traces will be
4256     *    appended to any existing file content.
4257     * @param firstPids of dalvik VM processes to dump stack traces for first
4258     * @param lastPids of dalvik VM processes to dump stack traces for last
4259     * @param nativeProcs optional list of native process names to dump stack crawls
4260     * @return file containing stack traces, or null if no dump file is configured
4261     */
4262    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4263            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4264        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4265        if (tracesPath == null || tracesPath.length() == 0) {
4266            return null;
4267        }
4268
4269        File tracesFile = new File(tracesPath);
4270        try {
4271            File tracesDir = tracesFile.getParentFile();
4272            if (!tracesDir.exists()) {
4273                tracesFile.mkdirs();
4274                if (!SELinux.restorecon(tracesDir)) {
4275                    return null;
4276                }
4277            }
4278            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4279
4280            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4281            tracesFile.createNewFile();
4282            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4283        } catch (IOException e) {
4284            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4285            return null;
4286        }
4287
4288        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4289        return tracesFile;
4290    }
4291
4292    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4293            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4294        // Use a FileObserver to detect when traces finish writing.
4295        // The order of traces is considered important to maintain for legibility.
4296        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4297            @Override
4298            public synchronized void onEvent(int event, String path) { notify(); }
4299        };
4300
4301        try {
4302            observer.startWatching();
4303
4304            // First collect all of the stacks of the most important pids.
4305            if (firstPids != null) {
4306                try {
4307                    int num = firstPids.size();
4308                    for (int i = 0; i < num; i++) {
4309                        synchronized (observer) {
4310                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4311                            observer.wait(200);  // Wait for write-close, give up after 200msec
4312                        }
4313                    }
4314                } catch (InterruptedException e) {
4315                    Log.wtf(TAG, e);
4316                }
4317            }
4318
4319            // Next collect the stacks of the native pids
4320            if (nativeProcs != null) {
4321                int[] pids = Process.getPidsForCommands(nativeProcs);
4322                if (pids != null) {
4323                    for (int pid : pids) {
4324                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4325                    }
4326                }
4327            }
4328
4329            // Lastly, measure CPU usage.
4330            if (processCpuTracker != null) {
4331                processCpuTracker.init();
4332                System.gc();
4333                processCpuTracker.update();
4334                try {
4335                    synchronized (processCpuTracker) {
4336                        processCpuTracker.wait(500); // measure over 1/2 second.
4337                    }
4338                } catch (InterruptedException e) {
4339                }
4340                processCpuTracker.update();
4341
4342                // We'll take the stack crawls of just the top apps using CPU.
4343                final int N = processCpuTracker.countWorkingStats();
4344                int numProcs = 0;
4345                for (int i=0; i<N && numProcs<5; i++) {
4346                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4347                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4348                        numProcs++;
4349                        try {
4350                            synchronized (observer) {
4351                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4352                                observer.wait(200);  // Wait for write-close, give up after 200msec
4353                            }
4354                        } catch (InterruptedException e) {
4355                            Log.wtf(TAG, e);
4356                        }
4357
4358                    }
4359                }
4360            }
4361        } finally {
4362            observer.stopWatching();
4363        }
4364    }
4365
4366    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4367        if (true || IS_USER_BUILD) {
4368            return;
4369        }
4370        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4371        if (tracesPath == null || tracesPath.length() == 0) {
4372            return;
4373        }
4374
4375        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4376        StrictMode.allowThreadDiskWrites();
4377        try {
4378            final File tracesFile = new File(tracesPath);
4379            final File tracesDir = tracesFile.getParentFile();
4380            final File tracesTmp = new File(tracesDir, "__tmp__");
4381            try {
4382                if (!tracesDir.exists()) {
4383                    tracesFile.mkdirs();
4384                    if (!SELinux.restorecon(tracesDir.getPath())) {
4385                        return;
4386                    }
4387                }
4388                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4389
4390                if (tracesFile.exists()) {
4391                    tracesTmp.delete();
4392                    tracesFile.renameTo(tracesTmp);
4393                }
4394                StringBuilder sb = new StringBuilder();
4395                Time tobj = new Time();
4396                tobj.set(System.currentTimeMillis());
4397                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4398                sb.append(": ");
4399                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4400                sb.append(" since ");
4401                sb.append(msg);
4402                FileOutputStream fos = new FileOutputStream(tracesFile);
4403                fos.write(sb.toString().getBytes());
4404                if (app == null) {
4405                    fos.write("\n*** No application process!".getBytes());
4406                }
4407                fos.close();
4408                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4409            } catch (IOException e) {
4410                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4411                return;
4412            }
4413
4414            if (app != null) {
4415                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4416                firstPids.add(app.pid);
4417                dumpStackTraces(tracesPath, firstPids, null, null, null);
4418            }
4419
4420            File lastTracesFile = null;
4421            File curTracesFile = null;
4422            for (int i=9; i>=0; i--) {
4423                String name = String.format(Locale.US, "slow%02d.txt", i);
4424                curTracesFile = new File(tracesDir, name);
4425                if (curTracesFile.exists()) {
4426                    if (lastTracesFile != null) {
4427                        curTracesFile.renameTo(lastTracesFile);
4428                    } else {
4429                        curTracesFile.delete();
4430                    }
4431                }
4432                lastTracesFile = curTracesFile;
4433            }
4434            tracesFile.renameTo(curTracesFile);
4435            if (tracesTmp.exists()) {
4436                tracesTmp.renameTo(tracesFile);
4437            }
4438        } finally {
4439            StrictMode.setThreadPolicy(oldPolicy);
4440        }
4441    }
4442
4443    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4444            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4445        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4446        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4447
4448        if (mController != null) {
4449            try {
4450                // 0 == continue, -1 = kill process immediately
4451                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4452                if (res < 0 && app.pid != MY_PID) {
4453                    Process.killProcess(app.pid);
4454                    Process.killProcessGroup(app.info.uid, app.pid);
4455                }
4456            } catch (RemoteException e) {
4457                mController = null;
4458                Watchdog.getInstance().setActivityController(null);
4459            }
4460        }
4461
4462        long anrTime = SystemClock.uptimeMillis();
4463        if (MONITOR_CPU_USAGE) {
4464            updateCpuStatsNow();
4465        }
4466
4467        synchronized (this) {
4468            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4469            if (mShuttingDown) {
4470                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4471                return;
4472            } else if (app.notResponding) {
4473                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4474                return;
4475            } else if (app.crashing) {
4476                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4477                return;
4478            }
4479
4480            // In case we come through here for the same app before completing
4481            // this one, mark as anring now so we will bail out.
4482            app.notResponding = true;
4483
4484            // Log the ANR to the event log.
4485            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4486                    app.processName, app.info.flags, annotation);
4487
4488            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4489            firstPids.add(app.pid);
4490
4491            int parentPid = app.pid;
4492            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4493            if (parentPid != app.pid) firstPids.add(parentPid);
4494
4495            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4496
4497            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4498                ProcessRecord r = mLruProcesses.get(i);
4499                if (r != null && r.thread != null) {
4500                    int pid = r.pid;
4501                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4502                        if (r.persistent) {
4503                            firstPids.add(pid);
4504                        } else {
4505                            lastPids.put(pid, Boolean.TRUE);
4506                        }
4507                    }
4508                }
4509            }
4510        }
4511
4512        // Log the ANR to the main log.
4513        StringBuilder info = new StringBuilder();
4514        info.setLength(0);
4515        info.append("ANR in ").append(app.processName);
4516        if (activity != null && activity.shortComponentName != null) {
4517            info.append(" (").append(activity.shortComponentName).append(")");
4518        }
4519        info.append("\n");
4520        info.append("PID: ").append(app.pid).append("\n");
4521        if (annotation != null) {
4522            info.append("Reason: ").append(annotation).append("\n");
4523        }
4524        if (parent != null && parent != activity) {
4525            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4526        }
4527
4528        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4529
4530        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4531                NATIVE_STACKS_OF_INTEREST);
4532
4533        String cpuInfo = null;
4534        if (MONITOR_CPU_USAGE) {
4535            updateCpuStatsNow();
4536            synchronized (mProcessCpuThread) {
4537                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4538            }
4539            info.append(processCpuTracker.printCurrentLoad());
4540            info.append(cpuInfo);
4541        }
4542
4543        info.append(processCpuTracker.printCurrentState(anrTime));
4544
4545        Slog.e(TAG, info.toString());
4546        if (tracesFile == null) {
4547            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4548            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4549        }
4550
4551        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4552                cpuInfo, tracesFile, null);
4553
4554        if (mController != null) {
4555            try {
4556                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4557                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4558                if (res != 0) {
4559                    if (res < 0 && app.pid != MY_PID) {
4560                        Process.killProcess(app.pid);
4561                        Process.killProcessGroup(app.info.uid, app.pid);
4562                    } else {
4563                        synchronized (this) {
4564                            mServices.scheduleServiceTimeoutLocked(app);
4565                        }
4566                    }
4567                    return;
4568                }
4569            } catch (RemoteException e) {
4570                mController = null;
4571                Watchdog.getInstance().setActivityController(null);
4572            }
4573        }
4574
4575        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4576        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4577                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4578
4579        synchronized (this) {
4580            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4581                killUnneededProcessLocked(app, "background ANR");
4582                return;
4583            }
4584
4585            // Set the app's notResponding state, and look up the errorReportReceiver
4586            makeAppNotRespondingLocked(app,
4587                    activity != null ? activity.shortComponentName : null,
4588                    annotation != null ? "ANR " + annotation : "ANR",
4589                    info.toString());
4590
4591            // Bring up the infamous App Not Responding dialog
4592            Message msg = Message.obtain();
4593            HashMap<String, Object> map = new HashMap<String, Object>();
4594            msg.what = SHOW_NOT_RESPONDING_MSG;
4595            msg.obj = map;
4596            msg.arg1 = aboveSystem ? 1 : 0;
4597            map.put("app", app);
4598            if (activity != null) {
4599                map.put("activity", activity);
4600            }
4601
4602            mHandler.sendMessage(msg);
4603        }
4604    }
4605
4606    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4607        if (!mLaunchWarningShown) {
4608            mLaunchWarningShown = true;
4609            mHandler.post(new Runnable() {
4610                @Override
4611                public void run() {
4612                    synchronized (ActivityManagerService.this) {
4613                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4614                        d.show();
4615                        mHandler.postDelayed(new Runnable() {
4616                            @Override
4617                            public void run() {
4618                                synchronized (ActivityManagerService.this) {
4619                                    d.dismiss();
4620                                    mLaunchWarningShown = false;
4621                                }
4622                            }
4623                        }, 4000);
4624                    }
4625                }
4626            });
4627        }
4628    }
4629
4630    @Override
4631    public boolean clearApplicationUserData(final String packageName,
4632            final IPackageDataObserver observer, int userId) {
4633        enforceNotIsolatedCaller("clearApplicationUserData");
4634        int uid = Binder.getCallingUid();
4635        int pid = Binder.getCallingPid();
4636        userId = handleIncomingUser(pid, uid,
4637                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4638        long callingId = Binder.clearCallingIdentity();
4639        try {
4640            IPackageManager pm = AppGlobals.getPackageManager();
4641            int pkgUid = -1;
4642            synchronized(this) {
4643                try {
4644                    pkgUid = pm.getPackageUid(packageName, userId);
4645                } catch (RemoteException e) {
4646                }
4647                if (pkgUid == -1) {
4648                    Slog.w(TAG, "Invalid packageName: " + packageName);
4649                    if (observer != null) {
4650                        try {
4651                            observer.onRemoveCompleted(packageName, false);
4652                        } catch (RemoteException e) {
4653                            Slog.i(TAG, "Observer no longer exists.");
4654                        }
4655                    }
4656                    return false;
4657                }
4658                if (uid == pkgUid || checkComponentPermission(
4659                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4660                        pid, uid, -1, true)
4661                        == PackageManager.PERMISSION_GRANTED) {
4662                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4663                } else {
4664                    throw new SecurityException("PID " + pid + " does not have permission "
4665                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4666                                    + " of package " + packageName);
4667                }
4668
4669                // Remove all tasks match the cleared application package and user
4670                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
4671                    final TaskRecord tr = mRecentTasks.get(i);
4672                    final String taskPackageName =
4673                            tr.getBaseIntent().getComponent().getPackageName();
4674                    if (tr.userId != userId) continue;
4675                    if (!taskPackageName.equals(packageName)) continue;
4676                    removeTaskByIdLocked(tr.taskId, 0);
4677                }
4678            }
4679
4680            try {
4681                // Clear application user data
4682                pm.clearApplicationUserData(packageName, observer, userId);
4683
4684                synchronized(this) {
4685                    // Remove all permissions granted from/to this package
4686                    removeUriPermissionsForPackageLocked(packageName, userId, true);
4687                }
4688
4689                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4690                        Uri.fromParts("package", packageName, null));
4691                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4692                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4693                        null, null, 0, null, null, null, false, false, userId);
4694            } catch (RemoteException e) {
4695            }
4696        } finally {
4697            Binder.restoreCallingIdentity(callingId);
4698        }
4699        return true;
4700    }
4701
4702    @Override
4703    public void killBackgroundProcesses(final String packageName, int userId) {
4704        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4705                != PackageManager.PERMISSION_GRANTED &&
4706                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4707                        != PackageManager.PERMISSION_GRANTED) {
4708            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4709                    + Binder.getCallingPid()
4710                    + ", uid=" + Binder.getCallingUid()
4711                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4712            Slog.w(TAG, msg);
4713            throw new SecurityException(msg);
4714        }
4715
4716        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4717                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4718        long callingId = Binder.clearCallingIdentity();
4719        try {
4720            IPackageManager pm = AppGlobals.getPackageManager();
4721            synchronized(this) {
4722                int appId = -1;
4723                try {
4724                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4725                } catch (RemoteException e) {
4726                }
4727                if (appId == -1) {
4728                    Slog.w(TAG, "Invalid packageName: " + packageName);
4729                    return;
4730                }
4731                killPackageProcessesLocked(packageName, appId, userId,
4732                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4733            }
4734        } finally {
4735            Binder.restoreCallingIdentity(callingId);
4736        }
4737    }
4738
4739    @Override
4740    public void killAllBackgroundProcesses() {
4741        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4742                != PackageManager.PERMISSION_GRANTED) {
4743            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4744                    + Binder.getCallingPid()
4745                    + ", uid=" + Binder.getCallingUid()
4746                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4747            Slog.w(TAG, msg);
4748            throw new SecurityException(msg);
4749        }
4750
4751        long callingId = Binder.clearCallingIdentity();
4752        try {
4753            synchronized(this) {
4754                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4755                final int NP = mProcessNames.getMap().size();
4756                for (int ip=0; ip<NP; ip++) {
4757                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4758                    final int NA = apps.size();
4759                    for (int ia=0; ia<NA; ia++) {
4760                        ProcessRecord app = apps.valueAt(ia);
4761                        if (app.persistent) {
4762                            // we don't kill persistent processes
4763                            continue;
4764                        }
4765                        if (app.removed) {
4766                            procs.add(app);
4767                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4768                            app.removed = true;
4769                            procs.add(app);
4770                        }
4771                    }
4772                }
4773
4774                int N = procs.size();
4775                for (int i=0; i<N; i++) {
4776                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4777                }
4778                mAllowLowerMemLevel = true;
4779                updateOomAdjLocked();
4780                doLowMemReportIfNeededLocked(null);
4781            }
4782        } finally {
4783            Binder.restoreCallingIdentity(callingId);
4784        }
4785    }
4786
4787    @Override
4788    public void forceStopPackage(final String packageName, int userId) {
4789        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4790                != PackageManager.PERMISSION_GRANTED) {
4791            String msg = "Permission Denial: forceStopPackage() from pid="
4792                    + Binder.getCallingPid()
4793                    + ", uid=" + Binder.getCallingUid()
4794                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4795            Slog.w(TAG, msg);
4796            throw new SecurityException(msg);
4797        }
4798        final int callingPid = Binder.getCallingPid();
4799        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4800                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4801        long callingId = Binder.clearCallingIdentity();
4802        try {
4803            IPackageManager pm = AppGlobals.getPackageManager();
4804            synchronized(this) {
4805                int[] users = userId == UserHandle.USER_ALL
4806                        ? getUsersLocked() : new int[] { userId };
4807                for (int user : users) {
4808                    int pkgUid = -1;
4809                    try {
4810                        pkgUid = pm.getPackageUid(packageName, user);
4811                    } catch (RemoteException e) {
4812                    }
4813                    if (pkgUid == -1) {
4814                        Slog.w(TAG, "Invalid packageName: " + packageName);
4815                        continue;
4816                    }
4817                    try {
4818                        pm.setPackageStoppedState(packageName, true, user);
4819                    } catch (RemoteException e) {
4820                    } catch (IllegalArgumentException e) {
4821                        Slog.w(TAG, "Failed trying to unstop package "
4822                                + packageName + ": " + e);
4823                    }
4824                    if (isUserRunningLocked(user, false)) {
4825                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4826                    }
4827                }
4828            }
4829        } finally {
4830            Binder.restoreCallingIdentity(callingId);
4831        }
4832    }
4833
4834    @Override
4835    public void addPackageDependency(String packageName) {
4836        synchronized (this) {
4837            int callingPid = Binder.getCallingPid();
4838            if (callingPid == Process.myPid()) {
4839                //  Yeah, um, no.
4840                Slog.w(TAG, "Can't addPackageDependency on system process");
4841                return;
4842            }
4843            ProcessRecord proc;
4844            synchronized (mPidsSelfLocked) {
4845                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4846            }
4847            if (proc != null) {
4848                if (proc.pkgDeps == null) {
4849                    proc.pkgDeps = new ArraySet<String>(1);
4850                }
4851                proc.pkgDeps.add(packageName);
4852            }
4853        }
4854    }
4855
4856    /*
4857     * The pkg name and app id have to be specified.
4858     */
4859    @Override
4860    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4861        if (pkg == null) {
4862            return;
4863        }
4864        // Make sure the uid is valid.
4865        if (appid < 0) {
4866            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4867            return;
4868        }
4869        int callerUid = Binder.getCallingUid();
4870        // Only the system server can kill an application
4871        if (callerUid == Process.SYSTEM_UID) {
4872            // Post an aysnc message to kill the application
4873            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4874            msg.arg1 = appid;
4875            msg.arg2 = 0;
4876            Bundle bundle = new Bundle();
4877            bundle.putString("pkg", pkg);
4878            bundle.putString("reason", reason);
4879            msg.obj = bundle;
4880            mHandler.sendMessage(msg);
4881        } else {
4882            throw new SecurityException(callerUid + " cannot kill pkg: " +
4883                    pkg);
4884        }
4885    }
4886
4887    @Override
4888    public void closeSystemDialogs(String reason) {
4889        enforceNotIsolatedCaller("closeSystemDialogs");
4890
4891        final int pid = Binder.getCallingPid();
4892        final int uid = Binder.getCallingUid();
4893        final long origId = Binder.clearCallingIdentity();
4894        try {
4895            synchronized (this) {
4896                // Only allow this from foreground processes, so that background
4897                // applications can't abuse it to prevent system UI from being shown.
4898                if (uid >= Process.FIRST_APPLICATION_UID) {
4899                    ProcessRecord proc;
4900                    synchronized (mPidsSelfLocked) {
4901                        proc = mPidsSelfLocked.get(pid);
4902                    }
4903                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4904                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4905                                + " from background process " + proc);
4906                        return;
4907                    }
4908                }
4909                closeSystemDialogsLocked(reason);
4910            }
4911        } finally {
4912            Binder.restoreCallingIdentity(origId);
4913        }
4914    }
4915
4916    void closeSystemDialogsLocked(String reason) {
4917        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4918        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4919                | Intent.FLAG_RECEIVER_FOREGROUND);
4920        if (reason != null) {
4921            intent.putExtra("reason", reason);
4922        }
4923        mWindowManager.closeSystemDialogs(reason);
4924
4925        mStackSupervisor.closeSystemDialogsLocked();
4926
4927        broadcastIntentLocked(null, null, intent, null,
4928                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4929                Process.SYSTEM_UID, UserHandle.USER_ALL);
4930    }
4931
4932    @Override
4933    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4934        enforceNotIsolatedCaller("getProcessMemoryInfo");
4935        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4936        for (int i=pids.length-1; i>=0; i--) {
4937            ProcessRecord proc;
4938            int oomAdj;
4939            synchronized (this) {
4940                synchronized (mPidsSelfLocked) {
4941                    proc = mPidsSelfLocked.get(pids[i]);
4942                    oomAdj = proc != null ? proc.setAdj : 0;
4943                }
4944            }
4945            infos[i] = new Debug.MemoryInfo();
4946            Debug.getMemoryInfo(pids[i], infos[i]);
4947            if (proc != null) {
4948                synchronized (this) {
4949                    if (proc.thread != null && proc.setAdj == oomAdj) {
4950                        // Record this for posterity if the process has been stable.
4951                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4952                                infos[i].getTotalUss(), false, proc.pkgList);
4953                    }
4954                }
4955            }
4956        }
4957        return infos;
4958    }
4959
4960    @Override
4961    public long[] getProcessPss(int[] pids) {
4962        enforceNotIsolatedCaller("getProcessPss");
4963        long[] pss = new long[pids.length];
4964        for (int i=pids.length-1; i>=0; i--) {
4965            ProcessRecord proc;
4966            int oomAdj;
4967            synchronized (this) {
4968                synchronized (mPidsSelfLocked) {
4969                    proc = mPidsSelfLocked.get(pids[i]);
4970                    oomAdj = proc != null ? proc.setAdj : 0;
4971                }
4972            }
4973            long[] tmpUss = new long[1];
4974            pss[i] = Debug.getPss(pids[i], tmpUss);
4975            if (proc != null) {
4976                synchronized (this) {
4977                    if (proc.thread != null && proc.setAdj == oomAdj) {
4978                        // Record this for posterity if the process has been stable.
4979                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4980                    }
4981                }
4982            }
4983        }
4984        return pss;
4985    }
4986
4987    @Override
4988    public void killApplicationProcess(String processName, int uid) {
4989        if (processName == null) {
4990            return;
4991        }
4992
4993        int callerUid = Binder.getCallingUid();
4994        // Only the system server can kill an application
4995        if (callerUid == Process.SYSTEM_UID) {
4996            synchronized (this) {
4997                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4998                if (app != null && app.thread != null) {
4999                    try {
5000                        app.thread.scheduleSuicide();
5001                    } catch (RemoteException e) {
5002                        // If the other end already died, then our work here is done.
5003                    }
5004                } else {
5005                    Slog.w(TAG, "Process/uid not found attempting kill of "
5006                            + processName + " / " + uid);
5007                }
5008            }
5009        } else {
5010            throw new SecurityException(callerUid + " cannot kill app process: " +
5011                    processName);
5012        }
5013    }
5014
5015    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5016        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5017                false, true, false, false, UserHandle.getUserId(uid), reason);
5018        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5019                Uri.fromParts("package", packageName, null));
5020        if (!mProcessesReady) {
5021            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5022                    | Intent.FLAG_RECEIVER_FOREGROUND);
5023        }
5024        intent.putExtra(Intent.EXTRA_UID, uid);
5025        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5026        broadcastIntentLocked(null, null, intent,
5027                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5028                false, false,
5029                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5030    }
5031
5032    private void forceStopUserLocked(int userId, String reason) {
5033        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5034        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5035        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5036                | Intent.FLAG_RECEIVER_FOREGROUND);
5037        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5038        broadcastIntentLocked(null, null, intent,
5039                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5040                false, false,
5041                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5042    }
5043
5044    private final boolean killPackageProcessesLocked(String packageName, int appId,
5045            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5046            boolean doit, boolean evenPersistent, String reason) {
5047        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5048
5049        // Remove all processes this package may have touched: all with the
5050        // same UID (except for the system or root user), and all whose name
5051        // matches the package name.
5052        final int NP = mProcessNames.getMap().size();
5053        for (int ip=0; ip<NP; ip++) {
5054            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5055            final int NA = apps.size();
5056            for (int ia=0; ia<NA; ia++) {
5057                ProcessRecord app = apps.valueAt(ia);
5058                if (app.persistent && !evenPersistent) {
5059                    // we don't kill persistent processes
5060                    continue;
5061                }
5062                if (app.removed) {
5063                    if (doit) {
5064                        procs.add(app);
5065                    }
5066                    continue;
5067                }
5068
5069                // Skip process if it doesn't meet our oom adj requirement.
5070                if (app.setAdj < minOomAdj) {
5071                    continue;
5072                }
5073
5074                // If no package is specified, we call all processes under the
5075                // give user id.
5076                if (packageName == null) {
5077                    if (app.userId != userId) {
5078                        continue;
5079                    }
5080                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5081                        continue;
5082                    }
5083                // Package has been specified, we want to hit all processes
5084                // that match it.  We need to qualify this by the processes
5085                // that are running under the specified app and user ID.
5086                } else {
5087                    final boolean isDep = app.pkgDeps != null
5088                            && app.pkgDeps.contains(packageName);
5089                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5090                        continue;
5091                    }
5092                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5093                        continue;
5094                    }
5095                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5096                        continue;
5097                    }
5098                }
5099
5100                // Process has passed all conditions, kill it!
5101                if (!doit) {
5102                    return true;
5103                }
5104                app.removed = true;
5105                procs.add(app);
5106            }
5107        }
5108
5109        int N = procs.size();
5110        for (int i=0; i<N; i++) {
5111            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5112        }
5113        updateOomAdjLocked();
5114        return N > 0;
5115    }
5116
5117    private final boolean forceStopPackageLocked(String name, int appId,
5118            boolean callerWillRestart, boolean purgeCache, boolean doit,
5119            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5120        int i;
5121        int N;
5122
5123        if (userId == UserHandle.USER_ALL && name == null) {
5124            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5125        }
5126
5127        if (appId < 0 && name != null) {
5128            try {
5129                appId = UserHandle.getAppId(
5130                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5131            } catch (RemoteException e) {
5132            }
5133        }
5134
5135        if (doit) {
5136            if (name != null) {
5137                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5138                        + " user=" + userId + ": " + reason);
5139            } else {
5140                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5141            }
5142
5143            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5144            for (int ip=pmap.size()-1; ip>=0; ip--) {
5145                SparseArray<Long> ba = pmap.valueAt(ip);
5146                for (i=ba.size()-1; i>=0; i--) {
5147                    boolean remove = false;
5148                    final int entUid = ba.keyAt(i);
5149                    if (name != null) {
5150                        if (userId == UserHandle.USER_ALL) {
5151                            if (UserHandle.getAppId(entUid) == appId) {
5152                                remove = true;
5153                            }
5154                        } else {
5155                            if (entUid == UserHandle.getUid(userId, appId)) {
5156                                remove = true;
5157                            }
5158                        }
5159                    } else if (UserHandle.getUserId(entUid) == userId) {
5160                        remove = true;
5161                    }
5162                    if (remove) {
5163                        ba.removeAt(i);
5164                    }
5165                }
5166                if (ba.size() == 0) {
5167                    pmap.removeAt(ip);
5168                }
5169            }
5170        }
5171
5172        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5173                -100, callerWillRestart, true, doit, evenPersistent,
5174                name == null ? ("stop user " + userId) : ("stop " + name));
5175
5176        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5177            if (!doit) {
5178                return true;
5179            }
5180            didSomething = true;
5181        }
5182
5183        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5184            if (!doit) {
5185                return true;
5186            }
5187            didSomething = true;
5188        }
5189
5190        if (name == null) {
5191            // Remove all sticky broadcasts from this user.
5192            mStickyBroadcasts.remove(userId);
5193        }
5194
5195        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5196        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5197                userId, providers)) {
5198            if (!doit) {
5199                return true;
5200            }
5201            didSomething = true;
5202        }
5203        N = providers.size();
5204        for (i=0; i<N; i++) {
5205            removeDyingProviderLocked(null, providers.get(i), true);
5206        }
5207
5208        // Remove transient permissions granted from/to this package/user
5209        removeUriPermissionsForPackageLocked(name, userId, false);
5210
5211        if (name == null || uninstalling) {
5212            // Remove pending intents.  For now we only do this when force
5213            // stopping users, because we have some problems when doing this
5214            // for packages -- app widgets are not currently cleaned up for
5215            // such packages, so they can be left with bad pending intents.
5216            if (mIntentSenderRecords.size() > 0) {
5217                Iterator<WeakReference<PendingIntentRecord>> it
5218                        = mIntentSenderRecords.values().iterator();
5219                while (it.hasNext()) {
5220                    WeakReference<PendingIntentRecord> wpir = it.next();
5221                    if (wpir == null) {
5222                        it.remove();
5223                        continue;
5224                    }
5225                    PendingIntentRecord pir = wpir.get();
5226                    if (pir == null) {
5227                        it.remove();
5228                        continue;
5229                    }
5230                    if (name == null) {
5231                        // Stopping user, remove all objects for the user.
5232                        if (pir.key.userId != userId) {
5233                            // Not the same user, skip it.
5234                            continue;
5235                        }
5236                    } else {
5237                        if (UserHandle.getAppId(pir.uid) != appId) {
5238                            // Different app id, skip it.
5239                            continue;
5240                        }
5241                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5242                            // Different user, skip it.
5243                            continue;
5244                        }
5245                        if (!pir.key.packageName.equals(name)) {
5246                            // Different package, skip it.
5247                            continue;
5248                        }
5249                    }
5250                    if (!doit) {
5251                        return true;
5252                    }
5253                    didSomething = true;
5254                    it.remove();
5255                    pir.canceled = true;
5256                    if (pir.key.activity != null) {
5257                        pir.key.activity.pendingResults.remove(pir.ref);
5258                    }
5259                }
5260            }
5261        }
5262
5263        if (doit) {
5264            if (purgeCache && name != null) {
5265                AttributeCache ac = AttributeCache.instance();
5266                if (ac != null) {
5267                    ac.removePackage(name);
5268                }
5269            }
5270            if (mBooted) {
5271                mStackSupervisor.resumeTopActivitiesLocked();
5272                mStackSupervisor.scheduleIdleLocked();
5273            }
5274        }
5275
5276        return didSomething;
5277    }
5278
5279    private final boolean removeProcessLocked(ProcessRecord app,
5280            boolean callerWillRestart, boolean allowRestart, String reason) {
5281        final String name = app.processName;
5282        final int uid = app.uid;
5283        if (DEBUG_PROCESSES) Slog.d(
5284            TAG, "Force removing proc " + app.toShortString() + " (" + name
5285            + "/" + uid + ")");
5286
5287        mProcessNames.remove(name, uid);
5288        mIsolatedProcesses.remove(app.uid);
5289        if (mHeavyWeightProcess == app) {
5290            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5291                    mHeavyWeightProcess.userId, 0));
5292            mHeavyWeightProcess = null;
5293        }
5294        boolean needRestart = false;
5295        if (app.pid > 0 && app.pid != MY_PID) {
5296            int pid = app.pid;
5297            synchronized (mPidsSelfLocked) {
5298                mPidsSelfLocked.remove(pid);
5299                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5300            }
5301            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5302            if (app.isolated) {
5303                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5304            }
5305            killUnneededProcessLocked(app, reason);
5306            Process.killProcessGroup(app.info.uid, app.pid);
5307            handleAppDiedLocked(app, true, allowRestart);
5308            removeLruProcessLocked(app);
5309
5310            if (app.persistent && !app.isolated) {
5311                if (!callerWillRestart) {
5312                    addAppLocked(app.info, false, null /* ABI override */);
5313                } else {
5314                    needRestart = true;
5315                }
5316            }
5317        } else {
5318            mRemovedProcesses.add(app);
5319        }
5320
5321        return needRestart;
5322    }
5323
5324    private final void processStartTimedOutLocked(ProcessRecord app) {
5325        final int pid = app.pid;
5326        boolean gone = false;
5327        synchronized (mPidsSelfLocked) {
5328            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5329            if (knownApp != null && knownApp.thread == null) {
5330                mPidsSelfLocked.remove(pid);
5331                gone = true;
5332            }
5333        }
5334
5335        if (gone) {
5336            Slog.w(TAG, "Process " + app + " failed to attach");
5337            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5338                    pid, app.uid, app.processName);
5339            mProcessNames.remove(app.processName, app.uid);
5340            mIsolatedProcesses.remove(app.uid);
5341            if (mHeavyWeightProcess == app) {
5342                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5343                        mHeavyWeightProcess.userId, 0));
5344                mHeavyWeightProcess = null;
5345            }
5346            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5347            if (app.isolated) {
5348                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5349            }
5350            // Take care of any launching providers waiting for this process.
5351            checkAppInLaunchingProvidersLocked(app, true);
5352            // Take care of any services that are waiting for the process.
5353            mServices.processStartTimedOutLocked(app);
5354            killUnneededProcessLocked(app, "start timeout");
5355            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5356                Slog.w(TAG, "Unattached app died before backup, skipping");
5357                try {
5358                    IBackupManager bm = IBackupManager.Stub.asInterface(
5359                            ServiceManager.getService(Context.BACKUP_SERVICE));
5360                    bm.agentDisconnected(app.info.packageName);
5361                } catch (RemoteException e) {
5362                    // Can't happen; the backup manager is local
5363                }
5364            }
5365            if (isPendingBroadcastProcessLocked(pid)) {
5366                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5367                skipPendingBroadcastLocked(pid);
5368            }
5369        } else {
5370            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5371        }
5372    }
5373
5374    private final boolean attachApplicationLocked(IApplicationThread thread,
5375            int pid) {
5376
5377        // Find the application record that is being attached...  either via
5378        // the pid if we are running in multiple processes, or just pull the
5379        // next app record if we are emulating process with anonymous threads.
5380        ProcessRecord app;
5381        if (pid != MY_PID && pid >= 0) {
5382            synchronized (mPidsSelfLocked) {
5383                app = mPidsSelfLocked.get(pid);
5384            }
5385        } else {
5386            app = null;
5387        }
5388
5389        if (app == null) {
5390            Slog.w(TAG, "No pending application record for pid " + pid
5391                    + " (IApplicationThread " + thread + "); dropping process");
5392            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5393            if (pid > 0 && pid != MY_PID) {
5394                Process.killProcessQuiet(pid);
5395                //TODO: Process.killProcessGroup(app.info.uid, pid);
5396            } else {
5397                try {
5398                    thread.scheduleExit();
5399                } catch (Exception e) {
5400                    // Ignore exceptions.
5401                }
5402            }
5403            return false;
5404        }
5405
5406        // If this application record is still attached to a previous
5407        // process, clean it up now.
5408        if (app.thread != null) {
5409            handleAppDiedLocked(app, true, true);
5410        }
5411
5412        // Tell the process all about itself.
5413
5414        if (localLOGV) Slog.v(
5415                TAG, "Binding process pid " + pid + " to record " + app);
5416
5417        final String processName = app.processName;
5418        try {
5419            AppDeathRecipient adr = new AppDeathRecipient(
5420                    app, pid, thread);
5421            thread.asBinder().linkToDeath(adr, 0);
5422            app.deathRecipient = adr;
5423        } catch (RemoteException e) {
5424            app.resetPackageList(mProcessStats);
5425            startProcessLocked(app, "link fail", processName);
5426            return false;
5427        }
5428
5429        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5430
5431        app.makeActive(thread, mProcessStats);
5432        app.curAdj = app.setAdj = -100;
5433        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5434        app.forcingToForeground = null;
5435        updateProcessForegroundLocked(app, false, false);
5436        app.hasShownUi = false;
5437        app.debugging = false;
5438        app.cached = false;
5439
5440        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5441
5442        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5443        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5444
5445        if (!normalMode) {
5446            Slog.i(TAG, "Launching preboot mode app: " + app);
5447        }
5448
5449        if (localLOGV) Slog.v(
5450            TAG, "New app record " + app
5451            + " thread=" + thread.asBinder() + " pid=" + pid);
5452        try {
5453            int testMode = IApplicationThread.DEBUG_OFF;
5454            if (mDebugApp != null && mDebugApp.equals(processName)) {
5455                testMode = mWaitForDebugger
5456                    ? IApplicationThread.DEBUG_WAIT
5457                    : IApplicationThread.DEBUG_ON;
5458                app.debugging = true;
5459                if (mDebugTransient) {
5460                    mDebugApp = mOrigDebugApp;
5461                    mWaitForDebugger = mOrigWaitForDebugger;
5462                }
5463            }
5464            String profileFile = app.instrumentationProfileFile;
5465            ParcelFileDescriptor profileFd = null;
5466            boolean profileAutoStop = false;
5467            if (mProfileApp != null && mProfileApp.equals(processName)) {
5468                mProfileProc = app;
5469                profileFile = mProfileFile;
5470                profileFd = mProfileFd;
5471                profileAutoStop = mAutoStopProfiler;
5472            }
5473            boolean enableOpenGlTrace = false;
5474            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5475                enableOpenGlTrace = true;
5476                mOpenGlTraceApp = null;
5477            }
5478
5479            // If the app is being launched for restore or full backup, set it up specially
5480            boolean isRestrictedBackupMode = false;
5481            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5482                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5483                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5484                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5485            }
5486
5487            ensurePackageDexOpt(app.instrumentationInfo != null
5488                    ? app.instrumentationInfo.packageName
5489                    : app.info.packageName);
5490            if (app.instrumentationClass != null) {
5491                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5492            }
5493            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5494                    + processName + " with config " + mConfiguration);
5495            ApplicationInfo appInfo = app.instrumentationInfo != null
5496                    ? app.instrumentationInfo : app.info;
5497            app.compat = compatibilityInfoForPackageLocked(appInfo);
5498            if (profileFd != null) {
5499                profileFd = profileFd.dup();
5500            }
5501            thread.bindApplication(processName, appInfo, providers,
5502                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5503                    app.instrumentationArguments, app.instrumentationWatcher,
5504                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5505                    isRestrictedBackupMode || !normalMode, app.persistent,
5506                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5507                    mCoreSettingsObserver.getCoreSettingsLocked());
5508            updateLruProcessLocked(app, false, null);
5509            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5510        } catch (Exception e) {
5511            // todo: Yikes!  What should we do?  For now we will try to
5512            // start another process, but that could easily get us in
5513            // an infinite loop of restarting processes...
5514            Slog.w(TAG, "Exception thrown during bind!", e);
5515
5516            app.resetPackageList(mProcessStats);
5517            app.unlinkDeathRecipient();
5518            startProcessLocked(app, "bind fail", processName);
5519            return false;
5520        }
5521
5522        // Remove this record from the list of starting applications.
5523        mPersistentStartingProcesses.remove(app);
5524        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5525                "Attach application locked removing on hold: " + app);
5526        mProcessesOnHold.remove(app);
5527
5528        boolean badApp = false;
5529        boolean didSomething = false;
5530
5531        // See if the top visible activity is waiting to run in this process...
5532        if (normalMode) {
5533            try {
5534                if (mStackSupervisor.attachApplicationLocked(app)) {
5535                    didSomething = true;
5536                }
5537            } catch (Exception e) {
5538                badApp = true;
5539            }
5540        }
5541
5542        // Find any services that should be running in this process...
5543        if (!badApp) {
5544            try {
5545                didSomething |= mServices.attachApplicationLocked(app, processName);
5546            } catch (Exception e) {
5547                badApp = true;
5548            }
5549        }
5550
5551        // Check if a next-broadcast receiver is in this process...
5552        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5553            try {
5554                didSomething |= sendPendingBroadcastsLocked(app);
5555            } catch (Exception e) {
5556                // If the app died trying to launch the receiver we declare it 'bad'
5557                badApp = true;
5558            }
5559        }
5560
5561        // Check whether the next backup agent is in this process...
5562        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5563            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5564            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5565            try {
5566                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5567                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5568                        mBackupTarget.backupMode);
5569            } catch (Exception e) {
5570                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5571                e.printStackTrace();
5572            }
5573        }
5574
5575        if (badApp) {
5576            // todo: Also need to kill application to deal with all
5577            // kinds of exceptions.
5578            handleAppDiedLocked(app, false, true);
5579            return false;
5580        }
5581
5582        if (!didSomething) {
5583            updateOomAdjLocked();
5584        }
5585
5586        return true;
5587    }
5588
5589    @Override
5590    public final void attachApplication(IApplicationThread thread) {
5591        synchronized (this) {
5592            int callingPid = Binder.getCallingPid();
5593            final long origId = Binder.clearCallingIdentity();
5594            attachApplicationLocked(thread, callingPid);
5595            Binder.restoreCallingIdentity(origId);
5596        }
5597    }
5598
5599    @Override
5600    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5601        final long origId = Binder.clearCallingIdentity();
5602        synchronized (this) {
5603            ActivityStack stack = ActivityRecord.getStackLocked(token);
5604            if (stack != null) {
5605                ActivityRecord r =
5606                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5607                if (stopProfiling) {
5608                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5609                        try {
5610                            mProfileFd.close();
5611                        } catch (IOException e) {
5612                        }
5613                        clearProfilerLocked();
5614                    }
5615                }
5616            }
5617        }
5618        Binder.restoreCallingIdentity(origId);
5619    }
5620
5621    void postEnableScreenAfterBootLocked() {
5622        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
5623    }
5624
5625    void enableScreenAfterBoot() {
5626        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5627                SystemClock.uptimeMillis());
5628        mWindowManager.enableScreenAfterBoot();
5629
5630        synchronized (this) {
5631            updateEventDispatchingLocked();
5632        }
5633    }
5634
5635    @Override
5636    public void showBootMessage(final CharSequence msg, final boolean always) {
5637        enforceNotIsolatedCaller("showBootMessage");
5638        mWindowManager.showBootMessage(msg, always);
5639    }
5640
5641    @Override
5642    public void dismissKeyguardOnNextActivity() {
5643        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5644        final long token = Binder.clearCallingIdentity();
5645        try {
5646            synchronized (this) {
5647                if (DEBUG_LOCKSCREEN) logLockScreen("");
5648                if (mLockScreenShown) {
5649                    mLockScreenShown = false;
5650                    comeOutOfSleepIfNeededLocked();
5651                }
5652                mStackSupervisor.setDismissKeyguard(true);
5653            }
5654        } finally {
5655            Binder.restoreCallingIdentity(token);
5656        }
5657    }
5658
5659    final void finishBooting() {
5660        // Register receivers to handle package update events
5661        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5662
5663        // Let system services know.
5664        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
5665
5666        synchronized (this) {
5667            // Ensure that any processes we had put on hold are now started
5668            // up.
5669            final int NP = mProcessesOnHold.size();
5670            if (NP > 0) {
5671                ArrayList<ProcessRecord> procs =
5672                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5673                for (int ip=0; ip<NP; ip++) {
5674                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5675                            + procs.get(ip));
5676                    startProcessLocked(procs.get(ip), "on-hold", null);
5677                }
5678            }
5679
5680            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5681                // Start looking for apps that are abusing wake locks.
5682                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5683                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5684                // Tell anyone interested that we are done booting!
5685                SystemProperties.set("sys.boot_completed", "1");
5686                SystemProperties.set("dev.bootcomplete", "1");
5687                for (int i=0; i<mStartedUsers.size(); i++) {
5688                    UserStartedState uss = mStartedUsers.valueAt(i);
5689                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5690                        uss.mState = UserStartedState.STATE_RUNNING;
5691                        final int userId = mStartedUsers.keyAt(i);
5692                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5693                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5694                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5695                        broadcastIntentLocked(null, null, intent, null,
5696                                new IIntentReceiver.Stub() {
5697                                    @Override
5698                                    public void performReceive(Intent intent, int resultCode,
5699                                            String data, Bundle extras, boolean ordered,
5700                                            boolean sticky, int sendingUser) {
5701                                        synchronized (ActivityManagerService.this) {
5702                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5703                                                    true, false);
5704                                        }
5705                                    }
5706                                },
5707                                0, null, null,
5708                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5709                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5710                                userId);
5711                    }
5712                }
5713                scheduleStartProfilesLocked();
5714            }
5715        }
5716    }
5717
5718    final void ensureBootCompleted() {
5719        boolean booting;
5720        boolean enableScreen;
5721        synchronized (this) {
5722            booting = mBooting;
5723            mBooting = false;
5724            enableScreen = !mBooted;
5725            mBooted = true;
5726        }
5727
5728        if (booting) {
5729            finishBooting();
5730        }
5731
5732        if (enableScreen) {
5733            enableScreenAfterBoot();
5734        }
5735    }
5736
5737    @Override
5738    public final void activityResumed(IBinder token) {
5739        final long origId = Binder.clearCallingIdentity();
5740        synchronized(this) {
5741            ActivityStack stack = ActivityRecord.getStackLocked(token);
5742            if (stack != null) {
5743                ActivityRecord.activityResumedLocked(token);
5744            }
5745        }
5746        Binder.restoreCallingIdentity(origId);
5747    }
5748
5749    @Override
5750    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5751        final long origId = Binder.clearCallingIdentity();
5752        synchronized(this) {
5753            ActivityStack stack = ActivityRecord.getStackLocked(token);
5754            if (stack != null) {
5755                stack.activityPausedLocked(token, false, persistentState);
5756            }
5757        }
5758        Binder.restoreCallingIdentity(origId);
5759    }
5760
5761    @Override
5762    public final void activityStopped(IBinder token, Bundle icicle,
5763            PersistableBundle persistentState, CharSequence description) {
5764        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5765
5766        // Refuse possible leaked file descriptors
5767        if (icicle != null && icicle.hasFileDescriptors()) {
5768            throw new IllegalArgumentException("File descriptors passed in Bundle");
5769        }
5770
5771        final long origId = Binder.clearCallingIdentity();
5772
5773        synchronized (this) {
5774            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5775            if (r != null) {
5776                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5777            }
5778        }
5779
5780        trimApplications();
5781
5782        Binder.restoreCallingIdentity(origId);
5783    }
5784
5785    @Override
5786    public final void activityDestroyed(IBinder token) {
5787        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5788        synchronized (this) {
5789            ActivityStack stack = ActivityRecord.getStackLocked(token);
5790            if (stack != null) {
5791                stack.activityDestroyedLocked(token);
5792            }
5793        }
5794    }
5795
5796    @Override
5797    public final void mediaResourcesReleased(IBinder token) {
5798        final long origId = Binder.clearCallingIdentity();
5799        try {
5800            synchronized (this) {
5801                ActivityStack stack = ActivityRecord.getStackLocked(token);
5802                if (stack != null) {
5803                    stack.mediaResourcesReleased(token);
5804                }
5805            }
5806        } finally {
5807            Binder.restoreCallingIdentity(origId);
5808        }
5809    }
5810
5811    @Override
5812    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5813        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5814    }
5815
5816    @Override
5817    public final void notifyEnterAnimationComplete(IBinder token) {
5818        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5819    }
5820
5821    @Override
5822    public String getCallingPackage(IBinder token) {
5823        synchronized (this) {
5824            ActivityRecord r = getCallingRecordLocked(token);
5825            return r != null ? r.info.packageName : null;
5826        }
5827    }
5828
5829    @Override
5830    public ComponentName getCallingActivity(IBinder token) {
5831        synchronized (this) {
5832            ActivityRecord r = getCallingRecordLocked(token);
5833            return r != null ? r.intent.getComponent() : null;
5834        }
5835    }
5836
5837    private ActivityRecord getCallingRecordLocked(IBinder token) {
5838        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5839        if (r == null) {
5840            return null;
5841        }
5842        return r.resultTo;
5843    }
5844
5845    @Override
5846    public ComponentName getActivityClassForToken(IBinder token) {
5847        synchronized(this) {
5848            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5849            if (r == null) {
5850                return null;
5851            }
5852            return r.intent.getComponent();
5853        }
5854    }
5855
5856    @Override
5857    public String getPackageForToken(IBinder token) {
5858        synchronized(this) {
5859            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5860            if (r == null) {
5861                return null;
5862            }
5863            return r.packageName;
5864        }
5865    }
5866
5867    @Override
5868    public IIntentSender getIntentSender(int type,
5869            String packageName, IBinder token, String resultWho,
5870            int requestCode, Intent[] intents, String[] resolvedTypes,
5871            int flags, Bundle options, int userId) {
5872        enforceNotIsolatedCaller("getIntentSender");
5873        // Refuse possible leaked file descriptors
5874        if (intents != null) {
5875            if (intents.length < 1) {
5876                throw new IllegalArgumentException("Intents array length must be >= 1");
5877            }
5878            for (int i=0; i<intents.length; i++) {
5879                Intent intent = intents[i];
5880                if (intent != null) {
5881                    if (intent.hasFileDescriptors()) {
5882                        throw new IllegalArgumentException("File descriptors passed in Intent");
5883                    }
5884                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5885                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5886                        throw new IllegalArgumentException(
5887                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5888                    }
5889                    intents[i] = new Intent(intent);
5890                }
5891            }
5892            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5893                throw new IllegalArgumentException(
5894                        "Intent array length does not match resolvedTypes length");
5895            }
5896        }
5897        if (options != null) {
5898            if (options.hasFileDescriptors()) {
5899                throw new IllegalArgumentException("File descriptors passed in options");
5900            }
5901        }
5902
5903        synchronized(this) {
5904            int callingUid = Binder.getCallingUid();
5905            int origUserId = userId;
5906            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5907                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5908                    ALLOW_NON_FULL, "getIntentSender", null);
5909            if (origUserId == UserHandle.USER_CURRENT) {
5910                // We don't want to evaluate this until the pending intent is
5911                // actually executed.  However, we do want to always do the
5912                // security checking for it above.
5913                userId = UserHandle.USER_CURRENT;
5914            }
5915            try {
5916                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5917                    int uid = AppGlobals.getPackageManager()
5918                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5919                    if (!UserHandle.isSameApp(callingUid, uid)) {
5920                        String msg = "Permission Denial: getIntentSender() from pid="
5921                            + Binder.getCallingPid()
5922                            + ", uid=" + Binder.getCallingUid()
5923                            + ", (need uid=" + uid + ")"
5924                            + " is not allowed to send as package " + packageName;
5925                        Slog.w(TAG, msg);
5926                        throw new SecurityException(msg);
5927                    }
5928                }
5929
5930                return getIntentSenderLocked(type, packageName, callingUid, userId,
5931                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5932
5933            } catch (RemoteException e) {
5934                throw new SecurityException(e);
5935            }
5936        }
5937    }
5938
5939    IIntentSender getIntentSenderLocked(int type, String packageName,
5940            int callingUid, int userId, IBinder token, String resultWho,
5941            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5942            Bundle options) {
5943        if (DEBUG_MU)
5944            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5945        ActivityRecord activity = null;
5946        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5947            activity = ActivityRecord.isInStackLocked(token);
5948            if (activity == null) {
5949                return null;
5950            }
5951            if (activity.finishing) {
5952                return null;
5953            }
5954        }
5955
5956        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5957        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5958        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5959        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5960                |PendingIntent.FLAG_UPDATE_CURRENT);
5961
5962        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5963                type, packageName, activity, resultWho,
5964                requestCode, intents, resolvedTypes, flags, options, userId);
5965        WeakReference<PendingIntentRecord> ref;
5966        ref = mIntentSenderRecords.get(key);
5967        PendingIntentRecord rec = ref != null ? ref.get() : null;
5968        if (rec != null) {
5969            if (!cancelCurrent) {
5970                if (updateCurrent) {
5971                    if (rec.key.requestIntent != null) {
5972                        rec.key.requestIntent.replaceExtras(intents != null ?
5973                                intents[intents.length - 1] : null);
5974                    }
5975                    if (intents != null) {
5976                        intents[intents.length-1] = rec.key.requestIntent;
5977                        rec.key.allIntents = intents;
5978                        rec.key.allResolvedTypes = resolvedTypes;
5979                    } else {
5980                        rec.key.allIntents = null;
5981                        rec.key.allResolvedTypes = null;
5982                    }
5983                }
5984                return rec;
5985            }
5986            rec.canceled = true;
5987            mIntentSenderRecords.remove(key);
5988        }
5989        if (noCreate) {
5990            return rec;
5991        }
5992        rec = new PendingIntentRecord(this, key, callingUid);
5993        mIntentSenderRecords.put(key, rec.ref);
5994        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5995            if (activity.pendingResults == null) {
5996                activity.pendingResults
5997                        = new HashSet<WeakReference<PendingIntentRecord>>();
5998            }
5999            activity.pendingResults.add(rec.ref);
6000        }
6001        return rec;
6002    }
6003
6004    @Override
6005    public void cancelIntentSender(IIntentSender sender) {
6006        if (!(sender instanceof PendingIntentRecord)) {
6007            return;
6008        }
6009        synchronized(this) {
6010            PendingIntentRecord rec = (PendingIntentRecord)sender;
6011            try {
6012                int uid = AppGlobals.getPackageManager()
6013                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6014                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6015                    String msg = "Permission Denial: cancelIntentSender() from pid="
6016                        + Binder.getCallingPid()
6017                        + ", uid=" + Binder.getCallingUid()
6018                        + " is not allowed to cancel packges "
6019                        + rec.key.packageName;
6020                    Slog.w(TAG, msg);
6021                    throw new SecurityException(msg);
6022                }
6023            } catch (RemoteException e) {
6024                throw new SecurityException(e);
6025            }
6026            cancelIntentSenderLocked(rec, true);
6027        }
6028    }
6029
6030    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6031        rec.canceled = true;
6032        mIntentSenderRecords.remove(rec.key);
6033        if (cleanActivity && rec.key.activity != null) {
6034            rec.key.activity.pendingResults.remove(rec.ref);
6035        }
6036    }
6037
6038    @Override
6039    public String getPackageForIntentSender(IIntentSender pendingResult) {
6040        if (!(pendingResult instanceof PendingIntentRecord)) {
6041            return null;
6042        }
6043        try {
6044            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6045            return res.key.packageName;
6046        } catch (ClassCastException e) {
6047        }
6048        return null;
6049    }
6050
6051    @Override
6052    public int getUidForIntentSender(IIntentSender sender) {
6053        if (sender instanceof PendingIntentRecord) {
6054            try {
6055                PendingIntentRecord res = (PendingIntentRecord)sender;
6056                return res.uid;
6057            } catch (ClassCastException e) {
6058            }
6059        }
6060        return -1;
6061    }
6062
6063    @Override
6064    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6065        if (!(pendingResult instanceof PendingIntentRecord)) {
6066            return false;
6067        }
6068        try {
6069            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6070            if (res.key.allIntents == null) {
6071                return false;
6072            }
6073            for (int i=0; i<res.key.allIntents.length; i++) {
6074                Intent intent = res.key.allIntents[i];
6075                if (intent.getPackage() != null && intent.getComponent() != null) {
6076                    return false;
6077                }
6078            }
6079            return true;
6080        } catch (ClassCastException e) {
6081        }
6082        return false;
6083    }
6084
6085    @Override
6086    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6087        if (!(pendingResult instanceof PendingIntentRecord)) {
6088            return false;
6089        }
6090        try {
6091            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6092            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6093                return true;
6094            }
6095            return false;
6096        } catch (ClassCastException e) {
6097        }
6098        return false;
6099    }
6100
6101    @Override
6102    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6103        if (!(pendingResult instanceof PendingIntentRecord)) {
6104            return null;
6105        }
6106        try {
6107            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6108            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6109        } catch (ClassCastException e) {
6110        }
6111        return null;
6112    }
6113
6114    @Override
6115    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6116        if (!(pendingResult instanceof PendingIntentRecord)) {
6117            return null;
6118        }
6119        try {
6120            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6121            Intent intent = res.key.requestIntent;
6122            if (intent != null) {
6123                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6124                        || res.lastTagPrefix.equals(prefix))) {
6125                    return res.lastTag;
6126                }
6127                res.lastTagPrefix = prefix;
6128                StringBuilder sb = new StringBuilder(128);
6129                if (prefix != null) {
6130                    sb.append(prefix);
6131                }
6132                if (intent.getAction() != null) {
6133                    sb.append(intent.getAction());
6134                } else if (intent.getComponent() != null) {
6135                    intent.getComponent().appendShortString(sb);
6136                } else {
6137                    sb.append("?");
6138                }
6139                return res.lastTag = sb.toString();
6140            }
6141        } catch (ClassCastException e) {
6142        }
6143        return null;
6144    }
6145
6146    @Override
6147    public void setProcessLimit(int max) {
6148        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6149                "setProcessLimit()");
6150        synchronized (this) {
6151            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6152            mProcessLimitOverride = max;
6153        }
6154        trimApplications();
6155    }
6156
6157    @Override
6158    public int getProcessLimit() {
6159        synchronized (this) {
6160            return mProcessLimitOverride;
6161        }
6162    }
6163
6164    void foregroundTokenDied(ForegroundToken token) {
6165        synchronized (ActivityManagerService.this) {
6166            synchronized (mPidsSelfLocked) {
6167                ForegroundToken cur
6168                    = mForegroundProcesses.get(token.pid);
6169                if (cur != token) {
6170                    return;
6171                }
6172                mForegroundProcesses.remove(token.pid);
6173                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6174                if (pr == null) {
6175                    return;
6176                }
6177                pr.forcingToForeground = null;
6178                updateProcessForegroundLocked(pr, false, false);
6179            }
6180            updateOomAdjLocked();
6181        }
6182    }
6183
6184    @Override
6185    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6186        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6187                "setProcessForeground()");
6188        synchronized(this) {
6189            boolean changed = false;
6190
6191            synchronized (mPidsSelfLocked) {
6192                ProcessRecord pr = mPidsSelfLocked.get(pid);
6193                if (pr == null && isForeground) {
6194                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6195                    return;
6196                }
6197                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6198                if (oldToken != null) {
6199                    oldToken.token.unlinkToDeath(oldToken, 0);
6200                    mForegroundProcesses.remove(pid);
6201                    if (pr != null) {
6202                        pr.forcingToForeground = null;
6203                    }
6204                    changed = true;
6205                }
6206                if (isForeground && token != null) {
6207                    ForegroundToken newToken = new ForegroundToken() {
6208                        @Override
6209                        public void binderDied() {
6210                            foregroundTokenDied(this);
6211                        }
6212                    };
6213                    newToken.pid = pid;
6214                    newToken.token = token;
6215                    try {
6216                        token.linkToDeath(newToken, 0);
6217                        mForegroundProcesses.put(pid, newToken);
6218                        pr.forcingToForeground = token;
6219                        changed = true;
6220                    } catch (RemoteException e) {
6221                        // If the process died while doing this, we will later
6222                        // do the cleanup with the process death link.
6223                    }
6224                }
6225            }
6226
6227            if (changed) {
6228                updateOomAdjLocked();
6229            }
6230        }
6231    }
6232
6233    // =========================================================
6234    // PERMISSIONS
6235    // =========================================================
6236
6237    static class PermissionController extends IPermissionController.Stub {
6238        ActivityManagerService mActivityManagerService;
6239        PermissionController(ActivityManagerService activityManagerService) {
6240            mActivityManagerService = activityManagerService;
6241        }
6242
6243        @Override
6244        public boolean checkPermission(String permission, int pid, int uid) {
6245            return mActivityManagerService.checkPermission(permission, pid,
6246                    uid) == PackageManager.PERMISSION_GRANTED;
6247        }
6248    }
6249
6250    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6251        @Override
6252        public int checkComponentPermission(String permission, int pid, int uid,
6253                int owningUid, boolean exported) {
6254            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6255                    owningUid, exported);
6256        }
6257
6258        @Override
6259        public Object getAMSLock() {
6260            return ActivityManagerService.this;
6261        }
6262    }
6263
6264    /**
6265     * This can be called with or without the global lock held.
6266     */
6267    int checkComponentPermission(String permission, int pid, int uid,
6268            int owningUid, boolean exported) {
6269        // We might be performing an operation on behalf of an indirect binder
6270        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6271        // client identity accordingly before proceeding.
6272        Identity tlsIdentity = sCallerIdentity.get();
6273        if (tlsIdentity != null) {
6274            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6275                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6276            uid = tlsIdentity.uid;
6277            pid = tlsIdentity.pid;
6278        }
6279
6280        if (pid == MY_PID) {
6281            return PackageManager.PERMISSION_GRANTED;
6282        }
6283
6284        return ActivityManager.checkComponentPermission(permission, uid,
6285                owningUid, exported);
6286    }
6287
6288    /**
6289     * As the only public entry point for permissions checking, this method
6290     * can enforce the semantic that requesting a check on a null global
6291     * permission is automatically denied.  (Internally a null permission
6292     * string is used when calling {@link #checkComponentPermission} in cases
6293     * when only uid-based security is needed.)
6294     *
6295     * This can be called with or without the global lock held.
6296     */
6297    @Override
6298    public int checkPermission(String permission, int pid, int uid) {
6299        if (permission == null) {
6300            return PackageManager.PERMISSION_DENIED;
6301        }
6302        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6303    }
6304
6305    /**
6306     * Binder IPC calls go through the public entry point.
6307     * This can be called with or without the global lock held.
6308     */
6309    int checkCallingPermission(String permission) {
6310        return checkPermission(permission,
6311                Binder.getCallingPid(),
6312                UserHandle.getAppId(Binder.getCallingUid()));
6313    }
6314
6315    /**
6316     * This can be called with or without the global lock held.
6317     */
6318    void enforceCallingPermission(String permission, String func) {
6319        if (checkCallingPermission(permission)
6320                == PackageManager.PERMISSION_GRANTED) {
6321            return;
6322        }
6323
6324        String msg = "Permission Denial: " + func + " from pid="
6325                + Binder.getCallingPid()
6326                + ", uid=" + Binder.getCallingUid()
6327                + " requires " + permission;
6328        Slog.w(TAG, msg);
6329        throw new SecurityException(msg);
6330    }
6331
6332    /**
6333     * Determine if UID is holding permissions required to access {@link Uri} in
6334     * the given {@link ProviderInfo}. Final permission checking is always done
6335     * in {@link ContentProvider}.
6336     */
6337    private final boolean checkHoldingPermissionsLocked(
6338            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6339        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6340                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6341        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6342            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6343                    != PERMISSION_GRANTED) {
6344                return false;
6345            }
6346        }
6347        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6348    }
6349
6350    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6351            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6352        if (pi.applicationInfo.uid == uid) {
6353            return true;
6354        } else if (!pi.exported) {
6355            return false;
6356        }
6357
6358        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6359        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6360        try {
6361            // check if target holds top-level <provider> permissions
6362            if (!readMet && pi.readPermission != null && considerUidPermissions
6363                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6364                readMet = true;
6365            }
6366            if (!writeMet && pi.writePermission != null && considerUidPermissions
6367                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6368                writeMet = true;
6369            }
6370
6371            // track if unprotected read/write is allowed; any denied
6372            // <path-permission> below removes this ability
6373            boolean allowDefaultRead = pi.readPermission == null;
6374            boolean allowDefaultWrite = pi.writePermission == null;
6375
6376            // check if target holds any <path-permission> that match uri
6377            final PathPermission[] pps = pi.pathPermissions;
6378            if (pps != null) {
6379                final String path = grantUri.uri.getPath();
6380                int i = pps.length;
6381                while (i > 0 && (!readMet || !writeMet)) {
6382                    i--;
6383                    PathPermission pp = pps[i];
6384                    if (pp.match(path)) {
6385                        if (!readMet) {
6386                            final String pprperm = pp.getReadPermission();
6387                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6388                                    + pprperm + " for " + pp.getPath()
6389                                    + ": match=" + pp.match(path)
6390                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6391                            if (pprperm != null) {
6392                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6393                                        == PERMISSION_GRANTED) {
6394                                    readMet = true;
6395                                } else {
6396                                    allowDefaultRead = false;
6397                                }
6398                            }
6399                        }
6400                        if (!writeMet) {
6401                            final String ppwperm = pp.getWritePermission();
6402                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6403                                    + ppwperm + " for " + pp.getPath()
6404                                    + ": match=" + pp.match(path)
6405                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6406                            if (ppwperm != null) {
6407                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6408                                        == PERMISSION_GRANTED) {
6409                                    writeMet = true;
6410                                } else {
6411                                    allowDefaultWrite = false;
6412                                }
6413                            }
6414                        }
6415                    }
6416                }
6417            }
6418
6419            // grant unprotected <provider> read/write, if not blocked by
6420            // <path-permission> above
6421            if (allowDefaultRead) readMet = true;
6422            if (allowDefaultWrite) writeMet = true;
6423
6424        } catch (RemoteException e) {
6425            return false;
6426        }
6427
6428        return readMet && writeMet;
6429    }
6430
6431    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6432        ProviderInfo pi = null;
6433        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6434        if (cpr != null) {
6435            pi = cpr.info;
6436        } else {
6437            try {
6438                pi = AppGlobals.getPackageManager().resolveContentProvider(
6439                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6440            } catch (RemoteException ex) {
6441            }
6442        }
6443        return pi;
6444    }
6445
6446    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6447        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6448        if (targetUris != null) {
6449            return targetUris.get(grantUri);
6450        }
6451        return null;
6452    }
6453
6454    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6455            String targetPkg, int targetUid, GrantUri grantUri) {
6456        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6457        if (targetUris == null) {
6458            targetUris = Maps.newArrayMap();
6459            mGrantedUriPermissions.put(targetUid, targetUris);
6460        }
6461
6462        UriPermission perm = targetUris.get(grantUri);
6463        if (perm == null) {
6464            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6465            targetUris.put(grantUri, perm);
6466        }
6467
6468        return perm;
6469    }
6470
6471    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6472            final int modeFlags) {
6473        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6474        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6475                : UriPermission.STRENGTH_OWNED;
6476
6477        // Root gets to do everything.
6478        if (uid == 0) {
6479            return true;
6480        }
6481
6482        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6483        if (perms == null) return false;
6484
6485        // First look for exact match
6486        final UriPermission exactPerm = perms.get(grantUri);
6487        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6488            return true;
6489        }
6490
6491        // No exact match, look for prefixes
6492        final int N = perms.size();
6493        for (int i = 0; i < N; i++) {
6494            final UriPermission perm = perms.valueAt(i);
6495            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6496                    && perm.getStrength(modeFlags) >= minStrength) {
6497                return true;
6498            }
6499        }
6500
6501        return false;
6502    }
6503
6504    @Override
6505    public int checkUriPermission(Uri uri, int pid, int uid,
6506            final int modeFlags, int userId) {
6507        enforceNotIsolatedCaller("checkUriPermission");
6508
6509        // Another redirected-binder-call permissions check as in
6510        // {@link checkComponentPermission}.
6511        Identity tlsIdentity = sCallerIdentity.get();
6512        if (tlsIdentity != null) {
6513            uid = tlsIdentity.uid;
6514            pid = tlsIdentity.pid;
6515        }
6516
6517        // Our own process gets to do everything.
6518        if (pid == MY_PID) {
6519            return PackageManager.PERMISSION_GRANTED;
6520        }
6521        synchronized (this) {
6522            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6523                    ? PackageManager.PERMISSION_GRANTED
6524                    : PackageManager.PERMISSION_DENIED;
6525        }
6526    }
6527
6528    /**
6529     * Check if the targetPkg can be granted permission to access uri by
6530     * the callingUid using the given modeFlags.  Throws a security exception
6531     * if callingUid is not allowed to do this.  Returns the uid of the target
6532     * if the URI permission grant should be performed; returns -1 if it is not
6533     * needed (for example targetPkg already has permission to access the URI).
6534     * If you already know the uid of the target, you can supply it in
6535     * lastTargetUid else set that to -1.
6536     */
6537    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6538            final int modeFlags, int lastTargetUid) {
6539        if (!Intent.isAccessUriMode(modeFlags)) {
6540            return -1;
6541        }
6542
6543        if (targetPkg != null) {
6544            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6545                    "Checking grant " + targetPkg + " permission to " + grantUri);
6546        }
6547
6548        final IPackageManager pm = AppGlobals.getPackageManager();
6549
6550        // If this is not a content: uri, we can't do anything with it.
6551        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6552            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6553                    "Can't grant URI permission for non-content URI: " + grantUri);
6554            return -1;
6555        }
6556
6557        final String authority = grantUri.uri.getAuthority();
6558        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6559        if (pi == null) {
6560            Slog.w(TAG, "No content provider found for permission check: " +
6561                    grantUri.uri.toSafeString());
6562            return -1;
6563        }
6564
6565        int targetUid = lastTargetUid;
6566        if (targetUid < 0 && targetPkg != null) {
6567            try {
6568                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6569                if (targetUid < 0) {
6570                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6571                            "Can't grant URI permission no uid for: " + targetPkg);
6572                    return -1;
6573                }
6574            } catch (RemoteException ex) {
6575                return -1;
6576            }
6577        }
6578
6579        if (targetUid >= 0) {
6580            // First...  does the target actually need this permission?
6581            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6582                // No need to grant the target this permission.
6583                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6584                        "Target " + targetPkg + " already has full permission to " + grantUri);
6585                return -1;
6586            }
6587        } else {
6588            // First...  there is no target package, so can anyone access it?
6589            boolean allowed = pi.exported;
6590            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6591                if (pi.readPermission != null) {
6592                    allowed = false;
6593                }
6594            }
6595            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6596                if (pi.writePermission != null) {
6597                    allowed = false;
6598                }
6599            }
6600            if (allowed) {
6601                return -1;
6602            }
6603        }
6604
6605        /* There is a special cross user grant if:
6606         * - The target is on another user.
6607         * - Apps on the current user can access the uri without any uid permissions.
6608         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6609         * grant uri permissions.
6610         */
6611        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6612                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6613                modeFlags, false /*without considering the uid permissions*/);
6614
6615        // Second...  is the provider allowing granting of URI permissions?
6616        if (!specialCrossUserGrant) {
6617            if (!pi.grantUriPermissions) {
6618                throw new SecurityException("Provider " + pi.packageName
6619                        + "/" + pi.name
6620                        + " does not allow granting of Uri permissions (uri "
6621                        + grantUri + ")");
6622            }
6623            if (pi.uriPermissionPatterns != null) {
6624                final int N = pi.uriPermissionPatterns.length;
6625                boolean allowed = false;
6626                for (int i=0; i<N; i++) {
6627                    if (pi.uriPermissionPatterns[i] != null
6628                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6629                        allowed = true;
6630                        break;
6631                    }
6632                }
6633                if (!allowed) {
6634                    throw new SecurityException("Provider " + pi.packageName
6635                            + "/" + pi.name
6636                            + " does not allow granting of permission to path of Uri "
6637                            + grantUri);
6638                }
6639            }
6640        }
6641
6642        // Third...  does the caller itself have permission to access
6643        // this uri?
6644        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6645            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6646                // Require they hold a strong enough Uri permission
6647                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6648                    throw new SecurityException("Uid " + callingUid
6649                            + " does not have permission to uri " + grantUri);
6650                }
6651            }
6652        }
6653        return targetUid;
6654    }
6655
6656    @Override
6657    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6658            final int modeFlags, int userId) {
6659        enforceNotIsolatedCaller("checkGrantUriPermission");
6660        synchronized(this) {
6661            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6662                    new GrantUri(userId, uri, false), modeFlags, -1);
6663        }
6664    }
6665
6666    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6667            final int modeFlags, UriPermissionOwner owner) {
6668        if (!Intent.isAccessUriMode(modeFlags)) {
6669            return;
6670        }
6671
6672        // So here we are: the caller has the assumed permission
6673        // to the uri, and the target doesn't.  Let's now give this to
6674        // the target.
6675
6676        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6677                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6678
6679        final String authority = grantUri.uri.getAuthority();
6680        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6681        if (pi == null) {
6682            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6683            return;
6684        }
6685
6686        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6687            grantUri.prefix = true;
6688        }
6689        final UriPermission perm = findOrCreateUriPermissionLocked(
6690                pi.packageName, targetPkg, targetUid, grantUri);
6691        perm.grantModes(modeFlags, owner);
6692    }
6693
6694    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6695            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6696        if (targetPkg == null) {
6697            throw new NullPointerException("targetPkg");
6698        }
6699        int targetUid;
6700        final IPackageManager pm = AppGlobals.getPackageManager();
6701        try {
6702            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6703        } catch (RemoteException ex) {
6704            return;
6705        }
6706
6707        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6708                targetUid);
6709        if (targetUid < 0) {
6710            return;
6711        }
6712
6713        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6714                owner);
6715    }
6716
6717    static class NeededUriGrants extends ArrayList<GrantUri> {
6718        final String targetPkg;
6719        final int targetUid;
6720        final int flags;
6721
6722        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6723            this.targetPkg = targetPkg;
6724            this.targetUid = targetUid;
6725            this.flags = flags;
6726        }
6727    }
6728
6729    /**
6730     * Like checkGrantUriPermissionLocked, but takes an Intent.
6731     */
6732    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6733            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6734        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6735                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6736                + " clip=" + (intent != null ? intent.getClipData() : null)
6737                + " from " + intent + "; flags=0x"
6738                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6739
6740        if (targetPkg == null) {
6741            throw new NullPointerException("targetPkg");
6742        }
6743
6744        if (intent == null) {
6745            return null;
6746        }
6747        Uri data = intent.getData();
6748        ClipData clip = intent.getClipData();
6749        if (data == null && clip == null) {
6750            return null;
6751        }
6752        // Default userId for uris in the intent (if they don't specify it themselves)
6753        int contentUserHint = intent.getContentUserHint();
6754        if (contentUserHint == UserHandle.USER_CURRENT) {
6755            contentUserHint = UserHandle.getUserId(callingUid);
6756        }
6757        final IPackageManager pm = AppGlobals.getPackageManager();
6758        int targetUid;
6759        if (needed != null) {
6760            targetUid = needed.targetUid;
6761        } else {
6762            try {
6763                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6764            } catch (RemoteException ex) {
6765                return null;
6766            }
6767            if (targetUid < 0) {
6768                if (DEBUG_URI_PERMISSION) {
6769                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6770                            + " on user " + targetUserId);
6771                }
6772                return null;
6773            }
6774        }
6775        if (data != null) {
6776            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6777            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6778                    targetUid);
6779            if (targetUid > 0) {
6780                if (needed == null) {
6781                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6782                }
6783                needed.add(grantUri);
6784            }
6785        }
6786        if (clip != null) {
6787            for (int i=0; i<clip.getItemCount(); i++) {
6788                Uri uri = clip.getItemAt(i).getUri();
6789                if (uri != null) {
6790                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6791                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6792                            targetUid);
6793                    if (targetUid > 0) {
6794                        if (needed == null) {
6795                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6796                        }
6797                        needed.add(grantUri);
6798                    }
6799                } else {
6800                    Intent clipIntent = clip.getItemAt(i).getIntent();
6801                    if (clipIntent != null) {
6802                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6803                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6804                        if (newNeeded != null) {
6805                            needed = newNeeded;
6806                        }
6807                    }
6808                }
6809            }
6810        }
6811
6812        return needed;
6813    }
6814
6815    /**
6816     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6817     */
6818    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6819            UriPermissionOwner owner) {
6820        if (needed != null) {
6821            for (int i=0; i<needed.size(); i++) {
6822                GrantUri grantUri = needed.get(i);
6823                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6824                        grantUri, needed.flags, owner);
6825            }
6826        }
6827    }
6828
6829    void grantUriPermissionFromIntentLocked(int callingUid,
6830            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6831        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6832                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6833        if (needed == null) {
6834            return;
6835        }
6836
6837        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6838    }
6839
6840    @Override
6841    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6842            final int modeFlags, int userId) {
6843        enforceNotIsolatedCaller("grantUriPermission");
6844        GrantUri grantUri = new GrantUri(userId, uri, false);
6845        synchronized(this) {
6846            final ProcessRecord r = getRecordForAppLocked(caller);
6847            if (r == null) {
6848                throw new SecurityException("Unable to find app for caller "
6849                        + caller
6850                        + " when granting permission to uri " + grantUri);
6851            }
6852            if (targetPkg == null) {
6853                throw new IllegalArgumentException("null target");
6854            }
6855            if (grantUri == null) {
6856                throw new IllegalArgumentException("null uri");
6857            }
6858
6859            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6860                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6861                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6862                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6863
6864            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6865                    UserHandle.getUserId(r.uid));
6866        }
6867    }
6868
6869    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6870        if (perm.modeFlags == 0) {
6871            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6872                    perm.targetUid);
6873            if (perms != null) {
6874                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6875                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6876
6877                perms.remove(perm.uri);
6878                if (perms.isEmpty()) {
6879                    mGrantedUriPermissions.remove(perm.targetUid);
6880                }
6881            }
6882        }
6883    }
6884
6885    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6886        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6887
6888        final IPackageManager pm = AppGlobals.getPackageManager();
6889        final String authority = grantUri.uri.getAuthority();
6890        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6891        if (pi == null) {
6892            Slog.w(TAG, "No content provider found for permission revoke: "
6893                    + grantUri.toSafeString());
6894            return;
6895        }
6896
6897        // Does the caller have this permission on the URI?
6898        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6899            // Right now, if you are not the original owner of the permission,
6900            // you are not allowed to revoke it.
6901            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6902                throw new SecurityException("Uid " + callingUid
6903                        + " does not have permission to uri " + grantUri);
6904            //}
6905        }
6906
6907        boolean persistChanged = false;
6908
6909        // Go through all of the permissions and remove any that match.
6910        int N = mGrantedUriPermissions.size();
6911        for (int i = 0; i < N; i++) {
6912            final int targetUid = mGrantedUriPermissions.keyAt(i);
6913            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6914
6915            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6916                final UriPermission perm = it.next();
6917                if (perm.uri.sourceUserId == grantUri.sourceUserId
6918                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6919                    if (DEBUG_URI_PERMISSION)
6920                        Slog.v(TAG,
6921                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6922                    persistChanged |= perm.revokeModes(
6923                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6924                    if (perm.modeFlags == 0) {
6925                        it.remove();
6926                    }
6927                }
6928            }
6929
6930            if (perms.isEmpty()) {
6931                mGrantedUriPermissions.remove(targetUid);
6932                N--;
6933                i--;
6934            }
6935        }
6936
6937        if (persistChanged) {
6938            schedulePersistUriGrants();
6939        }
6940    }
6941
6942    @Override
6943    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6944            int userId) {
6945        enforceNotIsolatedCaller("revokeUriPermission");
6946        synchronized(this) {
6947            final ProcessRecord r = getRecordForAppLocked(caller);
6948            if (r == null) {
6949                throw new SecurityException("Unable to find app for caller "
6950                        + caller
6951                        + " when revoking permission to uri " + uri);
6952            }
6953            if (uri == null) {
6954                Slog.w(TAG, "revokeUriPermission: null uri");
6955                return;
6956            }
6957
6958            if (!Intent.isAccessUriMode(modeFlags)) {
6959                return;
6960            }
6961
6962            final IPackageManager pm = AppGlobals.getPackageManager();
6963            final String authority = uri.getAuthority();
6964            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6965            if (pi == null) {
6966                Slog.w(TAG, "No content provider found for permission revoke: "
6967                        + uri.toSafeString());
6968                return;
6969            }
6970
6971            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6972        }
6973    }
6974
6975    /**
6976     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6977     * given package.
6978     *
6979     * @param packageName Package name to match, or {@code null} to apply to all
6980     *            packages.
6981     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6982     *            to all users.
6983     * @param persistable If persistable grants should be removed.
6984     */
6985    private void removeUriPermissionsForPackageLocked(
6986            String packageName, int userHandle, boolean persistable) {
6987        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6988            throw new IllegalArgumentException("Must narrow by either package or user");
6989        }
6990
6991        boolean persistChanged = false;
6992
6993        int N = mGrantedUriPermissions.size();
6994        for (int i = 0; i < N; i++) {
6995            final int targetUid = mGrantedUriPermissions.keyAt(i);
6996            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6997
6998            // Only inspect grants matching user
6999            if (userHandle == UserHandle.USER_ALL
7000                    || userHandle == UserHandle.getUserId(targetUid)) {
7001                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7002                    final UriPermission perm = it.next();
7003
7004                    // Only inspect grants matching package
7005                    if (packageName == null || perm.sourcePkg.equals(packageName)
7006                            || perm.targetPkg.equals(packageName)) {
7007                        persistChanged |= perm.revokeModes(
7008                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7009
7010                        // Only remove when no modes remain; any persisted grants
7011                        // will keep this alive.
7012                        if (perm.modeFlags == 0) {
7013                            it.remove();
7014                        }
7015                    }
7016                }
7017
7018                if (perms.isEmpty()) {
7019                    mGrantedUriPermissions.remove(targetUid);
7020                    N--;
7021                    i--;
7022                }
7023            }
7024        }
7025
7026        if (persistChanged) {
7027            schedulePersistUriGrants();
7028        }
7029    }
7030
7031    @Override
7032    public IBinder newUriPermissionOwner(String name) {
7033        enforceNotIsolatedCaller("newUriPermissionOwner");
7034        synchronized(this) {
7035            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7036            return owner.getExternalTokenLocked();
7037        }
7038    }
7039
7040    @Override
7041    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7042            final int modeFlags, int sourceUserId, int targetUserId) {
7043        synchronized(this) {
7044            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7045            if (owner == null) {
7046                throw new IllegalArgumentException("Unknown owner: " + token);
7047            }
7048            if (fromUid != Binder.getCallingUid()) {
7049                if (Binder.getCallingUid() != Process.myUid()) {
7050                    // Only system code can grant URI permissions on behalf
7051                    // of other users.
7052                    throw new SecurityException("nice try");
7053                }
7054            }
7055            if (targetPkg == null) {
7056                throw new IllegalArgumentException("null target");
7057            }
7058            if (uri == null) {
7059                throw new IllegalArgumentException("null uri");
7060            }
7061
7062            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7063                    modeFlags, owner, targetUserId);
7064        }
7065    }
7066
7067    @Override
7068    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7069        synchronized(this) {
7070            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7071            if (owner == null) {
7072                throw new IllegalArgumentException("Unknown owner: " + token);
7073            }
7074
7075            if (uri == null) {
7076                owner.removeUriPermissionsLocked(mode);
7077            } else {
7078                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7079            }
7080        }
7081    }
7082
7083    private void schedulePersistUriGrants() {
7084        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7085            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7086                    10 * DateUtils.SECOND_IN_MILLIS);
7087        }
7088    }
7089
7090    private void writeGrantedUriPermissions() {
7091        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7092
7093        // Snapshot permissions so we can persist without lock
7094        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7095        synchronized (this) {
7096            final int size = mGrantedUriPermissions.size();
7097            for (int i = 0; i < size; i++) {
7098                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7099                for (UriPermission perm : perms.values()) {
7100                    if (perm.persistedModeFlags != 0) {
7101                        persist.add(perm.snapshot());
7102                    }
7103                }
7104            }
7105        }
7106
7107        FileOutputStream fos = null;
7108        try {
7109            fos = mGrantFile.startWrite();
7110
7111            XmlSerializer out = new FastXmlSerializer();
7112            out.setOutput(fos, "utf-8");
7113            out.startDocument(null, true);
7114            out.startTag(null, TAG_URI_GRANTS);
7115            for (UriPermission.Snapshot perm : persist) {
7116                out.startTag(null, TAG_URI_GRANT);
7117                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7118                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7119                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7120                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7121                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7122                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7123                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7124                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7125                out.endTag(null, TAG_URI_GRANT);
7126            }
7127            out.endTag(null, TAG_URI_GRANTS);
7128            out.endDocument();
7129
7130            mGrantFile.finishWrite(fos);
7131        } catch (IOException e) {
7132            if (fos != null) {
7133                mGrantFile.failWrite(fos);
7134            }
7135        }
7136    }
7137
7138    private void readGrantedUriPermissionsLocked() {
7139        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7140
7141        final long now = System.currentTimeMillis();
7142
7143        FileInputStream fis = null;
7144        try {
7145            fis = mGrantFile.openRead();
7146            final XmlPullParser in = Xml.newPullParser();
7147            in.setInput(fis, null);
7148
7149            int type;
7150            while ((type = in.next()) != END_DOCUMENT) {
7151                final String tag = in.getName();
7152                if (type == START_TAG) {
7153                    if (TAG_URI_GRANT.equals(tag)) {
7154                        final int sourceUserId;
7155                        final int targetUserId;
7156                        final int userHandle = readIntAttribute(in,
7157                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7158                        if (userHandle != UserHandle.USER_NULL) {
7159                            // For backwards compatibility.
7160                            sourceUserId = userHandle;
7161                            targetUserId = userHandle;
7162                        } else {
7163                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7164                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7165                        }
7166                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7167                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7168                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7169                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7170                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7171                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7172
7173                        // Sanity check that provider still belongs to source package
7174                        final ProviderInfo pi = getProviderInfoLocked(
7175                                uri.getAuthority(), sourceUserId);
7176                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7177                            int targetUid = -1;
7178                            try {
7179                                targetUid = AppGlobals.getPackageManager()
7180                                        .getPackageUid(targetPkg, targetUserId);
7181                            } catch (RemoteException e) {
7182                            }
7183                            if (targetUid != -1) {
7184                                final UriPermission perm = findOrCreateUriPermissionLocked(
7185                                        sourcePkg, targetPkg, targetUid,
7186                                        new GrantUri(sourceUserId, uri, prefix));
7187                                perm.initPersistedModes(modeFlags, createdTime);
7188                            }
7189                        } else {
7190                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7191                                    + " but instead found " + pi);
7192                        }
7193                    }
7194                }
7195            }
7196        } catch (FileNotFoundException e) {
7197            // Missing grants is okay
7198        } catch (IOException e) {
7199            Log.wtf(TAG, "Failed reading Uri grants", e);
7200        } catch (XmlPullParserException e) {
7201            Log.wtf(TAG, "Failed reading Uri grants", e);
7202        } finally {
7203            IoUtils.closeQuietly(fis);
7204        }
7205    }
7206
7207    @Override
7208    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7209        enforceNotIsolatedCaller("takePersistableUriPermission");
7210
7211        Preconditions.checkFlagsArgument(modeFlags,
7212                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7213
7214        synchronized (this) {
7215            final int callingUid = Binder.getCallingUid();
7216            boolean persistChanged = false;
7217            GrantUri grantUri = new GrantUri(userId, uri, false);
7218
7219            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7220                    new GrantUri(userId, uri, false));
7221            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7222                    new GrantUri(userId, uri, true));
7223
7224            final boolean exactValid = (exactPerm != null)
7225                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7226            final boolean prefixValid = (prefixPerm != null)
7227                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7228
7229            if (!(exactValid || prefixValid)) {
7230                throw new SecurityException("No persistable permission grants found for UID "
7231                        + callingUid + " and Uri " + grantUri.toSafeString());
7232            }
7233
7234            if (exactValid) {
7235                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7236            }
7237            if (prefixValid) {
7238                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7239            }
7240
7241            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7242
7243            if (persistChanged) {
7244                schedulePersistUriGrants();
7245            }
7246        }
7247    }
7248
7249    @Override
7250    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7251        enforceNotIsolatedCaller("releasePersistableUriPermission");
7252
7253        Preconditions.checkFlagsArgument(modeFlags,
7254                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7255
7256        synchronized (this) {
7257            final int callingUid = Binder.getCallingUid();
7258            boolean persistChanged = false;
7259
7260            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7261                    new GrantUri(userId, uri, false));
7262            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7263                    new GrantUri(userId, uri, true));
7264            if (exactPerm == null && prefixPerm == null) {
7265                throw new SecurityException("No permission grants found for UID " + callingUid
7266                        + " and Uri " + uri.toSafeString());
7267            }
7268
7269            if (exactPerm != null) {
7270                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7271                removeUriPermissionIfNeededLocked(exactPerm);
7272            }
7273            if (prefixPerm != null) {
7274                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7275                removeUriPermissionIfNeededLocked(prefixPerm);
7276            }
7277
7278            if (persistChanged) {
7279                schedulePersistUriGrants();
7280            }
7281        }
7282    }
7283
7284    /**
7285     * Prune any older {@link UriPermission} for the given UID until outstanding
7286     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7287     *
7288     * @return if any mutations occured that require persisting.
7289     */
7290    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7291        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7292        if (perms == null) return false;
7293        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7294
7295        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7296        for (UriPermission perm : perms.values()) {
7297            if (perm.persistedModeFlags != 0) {
7298                persisted.add(perm);
7299            }
7300        }
7301
7302        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7303        if (trimCount <= 0) return false;
7304
7305        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7306        for (int i = 0; i < trimCount; i++) {
7307            final UriPermission perm = persisted.get(i);
7308
7309            if (DEBUG_URI_PERMISSION) {
7310                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7311            }
7312
7313            perm.releasePersistableModes(~0);
7314            removeUriPermissionIfNeededLocked(perm);
7315        }
7316
7317        return true;
7318    }
7319
7320    @Override
7321    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7322            String packageName, boolean incoming) {
7323        enforceNotIsolatedCaller("getPersistedUriPermissions");
7324        Preconditions.checkNotNull(packageName, "packageName");
7325
7326        final int callingUid = Binder.getCallingUid();
7327        final IPackageManager pm = AppGlobals.getPackageManager();
7328        try {
7329            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7330            if (packageUid != callingUid) {
7331                throw new SecurityException(
7332                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7333            }
7334        } catch (RemoteException e) {
7335            throw new SecurityException("Failed to verify package name ownership");
7336        }
7337
7338        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7339        synchronized (this) {
7340            if (incoming) {
7341                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7342                        callingUid);
7343                if (perms == null) {
7344                    Slog.w(TAG, "No permission grants found for " + packageName);
7345                } else {
7346                    for (UriPermission perm : perms.values()) {
7347                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7348                            result.add(perm.buildPersistedPublicApiObject());
7349                        }
7350                    }
7351                }
7352            } else {
7353                final int size = mGrantedUriPermissions.size();
7354                for (int i = 0; i < size; i++) {
7355                    final ArrayMap<GrantUri, UriPermission> perms =
7356                            mGrantedUriPermissions.valueAt(i);
7357                    for (UriPermission perm : perms.values()) {
7358                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7359                            result.add(perm.buildPersistedPublicApiObject());
7360                        }
7361                    }
7362                }
7363            }
7364        }
7365        return new ParceledListSlice<android.content.UriPermission>(result);
7366    }
7367
7368    @Override
7369    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7370        synchronized (this) {
7371            ProcessRecord app =
7372                who != null ? getRecordForAppLocked(who) : null;
7373            if (app == null) return;
7374
7375            Message msg = Message.obtain();
7376            msg.what = WAIT_FOR_DEBUGGER_MSG;
7377            msg.obj = app;
7378            msg.arg1 = waiting ? 1 : 0;
7379            mHandler.sendMessage(msg);
7380        }
7381    }
7382
7383    @Override
7384    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7385        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7386        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7387        outInfo.availMem = Process.getFreeMemory();
7388        outInfo.totalMem = Process.getTotalMemory();
7389        outInfo.threshold = homeAppMem;
7390        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7391        outInfo.hiddenAppThreshold = cachedAppMem;
7392        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7393                ProcessList.SERVICE_ADJ);
7394        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7395                ProcessList.VISIBLE_APP_ADJ);
7396        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7397                ProcessList.FOREGROUND_APP_ADJ);
7398    }
7399
7400    // =========================================================
7401    // TASK MANAGEMENT
7402    // =========================================================
7403
7404    @Override
7405    public List<IAppTask> getAppTasks() {
7406        final PackageManager pm = mContext.getPackageManager();
7407        int callingUid = Binder.getCallingUid();
7408        long ident = Binder.clearCallingIdentity();
7409
7410        // Compose the list of packages for this id to test against
7411        HashSet<String> packages = new HashSet<String>();
7412        String[] uidPackages = pm.getPackagesForUid(callingUid);
7413        for (int i = 0; i < uidPackages.length; i++) {
7414            packages.add(uidPackages[i]);
7415        }
7416
7417        synchronized(this) {
7418            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7419            try {
7420                if (localLOGV) Slog.v(TAG, "getAppTasks");
7421
7422                final int N = mRecentTasks.size();
7423                for (int i = 0; i < N; i++) {
7424                    TaskRecord tr = mRecentTasks.get(i);
7425                    // Skip tasks that do not match the package name
7426                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7427                        ActivityManager.RecentTaskInfo taskInfo =
7428                                createRecentTaskInfoFromTaskRecord(tr);
7429                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7430                        list.add(taskImpl);
7431                    }
7432                }
7433            } finally {
7434                Binder.restoreCallingIdentity(ident);
7435            }
7436            return list;
7437        }
7438    }
7439
7440    @Override
7441    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7442        final int callingUid = Binder.getCallingUid();
7443        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7444
7445        synchronized(this) {
7446            if (localLOGV) Slog.v(
7447                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7448
7449            final boolean allowed = checkCallingPermission(
7450                    android.Manifest.permission.GET_TASKS)
7451                    == PackageManager.PERMISSION_GRANTED;
7452            if (!allowed) {
7453                Slog.w(TAG, "getTasks: caller " + callingUid
7454                        + " does not hold GET_TASKS; limiting output");
7455            }
7456
7457            // TODO: Improve with MRU list from all ActivityStacks.
7458            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7459        }
7460
7461        return list;
7462    }
7463
7464    TaskRecord getMostRecentTask() {
7465        return mRecentTasks.get(0);
7466    }
7467
7468    /**
7469     * Creates a new RecentTaskInfo from a TaskRecord.
7470     */
7471    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7472        // Update the task description to reflect any changes in the task stack
7473        tr.updateTaskDescription();
7474
7475        // Compose the recent task info
7476        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7477        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7478        rti.persistentId = tr.taskId;
7479        rti.baseIntent = new Intent(tr.getBaseIntent());
7480        rti.origActivity = tr.origActivity;
7481        rti.description = tr.lastDescription;
7482        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7483        rti.userId = tr.userId;
7484        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7485        rti.firstActiveTime = tr.firstActiveTime;
7486        rti.lastActiveTime = tr.lastActiveTime;
7487        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7488        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
7489        return rti;
7490    }
7491
7492    @Override
7493    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7494        final int callingUid = Binder.getCallingUid();
7495        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7496                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7497
7498        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7499        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7500        synchronized (this) {
7501            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7502                    == PackageManager.PERMISSION_GRANTED;
7503            if (!allowed) {
7504                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7505                        + " does not hold GET_TASKS; limiting output");
7506            }
7507            final boolean detailed = checkCallingPermission(
7508                    android.Manifest.permission.GET_DETAILED_TASKS)
7509                    == PackageManager.PERMISSION_GRANTED;
7510
7511            IPackageManager pm = AppGlobals.getPackageManager();
7512
7513            final int N = mRecentTasks.size();
7514            ArrayList<ActivityManager.RecentTaskInfo> res
7515                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7516                            maxNum < N ? maxNum : N);
7517
7518            final Set<Integer> includedUsers;
7519            if (includeProfiles) {
7520                includedUsers = getProfileIdsLocked(userId);
7521            } else {
7522                includedUsers = new HashSet<Integer>();
7523            }
7524            includedUsers.add(Integer.valueOf(userId));
7525
7526            // Regroup affiliated tasks together.
7527            for (int i = 0; i < N; ) {
7528                TaskRecord task = mRecentTasks.remove(i);
7529                if (mTmpRecents.contains(task)) {
7530                    continue;
7531                }
7532                int affiliatedTaskId = task.mAffiliatedTaskId;
7533                while (true) {
7534                    TaskRecord next = task.mNextAffiliate;
7535                    if (next == null) {
7536                        break;
7537                    }
7538                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7539                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7540                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7541                        task.setNextAffiliate(null);
7542                        if (next.mPrevAffiliate == task) {
7543                            next.setPrevAffiliate(null);
7544                        }
7545                        break;
7546                    }
7547                    if (next.mPrevAffiliate != task) {
7548                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7549                                next.mPrevAffiliate + " task=" + task);
7550                        next.setPrevAffiliate(null);
7551                        break;
7552                    }
7553                    if (!mRecentTasks.contains(next)) {
7554                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7555                        task.setNextAffiliate(null);
7556                        if (next.mPrevAffiliate == task) {
7557                            next.setPrevAffiliate(null);
7558                        }
7559                        break;
7560                    }
7561                    task = next;
7562                }
7563                // task is now the end of the list
7564                do {
7565                    mRecentTasks.remove(task);
7566                    mRecentTasks.add(i++, task);
7567                    mTmpRecents.add(task);
7568                } while ((task = task.mPrevAffiliate) != null);
7569            }
7570            mTmpRecents.clear();
7571            // mRecentTasks is now in sorted, affiliated order.
7572
7573            for (int i=0; i<N && maxNum > 0; i++) {
7574                TaskRecord tr = mRecentTasks.get(i);
7575                // Only add calling user or related users recent tasks
7576                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7577
7578                // Return the entry if desired by the caller.  We always return
7579                // the first entry, because callers always expect this to be the
7580                // foreground app.  We may filter others if the caller has
7581                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7582                // we should exclude the entry.
7583
7584                if (i == 0
7585                        || withExcluded
7586                        || (tr.intent == null)
7587                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7588                                == 0)) {
7589                    if (!allowed) {
7590                        // If the caller doesn't have the GET_TASKS permission, then only
7591                        // allow them to see a small subset of tasks -- their own and home.
7592                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7593                            continue;
7594                        }
7595                    }
7596                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7597                        // Don't include auto remove tasks that are finished or finishing.
7598                        continue;
7599                    }
7600
7601                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7602                    if (!detailed) {
7603                        rti.baseIntent.replaceExtras((Bundle)null);
7604                    }
7605
7606                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7607                        // Check whether this activity is currently available.
7608                        try {
7609                            if (rti.origActivity != null) {
7610                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7611                                        == null) {
7612                                    continue;
7613                                }
7614                            } else if (rti.baseIntent != null) {
7615                                if (pm.queryIntentActivities(rti.baseIntent,
7616                                        null, 0, userId) == null) {
7617                                    continue;
7618                                }
7619                            }
7620                        } catch (RemoteException e) {
7621                            // Will never happen.
7622                        }
7623                    }
7624
7625                    res.add(rti);
7626                    maxNum--;
7627                }
7628            }
7629            return res;
7630        }
7631    }
7632
7633    private TaskRecord recentTaskForIdLocked(int id) {
7634        final int N = mRecentTasks.size();
7635            for (int i=0; i<N; i++) {
7636                TaskRecord tr = mRecentTasks.get(i);
7637                if (tr.taskId == id) {
7638                    return tr;
7639                }
7640            }
7641            return null;
7642    }
7643
7644    @Override
7645    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7646        synchronized (this) {
7647            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7648                    "getTaskThumbnail()");
7649            TaskRecord tr = recentTaskForIdLocked(id);
7650            if (tr != null) {
7651                return tr.getTaskThumbnailLocked();
7652            }
7653        }
7654        return null;
7655    }
7656
7657    @Override
7658    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7659        synchronized (this) {
7660            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7661            if (r != null) {
7662                r.taskDescription = td;
7663                r.task.updateTaskDescription();
7664            }
7665        }
7666    }
7667
7668    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7669        if (!pr.killedByAm) {
7670            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7671            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7672                    pr.processName, pr.setAdj, reason);
7673            pr.killedByAm = true;
7674            Process.killProcessQuiet(pr.pid);
7675            Process.killProcessGroup(pr.info.uid, pr.pid);
7676        }
7677    }
7678
7679    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7680        tr.disposeThumbnail();
7681        mRecentTasks.remove(tr);
7682        tr.closeRecentsChain();
7683        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7684        Intent baseIntent = new Intent(
7685                tr.intent != null ? tr.intent : tr.affinityIntent);
7686        ComponentName component = baseIntent.getComponent();
7687        if (component == null) {
7688            Slog.w(TAG, "Now component for base intent of task: " + tr);
7689            return;
7690        }
7691
7692        // Find any running services associated with this app.
7693        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7694
7695        if (killProcesses) {
7696            // Find any running processes associated with this app.
7697            final String pkg = component.getPackageName();
7698            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7699            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7700            for (int i=0; i<pmap.size(); i++) {
7701                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7702                for (int j=0; j<uids.size(); j++) {
7703                    ProcessRecord proc = uids.valueAt(j);
7704                    if (proc.userId != tr.userId) {
7705                        continue;
7706                    }
7707                    if (!proc.pkgList.containsKey(pkg)) {
7708                        continue;
7709                    }
7710                    procs.add(proc);
7711                }
7712            }
7713
7714            // Kill the running processes.
7715            for (int i=0; i<procs.size(); i++) {
7716                ProcessRecord pr = procs.get(i);
7717                if (pr == mHomeProcess) {
7718                    // Don't kill the home process along with tasks from the same package.
7719                    continue;
7720                }
7721                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7722                    killUnneededProcessLocked(pr, "remove task");
7723                } else {
7724                    pr.waitingToKill = "remove task";
7725                }
7726            }
7727        }
7728    }
7729
7730    /**
7731     * Removes the task with the specified task id.
7732     *
7733     * @param taskId Identifier of the task to be removed.
7734     * @param flags Additional operational flags.  May be 0 or
7735     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7736     * @return Returns true if the given task was found and removed.
7737     */
7738    private boolean removeTaskByIdLocked(int taskId, int flags) {
7739        TaskRecord tr = recentTaskForIdLocked(taskId);
7740        if (tr != null) {
7741            tr.removeTaskActivitiesLocked();
7742            cleanUpRemovedTaskLocked(tr, flags);
7743            if (tr.isPersistable) {
7744                notifyTaskPersisterLocked(null, true);
7745            }
7746            return true;
7747        }
7748        return false;
7749    }
7750
7751    @Override
7752    public boolean removeTask(int taskId, int flags) {
7753        synchronized (this) {
7754            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7755                    "removeTask()");
7756            long ident = Binder.clearCallingIdentity();
7757            try {
7758                return removeTaskByIdLocked(taskId, flags);
7759            } finally {
7760                Binder.restoreCallingIdentity(ident);
7761            }
7762        }
7763    }
7764
7765    /**
7766     * TODO: Add mController hook
7767     */
7768    @Override
7769    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7770        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7771                "moveTaskToFront()");
7772
7773        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7774        synchronized(this) {
7775            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7776                    Binder.getCallingUid(), "Task to front")) {
7777                ActivityOptions.abort(options);
7778                return;
7779            }
7780            final long origId = Binder.clearCallingIdentity();
7781            try {
7782                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7783                if (task == null) {
7784                    return;
7785                }
7786                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7787                    mStackSupervisor.showLockTaskToast();
7788                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7789                    return;
7790                }
7791                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7792                if (prev != null && prev.isRecentsActivity()) {
7793                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7794                }
7795                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7796            } finally {
7797                Binder.restoreCallingIdentity(origId);
7798            }
7799            ActivityOptions.abort(options);
7800        }
7801    }
7802
7803    @Override
7804    public void moveTaskToBack(int taskId) {
7805        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7806                "moveTaskToBack()");
7807
7808        synchronized(this) {
7809            TaskRecord tr = recentTaskForIdLocked(taskId);
7810            if (tr != null) {
7811                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7812                ActivityStack stack = tr.stack;
7813                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7814                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7815                            Binder.getCallingUid(), "Task to back")) {
7816                        return;
7817                    }
7818                }
7819                final long origId = Binder.clearCallingIdentity();
7820                try {
7821                    stack.moveTaskToBackLocked(taskId, null);
7822                } finally {
7823                    Binder.restoreCallingIdentity(origId);
7824                }
7825            }
7826        }
7827    }
7828
7829    /**
7830     * Moves an activity, and all of the other activities within the same task, to the bottom
7831     * of the history stack.  The activity's order within the task is unchanged.
7832     *
7833     * @param token A reference to the activity we wish to move
7834     * @param nonRoot If false then this only works if the activity is the root
7835     *                of a task; if true it will work for any activity in a task.
7836     * @return Returns true if the move completed, false if not.
7837     */
7838    @Override
7839    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7840        enforceNotIsolatedCaller("moveActivityTaskToBack");
7841        synchronized(this) {
7842            final long origId = Binder.clearCallingIdentity();
7843            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7844            if (taskId >= 0) {
7845                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7846            }
7847            Binder.restoreCallingIdentity(origId);
7848        }
7849        return false;
7850    }
7851
7852    @Override
7853    public void moveTaskBackwards(int task) {
7854        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7855                "moveTaskBackwards()");
7856
7857        synchronized(this) {
7858            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7859                    Binder.getCallingUid(), "Task backwards")) {
7860                return;
7861            }
7862            final long origId = Binder.clearCallingIdentity();
7863            moveTaskBackwardsLocked(task);
7864            Binder.restoreCallingIdentity(origId);
7865        }
7866    }
7867
7868    private final void moveTaskBackwardsLocked(int task) {
7869        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7870    }
7871
7872    @Override
7873    public IBinder getHomeActivityToken() throws RemoteException {
7874        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7875                "getHomeActivityToken()");
7876        synchronized (this) {
7877            return mStackSupervisor.getHomeActivityToken();
7878        }
7879    }
7880
7881    @Override
7882    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7883            IActivityContainerCallback callback) throws RemoteException {
7884        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7885                "createActivityContainer()");
7886        synchronized (this) {
7887            if (parentActivityToken == null) {
7888                throw new IllegalArgumentException("parent token must not be null");
7889            }
7890            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7891            if (r == null) {
7892                return null;
7893            }
7894            if (callback == null) {
7895                throw new IllegalArgumentException("callback must not be null");
7896            }
7897            return mStackSupervisor.createActivityContainer(r, callback);
7898        }
7899    }
7900
7901    @Override
7902    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7903        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7904                "deleteActivityContainer()");
7905        synchronized (this) {
7906            mStackSupervisor.deleteActivityContainer(container);
7907        }
7908    }
7909
7910    @Override
7911    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7912            throws RemoteException {
7913        synchronized (this) {
7914            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7915            if (stack != null) {
7916                return stack.mActivityContainer;
7917            }
7918            return null;
7919        }
7920    }
7921
7922    @Override
7923    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7924        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7925                "moveTaskToStack()");
7926        if (stackId == HOME_STACK_ID) {
7927            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7928                    new RuntimeException("here").fillInStackTrace());
7929        }
7930        synchronized (this) {
7931            long ident = Binder.clearCallingIdentity();
7932            try {
7933                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7934                        + stackId + " toTop=" + toTop);
7935                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7936            } finally {
7937                Binder.restoreCallingIdentity(ident);
7938            }
7939        }
7940    }
7941
7942    @Override
7943    public void resizeStack(int stackBoxId, Rect bounds) {
7944        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7945                "resizeStackBox()");
7946        long ident = Binder.clearCallingIdentity();
7947        try {
7948            mWindowManager.resizeStack(stackBoxId, bounds);
7949        } finally {
7950            Binder.restoreCallingIdentity(ident);
7951        }
7952    }
7953
7954    @Override
7955    public List<StackInfo> getAllStackInfos() {
7956        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7957                "getAllStackInfos()");
7958        long ident = Binder.clearCallingIdentity();
7959        try {
7960            synchronized (this) {
7961                return mStackSupervisor.getAllStackInfosLocked();
7962            }
7963        } finally {
7964            Binder.restoreCallingIdentity(ident);
7965        }
7966    }
7967
7968    @Override
7969    public StackInfo getStackInfo(int stackId) {
7970        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7971                "getStackInfo()");
7972        long ident = Binder.clearCallingIdentity();
7973        try {
7974            synchronized (this) {
7975                return mStackSupervisor.getStackInfoLocked(stackId);
7976            }
7977        } finally {
7978            Binder.restoreCallingIdentity(ident);
7979        }
7980    }
7981
7982    @Override
7983    public boolean isInHomeStack(int taskId) {
7984        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7985                "getStackInfo()");
7986        long ident = Binder.clearCallingIdentity();
7987        try {
7988            synchronized (this) {
7989                TaskRecord tr = recentTaskForIdLocked(taskId);
7990                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7991            }
7992        } finally {
7993            Binder.restoreCallingIdentity(ident);
7994        }
7995    }
7996
7997    @Override
7998    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7999        synchronized(this) {
8000            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8001        }
8002    }
8003
8004    private boolean isLockTaskAuthorized(String pkg) {
8005        final DevicePolicyManager dpm = (DevicePolicyManager)
8006                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8007        try {
8008            int uid = mContext.getPackageManager().getPackageUid(pkg,
8009                    Binder.getCallingUserHandle().getIdentifier());
8010            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8011        } catch (NameNotFoundException e) {
8012            return false;
8013        }
8014    }
8015
8016    void startLockTaskMode(TaskRecord task) {
8017        final String pkg;
8018        synchronized (this) {
8019            pkg = task.intent.getComponent().getPackageName();
8020        }
8021        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8022        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8023            final TaskRecord taskRecord = task;
8024            mHandler.post(new Runnable() {
8025                @Override
8026                public void run() {
8027                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8028                }
8029            });
8030            return;
8031        }
8032        long ident = Binder.clearCallingIdentity();
8033        try {
8034            synchronized (this) {
8035                // Since we lost lock on task, make sure it is still there.
8036                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8037                if (task != null) {
8038                    if (!isSystemInitiated
8039                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8040                        throw new IllegalArgumentException("Invalid task, not in foreground");
8041                    }
8042                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8043                }
8044            }
8045        } finally {
8046            Binder.restoreCallingIdentity(ident);
8047        }
8048    }
8049
8050    @Override
8051    public void startLockTaskMode(int taskId) {
8052        final TaskRecord task;
8053        long ident = Binder.clearCallingIdentity();
8054        try {
8055            synchronized (this) {
8056                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8057            }
8058        } finally {
8059            Binder.restoreCallingIdentity(ident);
8060        }
8061        if (task != null) {
8062            startLockTaskMode(task);
8063        }
8064    }
8065
8066    @Override
8067    public void startLockTaskMode(IBinder token) {
8068        final TaskRecord task;
8069        long ident = Binder.clearCallingIdentity();
8070        try {
8071            synchronized (this) {
8072                final ActivityRecord r = ActivityRecord.forToken(token);
8073                if (r == null) {
8074                    return;
8075                }
8076                task = r.task;
8077            }
8078        } finally {
8079            Binder.restoreCallingIdentity(ident);
8080        }
8081        if (task != null) {
8082            startLockTaskMode(task);
8083        }
8084    }
8085
8086    @Override
8087    public void startLockTaskModeOnCurrent() throws RemoteException {
8088        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8089        ActivityRecord r = null;
8090        synchronized (this) {
8091            r = mStackSupervisor.topRunningActivityLocked();
8092        }
8093        startLockTaskMode(r.task);
8094    }
8095
8096    @Override
8097    public void stopLockTaskMode() {
8098        // Verify that the user matches the package of the intent for the TaskRecord
8099        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8100        // and stopLockTaskMode.
8101        final int callingUid = Binder.getCallingUid();
8102        if (callingUid != Process.SYSTEM_UID) {
8103            try {
8104                String pkg =
8105                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8106                int uid = mContext.getPackageManager().getPackageUid(pkg,
8107                        Binder.getCallingUserHandle().getIdentifier());
8108                if (uid != callingUid) {
8109                    throw new SecurityException("Invalid uid, expected " + uid);
8110                }
8111            } catch (NameNotFoundException e) {
8112                Log.d(TAG, "stopLockTaskMode " + e);
8113                return;
8114            }
8115        }
8116        long ident = Binder.clearCallingIdentity();
8117        try {
8118            Log.d(TAG, "stopLockTaskMode");
8119            // Stop lock task
8120            synchronized (this) {
8121                mStackSupervisor.setLockTaskModeLocked(null, false);
8122            }
8123        } finally {
8124            Binder.restoreCallingIdentity(ident);
8125        }
8126    }
8127
8128    @Override
8129    public void stopLockTaskModeOnCurrent() throws RemoteException {
8130        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8131        long ident = Binder.clearCallingIdentity();
8132        try {
8133            stopLockTaskMode();
8134        } finally {
8135            Binder.restoreCallingIdentity(ident);
8136        }
8137    }
8138
8139    @Override
8140    public boolean isInLockTaskMode() {
8141        synchronized (this) {
8142            return mStackSupervisor.isInLockTaskMode();
8143        }
8144    }
8145
8146    // =========================================================
8147    // CONTENT PROVIDERS
8148    // =========================================================
8149
8150    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8151        List<ProviderInfo> providers = null;
8152        try {
8153            providers = AppGlobals.getPackageManager().
8154                queryContentProviders(app.processName, app.uid,
8155                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8156        } catch (RemoteException ex) {
8157        }
8158        if (DEBUG_MU)
8159            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8160        int userId = app.userId;
8161        if (providers != null) {
8162            int N = providers.size();
8163            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8164            for (int i=0; i<N; i++) {
8165                ProviderInfo cpi =
8166                    (ProviderInfo)providers.get(i);
8167                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8168                        cpi.name, cpi.flags);
8169                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8170                    // This is a singleton provider, but a user besides the
8171                    // default user is asking to initialize a process it runs
8172                    // in...  well, no, it doesn't actually run in this process,
8173                    // it runs in the process of the default user.  Get rid of it.
8174                    providers.remove(i);
8175                    N--;
8176                    i--;
8177                    continue;
8178                }
8179
8180                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8181                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8182                if (cpr == null) {
8183                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8184                    mProviderMap.putProviderByClass(comp, cpr);
8185                }
8186                if (DEBUG_MU)
8187                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8188                app.pubProviders.put(cpi.name, cpr);
8189                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8190                    // Don't add this if it is a platform component that is marked
8191                    // to run in multiple processes, because this is actually
8192                    // part of the framework so doesn't make sense to track as a
8193                    // separate apk in the process.
8194                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8195                            mProcessStats);
8196                }
8197                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8198            }
8199        }
8200        return providers;
8201    }
8202
8203    /**
8204     * Check if {@link ProcessRecord} has a possible chance at accessing the
8205     * given {@link ProviderInfo}. Final permission checking is always done
8206     * in {@link ContentProvider}.
8207     */
8208    private final String checkContentProviderPermissionLocked(
8209            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8210        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8211        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8212        boolean checkedGrants = false;
8213        if (checkUser) {
8214            // Looking for cross-user grants before enforcing the typical cross-users permissions
8215            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8216            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8217                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8218                    return null;
8219                }
8220                checkedGrants = true;
8221            }
8222            userId = handleIncomingUser(callingPid, callingUid, userId,
8223                    false, ALLOW_NON_FULL,
8224                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8225            if (userId != tmpTargetUserId) {
8226                // When we actually went to determine the final targer user ID, this ended
8227                // up different than our initial check for the authority.  This is because
8228                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8229                // SELF.  So we need to re-check the grants again.
8230                checkedGrants = false;
8231            }
8232        }
8233        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8234                cpi.applicationInfo.uid, cpi.exported)
8235                == PackageManager.PERMISSION_GRANTED) {
8236            return null;
8237        }
8238        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8239                cpi.applicationInfo.uid, cpi.exported)
8240                == PackageManager.PERMISSION_GRANTED) {
8241            return null;
8242        }
8243
8244        PathPermission[] pps = cpi.pathPermissions;
8245        if (pps != null) {
8246            int i = pps.length;
8247            while (i > 0) {
8248                i--;
8249                PathPermission pp = pps[i];
8250                String pprperm = pp.getReadPermission();
8251                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8252                        cpi.applicationInfo.uid, cpi.exported)
8253                        == PackageManager.PERMISSION_GRANTED) {
8254                    return null;
8255                }
8256                String ppwperm = pp.getWritePermission();
8257                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8258                        cpi.applicationInfo.uid, cpi.exported)
8259                        == PackageManager.PERMISSION_GRANTED) {
8260                    return null;
8261                }
8262            }
8263        }
8264        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8265            return null;
8266        }
8267
8268        String msg;
8269        if (!cpi.exported) {
8270            msg = "Permission Denial: opening provider " + cpi.name
8271                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8272                    + ", uid=" + callingUid + ") that is not exported from uid "
8273                    + cpi.applicationInfo.uid;
8274        } else {
8275            msg = "Permission Denial: opening provider " + cpi.name
8276                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8277                    + ", uid=" + callingUid + ") requires "
8278                    + cpi.readPermission + " or " + cpi.writePermission;
8279        }
8280        Slog.w(TAG, msg);
8281        return msg;
8282    }
8283
8284    /**
8285     * Returns if the ContentProvider has granted a uri to callingUid
8286     */
8287    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8288        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8289        if (perms != null) {
8290            for (int i=perms.size()-1; i>=0; i--) {
8291                GrantUri grantUri = perms.keyAt(i);
8292                if (grantUri.sourceUserId == userId || !checkUser) {
8293                    if (matchesProvider(grantUri.uri, cpi)) {
8294                        return true;
8295                    }
8296                }
8297            }
8298        }
8299        return false;
8300    }
8301
8302    /**
8303     * Returns true if the uri authority is one of the authorities specified in the provider.
8304     */
8305    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8306        String uriAuth = uri.getAuthority();
8307        String cpiAuth = cpi.authority;
8308        if (cpiAuth.indexOf(';') == -1) {
8309            return cpiAuth.equals(uriAuth);
8310        }
8311        String[] cpiAuths = cpiAuth.split(";");
8312        int length = cpiAuths.length;
8313        for (int i = 0; i < length; i++) {
8314            if (cpiAuths[i].equals(uriAuth)) return true;
8315        }
8316        return false;
8317    }
8318
8319    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8320            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8321        if (r != null) {
8322            for (int i=0; i<r.conProviders.size(); i++) {
8323                ContentProviderConnection conn = r.conProviders.get(i);
8324                if (conn.provider == cpr) {
8325                    if (DEBUG_PROVIDER) Slog.v(TAG,
8326                            "Adding provider requested by "
8327                            + r.processName + " from process "
8328                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8329                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8330                    if (stable) {
8331                        conn.stableCount++;
8332                        conn.numStableIncs++;
8333                    } else {
8334                        conn.unstableCount++;
8335                        conn.numUnstableIncs++;
8336                    }
8337                    return conn;
8338                }
8339            }
8340            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8341            if (stable) {
8342                conn.stableCount = 1;
8343                conn.numStableIncs = 1;
8344            } else {
8345                conn.unstableCount = 1;
8346                conn.numUnstableIncs = 1;
8347            }
8348            cpr.connections.add(conn);
8349            r.conProviders.add(conn);
8350            return conn;
8351        }
8352        cpr.addExternalProcessHandleLocked(externalProcessToken);
8353        return null;
8354    }
8355
8356    boolean decProviderCountLocked(ContentProviderConnection conn,
8357            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8358        if (conn != null) {
8359            cpr = conn.provider;
8360            if (DEBUG_PROVIDER) Slog.v(TAG,
8361                    "Removing provider requested by "
8362                    + conn.client.processName + " from process "
8363                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8364                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8365            if (stable) {
8366                conn.stableCount--;
8367            } else {
8368                conn.unstableCount--;
8369            }
8370            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8371                cpr.connections.remove(conn);
8372                conn.client.conProviders.remove(conn);
8373                return true;
8374            }
8375            return false;
8376        }
8377        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8378        return false;
8379    }
8380
8381    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8382            String name, IBinder token, boolean stable, int userId) {
8383        ContentProviderRecord cpr;
8384        ContentProviderConnection conn = null;
8385        ProviderInfo cpi = null;
8386
8387        synchronized(this) {
8388            ProcessRecord r = null;
8389            if (caller != null) {
8390                r = getRecordForAppLocked(caller);
8391                if (r == null) {
8392                    throw new SecurityException(
8393                            "Unable to find app for caller " + caller
8394                          + " (pid=" + Binder.getCallingPid()
8395                          + ") when getting content provider " + name);
8396                }
8397            }
8398
8399            boolean checkCrossUser = true;
8400
8401            // First check if this content provider has been published...
8402            cpr = mProviderMap.getProviderByName(name, userId);
8403            // If that didn't work, check if it exists for user 0 and then
8404            // verify that it's a singleton provider before using it.
8405            if (cpr == null && userId != UserHandle.USER_OWNER) {
8406                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8407                if (cpr != null) {
8408                    cpi = cpr.info;
8409                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8410                            cpi.name, cpi.flags)
8411                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8412                        userId = UserHandle.USER_OWNER;
8413                        checkCrossUser = false;
8414                    } else {
8415                        cpr = null;
8416                        cpi = null;
8417                    }
8418                }
8419            }
8420
8421            boolean providerRunning = cpr != null;
8422            if (providerRunning) {
8423                cpi = cpr.info;
8424                String msg;
8425                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8426                        != null) {
8427                    throw new SecurityException(msg);
8428                }
8429
8430                if (r != null && cpr.canRunHere(r)) {
8431                    // This provider has been published or is in the process
8432                    // of being published...  but it is also allowed to run
8433                    // in the caller's process, so don't make a connection
8434                    // and just let the caller instantiate its own instance.
8435                    ContentProviderHolder holder = cpr.newHolder(null);
8436                    // don't give caller the provider object, it needs
8437                    // to make its own.
8438                    holder.provider = null;
8439                    return holder;
8440                }
8441
8442                final long origId = Binder.clearCallingIdentity();
8443
8444                // In this case the provider instance already exists, so we can
8445                // return it right away.
8446                conn = incProviderCountLocked(r, cpr, token, stable);
8447                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8448                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8449                        // If this is a perceptible app accessing the provider,
8450                        // make sure to count it as being accessed and thus
8451                        // back up on the LRU list.  This is good because
8452                        // content providers are often expensive to start.
8453                        updateLruProcessLocked(cpr.proc, false, null);
8454                    }
8455                }
8456
8457                if (cpr.proc != null) {
8458                    if (false) {
8459                        if (cpr.name.flattenToShortString().equals(
8460                                "com.android.providers.calendar/.CalendarProvider2")) {
8461                            Slog.v(TAG, "****************** KILLING "
8462                                + cpr.name.flattenToShortString());
8463                            Process.killProcess(cpr.proc.pid);
8464                        }
8465                    }
8466                    boolean success = updateOomAdjLocked(cpr.proc);
8467                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8468                    // NOTE: there is still a race here where a signal could be
8469                    // pending on the process even though we managed to update its
8470                    // adj level.  Not sure what to do about this, but at least
8471                    // the race is now smaller.
8472                    if (!success) {
8473                        // Uh oh...  it looks like the provider's process
8474                        // has been killed on us.  We need to wait for a new
8475                        // process to be started, and make sure its death
8476                        // doesn't kill our process.
8477                        Slog.i(TAG,
8478                                "Existing provider " + cpr.name.flattenToShortString()
8479                                + " is crashing; detaching " + r);
8480                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8481                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8482                        if (!lastRef) {
8483                            // This wasn't the last ref our process had on
8484                            // the provider...  we have now been killed, bail.
8485                            return null;
8486                        }
8487                        providerRunning = false;
8488                        conn = null;
8489                    }
8490                }
8491
8492                Binder.restoreCallingIdentity(origId);
8493            }
8494
8495            boolean singleton;
8496            if (!providerRunning) {
8497                try {
8498                    cpi = AppGlobals.getPackageManager().
8499                        resolveContentProvider(name,
8500                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8501                } catch (RemoteException ex) {
8502                }
8503                if (cpi == null) {
8504                    return null;
8505                }
8506                // If the provider is a singleton AND
8507                // (it's a call within the same user || the provider is a
8508                // privileged app)
8509                // Then allow connecting to the singleton provider
8510                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8511                        cpi.name, cpi.flags)
8512                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8513                if (singleton) {
8514                    userId = UserHandle.USER_OWNER;
8515                }
8516                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8517
8518                String msg;
8519                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8520                        != null) {
8521                    throw new SecurityException(msg);
8522                }
8523
8524                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8525                        && !cpi.processName.equals("system")) {
8526                    // If this content provider does not run in the system
8527                    // process, and the system is not yet ready to run other
8528                    // processes, then fail fast instead of hanging.
8529                    throw new IllegalArgumentException(
8530                            "Attempt to launch content provider before system ready");
8531                }
8532
8533                // Make sure that the user who owns this provider is started.  If not,
8534                // we don't want to allow it to run.
8535                if (mStartedUsers.get(userId) == null) {
8536                    Slog.w(TAG, "Unable to launch app "
8537                            + cpi.applicationInfo.packageName + "/"
8538                            + cpi.applicationInfo.uid + " for provider "
8539                            + name + ": user " + userId + " is stopped");
8540                    return null;
8541                }
8542
8543                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8544                cpr = mProviderMap.getProviderByClass(comp, userId);
8545                final boolean firstClass = cpr == null;
8546                if (firstClass) {
8547                    try {
8548                        ApplicationInfo ai =
8549                            AppGlobals.getPackageManager().
8550                                getApplicationInfo(
8551                                        cpi.applicationInfo.packageName,
8552                                        STOCK_PM_FLAGS, userId);
8553                        if (ai == null) {
8554                            Slog.w(TAG, "No package info for content provider "
8555                                    + cpi.name);
8556                            return null;
8557                        }
8558                        ai = getAppInfoForUser(ai, userId);
8559                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8560                    } catch (RemoteException ex) {
8561                        // pm is in same process, this will never happen.
8562                    }
8563                }
8564
8565                if (r != null && cpr.canRunHere(r)) {
8566                    // If this is a multiprocess provider, then just return its
8567                    // info and allow the caller to instantiate it.  Only do
8568                    // this if the provider is the same user as the caller's
8569                    // process, or can run as root (so can be in any process).
8570                    return cpr.newHolder(null);
8571                }
8572
8573                if (DEBUG_PROVIDER) {
8574                    RuntimeException e = new RuntimeException("here");
8575                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8576                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8577                }
8578
8579                // This is single process, and our app is now connecting to it.
8580                // See if we are already in the process of launching this
8581                // provider.
8582                final int N = mLaunchingProviders.size();
8583                int i;
8584                for (i=0; i<N; i++) {
8585                    if (mLaunchingProviders.get(i) == cpr) {
8586                        break;
8587                    }
8588                }
8589
8590                // If the provider is not already being launched, then get it
8591                // started.
8592                if (i >= N) {
8593                    final long origId = Binder.clearCallingIdentity();
8594
8595                    try {
8596                        // Content provider is now in use, its package can't be stopped.
8597                        try {
8598                            AppGlobals.getPackageManager().setPackageStoppedState(
8599                                    cpr.appInfo.packageName, false, userId);
8600                        } catch (RemoteException e) {
8601                        } catch (IllegalArgumentException e) {
8602                            Slog.w(TAG, "Failed trying to unstop package "
8603                                    + cpr.appInfo.packageName + ": " + e);
8604                        }
8605
8606                        // Use existing process if already started
8607                        ProcessRecord proc = getProcessRecordLocked(
8608                                cpi.processName, cpr.appInfo.uid, false);
8609                        if (proc != null && proc.thread != null) {
8610                            if (DEBUG_PROVIDER) {
8611                                Slog.d(TAG, "Installing in existing process " + proc);
8612                            }
8613                            proc.pubProviders.put(cpi.name, cpr);
8614                            try {
8615                                proc.thread.scheduleInstallProvider(cpi);
8616                            } catch (RemoteException e) {
8617                            }
8618                        } else {
8619                            proc = startProcessLocked(cpi.processName,
8620                                    cpr.appInfo, false, 0, "content provider",
8621                                    new ComponentName(cpi.applicationInfo.packageName,
8622                                            cpi.name), false, false, false);
8623                            if (proc == null) {
8624                                Slog.w(TAG, "Unable to launch app "
8625                                        + cpi.applicationInfo.packageName + "/"
8626                                        + cpi.applicationInfo.uid + " for provider "
8627                                        + name + ": process is bad");
8628                                return null;
8629                            }
8630                        }
8631                        cpr.launchingApp = proc;
8632                        mLaunchingProviders.add(cpr);
8633                    } finally {
8634                        Binder.restoreCallingIdentity(origId);
8635                    }
8636                }
8637
8638                // Make sure the provider is published (the same provider class
8639                // may be published under multiple names).
8640                if (firstClass) {
8641                    mProviderMap.putProviderByClass(comp, cpr);
8642                }
8643
8644                mProviderMap.putProviderByName(name, cpr);
8645                conn = incProviderCountLocked(r, cpr, token, stable);
8646                if (conn != null) {
8647                    conn.waiting = true;
8648                }
8649            }
8650        }
8651
8652        // Wait for the provider to be published...
8653        synchronized (cpr) {
8654            while (cpr.provider == null) {
8655                if (cpr.launchingApp == null) {
8656                    Slog.w(TAG, "Unable to launch app "
8657                            + cpi.applicationInfo.packageName + "/"
8658                            + cpi.applicationInfo.uid + " for provider "
8659                            + name + ": launching app became null");
8660                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8661                            UserHandle.getUserId(cpi.applicationInfo.uid),
8662                            cpi.applicationInfo.packageName,
8663                            cpi.applicationInfo.uid, name);
8664                    return null;
8665                }
8666                try {
8667                    if (DEBUG_MU) {
8668                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8669                                + cpr.launchingApp);
8670                    }
8671                    if (conn != null) {
8672                        conn.waiting = true;
8673                    }
8674                    cpr.wait();
8675                } catch (InterruptedException ex) {
8676                } finally {
8677                    if (conn != null) {
8678                        conn.waiting = false;
8679                    }
8680                }
8681            }
8682        }
8683        return cpr != null ? cpr.newHolder(conn) : null;
8684    }
8685
8686    @Override
8687    public final ContentProviderHolder getContentProvider(
8688            IApplicationThread caller, String name, int userId, boolean stable) {
8689        enforceNotIsolatedCaller("getContentProvider");
8690        if (caller == null) {
8691            String msg = "null IApplicationThread when getting content provider "
8692                    + name;
8693            Slog.w(TAG, msg);
8694            throw new SecurityException(msg);
8695        }
8696        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8697        // with cross-user grant.
8698        return getContentProviderImpl(caller, name, null, stable, userId);
8699    }
8700
8701    public ContentProviderHolder getContentProviderExternal(
8702            String name, int userId, IBinder token) {
8703        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8704            "Do not have permission in call getContentProviderExternal()");
8705        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8706                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8707        return getContentProviderExternalUnchecked(name, token, userId);
8708    }
8709
8710    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8711            IBinder token, int userId) {
8712        return getContentProviderImpl(null, name, token, true, userId);
8713    }
8714
8715    /**
8716     * Drop a content provider from a ProcessRecord's bookkeeping
8717     */
8718    public void removeContentProvider(IBinder connection, boolean stable) {
8719        enforceNotIsolatedCaller("removeContentProvider");
8720        long ident = Binder.clearCallingIdentity();
8721        try {
8722            synchronized (this) {
8723                ContentProviderConnection conn;
8724                try {
8725                    conn = (ContentProviderConnection)connection;
8726                } catch (ClassCastException e) {
8727                    String msg ="removeContentProvider: " + connection
8728                            + " not a ContentProviderConnection";
8729                    Slog.w(TAG, msg);
8730                    throw new IllegalArgumentException(msg);
8731                }
8732                if (conn == null) {
8733                    throw new NullPointerException("connection is null");
8734                }
8735                if (decProviderCountLocked(conn, null, null, stable)) {
8736                    updateOomAdjLocked();
8737                }
8738            }
8739        } finally {
8740            Binder.restoreCallingIdentity(ident);
8741        }
8742    }
8743
8744    public void removeContentProviderExternal(String name, IBinder token) {
8745        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8746            "Do not have permission in call removeContentProviderExternal()");
8747        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8748    }
8749
8750    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8751        synchronized (this) {
8752            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8753            if(cpr == null) {
8754                //remove from mProvidersByClass
8755                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8756                return;
8757            }
8758
8759            //update content provider record entry info
8760            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8761            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8762            if (localCpr.hasExternalProcessHandles()) {
8763                if (localCpr.removeExternalProcessHandleLocked(token)) {
8764                    updateOomAdjLocked();
8765                } else {
8766                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8767                            + " with no external reference for token: "
8768                            + token + ".");
8769                }
8770            } else {
8771                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8772                        + " with no external references.");
8773            }
8774        }
8775    }
8776
8777    public final void publishContentProviders(IApplicationThread caller,
8778            List<ContentProviderHolder> providers) {
8779        if (providers == null) {
8780            return;
8781        }
8782
8783        enforceNotIsolatedCaller("publishContentProviders");
8784        synchronized (this) {
8785            final ProcessRecord r = getRecordForAppLocked(caller);
8786            if (DEBUG_MU)
8787                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8788            if (r == null) {
8789                throw new SecurityException(
8790                        "Unable to find app for caller " + caller
8791                      + " (pid=" + Binder.getCallingPid()
8792                      + ") when publishing content providers");
8793            }
8794
8795            final long origId = Binder.clearCallingIdentity();
8796
8797            final int N = providers.size();
8798            for (int i=0; i<N; i++) {
8799                ContentProviderHolder src = providers.get(i);
8800                if (src == null || src.info == null || src.provider == null) {
8801                    continue;
8802                }
8803                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8804                if (DEBUG_MU)
8805                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8806                if (dst != null) {
8807                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8808                    mProviderMap.putProviderByClass(comp, dst);
8809                    String names[] = dst.info.authority.split(";");
8810                    for (int j = 0; j < names.length; j++) {
8811                        mProviderMap.putProviderByName(names[j], dst);
8812                    }
8813
8814                    int NL = mLaunchingProviders.size();
8815                    int j;
8816                    for (j=0; j<NL; j++) {
8817                        if (mLaunchingProviders.get(j) == dst) {
8818                            mLaunchingProviders.remove(j);
8819                            j--;
8820                            NL--;
8821                        }
8822                    }
8823                    synchronized (dst) {
8824                        dst.provider = src.provider;
8825                        dst.proc = r;
8826                        dst.notifyAll();
8827                    }
8828                    updateOomAdjLocked(r);
8829                }
8830            }
8831
8832            Binder.restoreCallingIdentity(origId);
8833        }
8834    }
8835
8836    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8837        ContentProviderConnection conn;
8838        try {
8839            conn = (ContentProviderConnection)connection;
8840        } catch (ClassCastException e) {
8841            String msg ="refContentProvider: " + connection
8842                    + " not a ContentProviderConnection";
8843            Slog.w(TAG, msg);
8844            throw new IllegalArgumentException(msg);
8845        }
8846        if (conn == null) {
8847            throw new NullPointerException("connection is null");
8848        }
8849
8850        synchronized (this) {
8851            if (stable > 0) {
8852                conn.numStableIncs += stable;
8853            }
8854            stable = conn.stableCount + stable;
8855            if (stable < 0) {
8856                throw new IllegalStateException("stableCount < 0: " + stable);
8857            }
8858
8859            if (unstable > 0) {
8860                conn.numUnstableIncs += unstable;
8861            }
8862            unstable = conn.unstableCount + unstable;
8863            if (unstable < 0) {
8864                throw new IllegalStateException("unstableCount < 0: " + unstable);
8865            }
8866
8867            if ((stable+unstable) <= 0) {
8868                throw new IllegalStateException("ref counts can't go to zero here: stable="
8869                        + stable + " unstable=" + unstable);
8870            }
8871            conn.stableCount = stable;
8872            conn.unstableCount = unstable;
8873            return !conn.dead;
8874        }
8875    }
8876
8877    public void unstableProviderDied(IBinder connection) {
8878        ContentProviderConnection conn;
8879        try {
8880            conn = (ContentProviderConnection)connection;
8881        } catch (ClassCastException e) {
8882            String msg ="refContentProvider: " + connection
8883                    + " not a ContentProviderConnection";
8884            Slog.w(TAG, msg);
8885            throw new IllegalArgumentException(msg);
8886        }
8887        if (conn == null) {
8888            throw new NullPointerException("connection is null");
8889        }
8890
8891        // Safely retrieve the content provider associated with the connection.
8892        IContentProvider provider;
8893        synchronized (this) {
8894            provider = conn.provider.provider;
8895        }
8896
8897        if (provider == null) {
8898            // Um, yeah, we're way ahead of you.
8899            return;
8900        }
8901
8902        // Make sure the caller is being honest with us.
8903        if (provider.asBinder().pingBinder()) {
8904            // Er, no, still looks good to us.
8905            synchronized (this) {
8906                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8907                        + " says " + conn + " died, but we don't agree");
8908                return;
8909            }
8910        }
8911
8912        // Well look at that!  It's dead!
8913        synchronized (this) {
8914            if (conn.provider.provider != provider) {
8915                // But something changed...  good enough.
8916                return;
8917            }
8918
8919            ProcessRecord proc = conn.provider.proc;
8920            if (proc == null || proc.thread == null) {
8921                // Seems like the process is already cleaned up.
8922                return;
8923            }
8924
8925            // As far as we're concerned, this is just like receiving a
8926            // death notification...  just a bit prematurely.
8927            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8928                    + ") early provider death");
8929            final long ident = Binder.clearCallingIdentity();
8930            try {
8931                appDiedLocked(proc, proc.pid, proc.thread);
8932            } finally {
8933                Binder.restoreCallingIdentity(ident);
8934            }
8935        }
8936    }
8937
8938    @Override
8939    public void appNotRespondingViaProvider(IBinder connection) {
8940        enforceCallingPermission(
8941                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8942
8943        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8944        if (conn == null) {
8945            Slog.w(TAG, "ContentProviderConnection is null");
8946            return;
8947        }
8948
8949        final ProcessRecord host = conn.provider.proc;
8950        if (host == null) {
8951            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8952            return;
8953        }
8954
8955        final long token = Binder.clearCallingIdentity();
8956        try {
8957            appNotResponding(host, null, null, false, "ContentProvider not responding");
8958        } finally {
8959            Binder.restoreCallingIdentity(token);
8960        }
8961    }
8962
8963    public final void installSystemProviders() {
8964        List<ProviderInfo> providers;
8965        synchronized (this) {
8966            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8967            providers = generateApplicationProvidersLocked(app);
8968            if (providers != null) {
8969                for (int i=providers.size()-1; i>=0; i--) {
8970                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8971                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8972                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8973                                + ": not system .apk");
8974                        providers.remove(i);
8975                    }
8976                }
8977            }
8978        }
8979        if (providers != null) {
8980            mSystemThread.installSystemProviders(providers);
8981        }
8982
8983        mCoreSettingsObserver = new CoreSettingsObserver(this);
8984
8985        //mUsageStatsService.monitorPackages();
8986    }
8987
8988    /**
8989     * Allows apps to retrieve the MIME type of a URI.
8990     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
8991     * users, then it does not need permission to access the ContentProvider.
8992     * Either, it needs cross-user uri grants.
8993     *
8994     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8995     *
8996     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8997     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8998     */
8999    public String getProviderMimeType(Uri uri, int userId) {
9000        enforceNotIsolatedCaller("getProviderMimeType");
9001        final String name = uri.getAuthority();
9002        int callingUid = Binder.getCallingUid();
9003        int callingPid = Binder.getCallingPid();
9004        long ident = 0;
9005        boolean clearedIdentity = false;
9006        userId = unsafeConvertIncomingUser(userId);
9007        if (UserHandle.getUserId(callingUid) != userId) {
9008            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9009                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9010                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9011                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9012                clearedIdentity = true;
9013                ident = Binder.clearCallingIdentity();
9014            }
9015        }
9016        ContentProviderHolder holder = null;
9017        try {
9018            holder = getContentProviderExternalUnchecked(name, null, userId);
9019            if (holder != null) {
9020                return holder.provider.getType(uri);
9021            }
9022        } catch (RemoteException e) {
9023            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9024            return null;
9025        } finally {
9026            // We need to clear the identity to call removeContentProviderExternalUnchecked
9027            if (!clearedIdentity) {
9028                ident = Binder.clearCallingIdentity();
9029            }
9030            try {
9031                if (holder != null) {
9032                    removeContentProviderExternalUnchecked(name, null, userId);
9033                }
9034            } finally {
9035                Binder.restoreCallingIdentity(ident);
9036            }
9037        }
9038
9039        return null;
9040    }
9041
9042    // =========================================================
9043    // GLOBAL MANAGEMENT
9044    // =========================================================
9045
9046    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9047            boolean isolated, int isolatedUid) {
9048        String proc = customProcess != null ? customProcess : info.processName;
9049        BatteryStatsImpl.Uid.Proc ps = null;
9050        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9051        int uid = info.uid;
9052        if (isolated) {
9053            if (isolatedUid == 0) {
9054                int userId = UserHandle.getUserId(uid);
9055                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9056                while (true) {
9057                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9058                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9059                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9060                    }
9061                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9062                    mNextIsolatedProcessUid++;
9063                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9064                        // No process for this uid, use it.
9065                        break;
9066                    }
9067                    stepsLeft--;
9068                    if (stepsLeft <= 0) {
9069                        return null;
9070                    }
9071                }
9072            } else {
9073                // Special case for startIsolatedProcess (internal only), where
9074                // the uid of the isolated process is specified by the caller.
9075                uid = isolatedUid;
9076            }
9077        }
9078        return new ProcessRecord(stats, info, proc, uid);
9079    }
9080
9081    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9082            String abiOverride) {
9083        ProcessRecord app;
9084        if (!isolated) {
9085            app = getProcessRecordLocked(info.processName, info.uid, true);
9086        } else {
9087            app = null;
9088        }
9089
9090        if (app == null) {
9091            app = newProcessRecordLocked(info, null, isolated, 0);
9092            mProcessNames.put(info.processName, app.uid, app);
9093            if (isolated) {
9094                mIsolatedProcesses.put(app.uid, app);
9095            }
9096            updateLruProcessLocked(app, false, null);
9097            updateOomAdjLocked();
9098        }
9099
9100        // This package really, really can not be stopped.
9101        try {
9102            AppGlobals.getPackageManager().setPackageStoppedState(
9103                    info.packageName, false, UserHandle.getUserId(app.uid));
9104        } catch (RemoteException e) {
9105        } catch (IllegalArgumentException e) {
9106            Slog.w(TAG, "Failed trying to unstop package "
9107                    + info.packageName + ": " + e);
9108        }
9109
9110        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9111                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9112            app.persistent = true;
9113            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9114        }
9115        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9116            mPersistentStartingProcesses.add(app);
9117            startProcessLocked(app, "added application", app.processName, abiOverride,
9118                    null /* entryPoint */, null /* entryPointArgs */);
9119        }
9120
9121        return app;
9122    }
9123
9124    public void unhandledBack() {
9125        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9126                "unhandledBack()");
9127
9128        synchronized(this) {
9129            final long origId = Binder.clearCallingIdentity();
9130            try {
9131                getFocusedStack().unhandledBackLocked();
9132            } finally {
9133                Binder.restoreCallingIdentity(origId);
9134            }
9135        }
9136    }
9137
9138    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9139        enforceNotIsolatedCaller("openContentUri");
9140        final int userId = UserHandle.getCallingUserId();
9141        String name = uri.getAuthority();
9142        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9143        ParcelFileDescriptor pfd = null;
9144        if (cph != null) {
9145            // We record the binder invoker's uid in thread-local storage before
9146            // going to the content provider to open the file.  Later, in the code
9147            // that handles all permissions checks, we look for this uid and use
9148            // that rather than the Activity Manager's own uid.  The effect is that
9149            // we do the check against the caller's permissions even though it looks
9150            // to the content provider like the Activity Manager itself is making
9151            // the request.
9152            sCallerIdentity.set(new Identity(
9153                    Binder.getCallingPid(), Binder.getCallingUid()));
9154            try {
9155                pfd = cph.provider.openFile(null, uri, "r", null);
9156            } catch (FileNotFoundException e) {
9157                // do nothing; pfd will be returned null
9158            } finally {
9159                // Ensure that whatever happens, we clean up the identity state
9160                sCallerIdentity.remove();
9161            }
9162
9163            // We've got the fd now, so we're done with the provider.
9164            removeContentProviderExternalUnchecked(name, null, userId);
9165        } else {
9166            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9167        }
9168        return pfd;
9169    }
9170
9171    // Actually is sleeping or shutting down or whatever else in the future
9172    // is an inactive state.
9173    public boolean isSleepingOrShuttingDown() {
9174        return mSleeping || mShuttingDown;
9175    }
9176
9177    public boolean isSleeping() {
9178        return mSleeping;
9179    }
9180
9181    void goingToSleep() {
9182        synchronized(this) {
9183            mWentToSleep = true;
9184            updateEventDispatchingLocked();
9185            goToSleepIfNeededLocked();
9186        }
9187    }
9188
9189    void finishRunningVoiceLocked() {
9190        if (mRunningVoice) {
9191            mRunningVoice = false;
9192            goToSleepIfNeededLocked();
9193        }
9194    }
9195
9196    void goToSleepIfNeededLocked() {
9197        if (mWentToSleep && !mRunningVoice) {
9198            if (!mSleeping) {
9199                mSleeping = true;
9200                mStackSupervisor.goingToSleepLocked();
9201
9202                // Initialize the wake times of all processes.
9203                checkExcessivePowerUsageLocked(false);
9204                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9205                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9206                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9207            }
9208        }
9209    }
9210
9211    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9212        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9213            // Never persist the home stack.
9214            return;
9215        }
9216        mTaskPersister.wakeup(task, flush);
9217    }
9218
9219    @Override
9220    public boolean shutdown(int timeout) {
9221        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9222                != PackageManager.PERMISSION_GRANTED) {
9223            throw new SecurityException("Requires permission "
9224                    + android.Manifest.permission.SHUTDOWN);
9225        }
9226
9227        boolean timedout = false;
9228
9229        synchronized(this) {
9230            mShuttingDown = true;
9231            updateEventDispatchingLocked();
9232            timedout = mStackSupervisor.shutdownLocked(timeout);
9233        }
9234
9235        mAppOpsService.shutdown();
9236        if (mUsageStatsService != null) {
9237            mUsageStatsService.prepareShutdown();
9238        }
9239        mBatteryStatsService.shutdown();
9240        synchronized (this) {
9241            mProcessStats.shutdownLocked();
9242        }
9243        notifyTaskPersisterLocked(null, true);
9244
9245        return timedout;
9246    }
9247
9248    public final void activitySlept(IBinder token) {
9249        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9250
9251        final long origId = Binder.clearCallingIdentity();
9252
9253        synchronized (this) {
9254            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9255            if (r != null) {
9256                mStackSupervisor.activitySleptLocked(r);
9257            }
9258        }
9259
9260        Binder.restoreCallingIdentity(origId);
9261    }
9262
9263    void logLockScreen(String msg) {
9264        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9265                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9266                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9267                mStackSupervisor.mDismissKeyguardOnNextActivity);
9268    }
9269
9270    private void comeOutOfSleepIfNeededLocked() {
9271        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9272            if (mSleeping) {
9273                mSleeping = false;
9274                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9275            }
9276        }
9277    }
9278
9279    void wakingUp() {
9280        synchronized(this) {
9281            mWentToSleep = false;
9282            updateEventDispatchingLocked();
9283            comeOutOfSleepIfNeededLocked();
9284        }
9285    }
9286
9287    void startRunningVoiceLocked() {
9288        if (!mRunningVoice) {
9289            mRunningVoice = true;
9290            comeOutOfSleepIfNeededLocked();
9291        }
9292    }
9293
9294    private void updateEventDispatchingLocked() {
9295        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9296    }
9297
9298    public void setLockScreenShown(boolean shown) {
9299        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9300                != PackageManager.PERMISSION_GRANTED) {
9301            throw new SecurityException("Requires permission "
9302                    + android.Manifest.permission.DEVICE_POWER);
9303        }
9304
9305        synchronized(this) {
9306            long ident = Binder.clearCallingIdentity();
9307            try {
9308                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9309                mLockScreenShown = shown;
9310                comeOutOfSleepIfNeededLocked();
9311            } finally {
9312                Binder.restoreCallingIdentity(ident);
9313            }
9314        }
9315    }
9316
9317    @Override
9318    public void stopAppSwitches() {
9319        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9320                != PackageManager.PERMISSION_GRANTED) {
9321            throw new SecurityException("Requires permission "
9322                    + android.Manifest.permission.STOP_APP_SWITCHES);
9323        }
9324
9325        synchronized(this) {
9326            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9327                    + APP_SWITCH_DELAY_TIME;
9328            mDidAppSwitch = false;
9329            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9330            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9331            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9332        }
9333    }
9334
9335    public void resumeAppSwitches() {
9336        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9337                != PackageManager.PERMISSION_GRANTED) {
9338            throw new SecurityException("Requires permission "
9339                    + android.Manifest.permission.STOP_APP_SWITCHES);
9340        }
9341
9342        synchronized(this) {
9343            // Note that we don't execute any pending app switches... we will
9344            // let those wait until either the timeout, or the next start
9345            // activity request.
9346            mAppSwitchesAllowedTime = 0;
9347        }
9348    }
9349
9350    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9351            String name) {
9352        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9353            return true;
9354        }
9355
9356        final int perm = checkComponentPermission(
9357                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9358                callingUid, -1, true);
9359        if (perm == PackageManager.PERMISSION_GRANTED) {
9360            return true;
9361        }
9362
9363        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9364        return false;
9365    }
9366
9367    public void setDebugApp(String packageName, boolean waitForDebugger,
9368            boolean persistent) {
9369        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9370                "setDebugApp()");
9371
9372        long ident = Binder.clearCallingIdentity();
9373        try {
9374            // Note that this is not really thread safe if there are multiple
9375            // callers into it at the same time, but that's not a situation we
9376            // care about.
9377            if (persistent) {
9378                final ContentResolver resolver = mContext.getContentResolver();
9379                Settings.Global.putString(
9380                    resolver, Settings.Global.DEBUG_APP,
9381                    packageName);
9382                Settings.Global.putInt(
9383                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9384                    waitForDebugger ? 1 : 0);
9385            }
9386
9387            synchronized (this) {
9388                if (!persistent) {
9389                    mOrigDebugApp = mDebugApp;
9390                    mOrigWaitForDebugger = mWaitForDebugger;
9391                }
9392                mDebugApp = packageName;
9393                mWaitForDebugger = waitForDebugger;
9394                mDebugTransient = !persistent;
9395                if (packageName != null) {
9396                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9397                            false, UserHandle.USER_ALL, "set debug app");
9398                }
9399            }
9400        } finally {
9401            Binder.restoreCallingIdentity(ident);
9402        }
9403    }
9404
9405    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9406        synchronized (this) {
9407            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9408            if (!isDebuggable) {
9409                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9410                    throw new SecurityException("Process not debuggable: " + app.packageName);
9411                }
9412            }
9413
9414            mOpenGlTraceApp = processName;
9415        }
9416    }
9417
9418    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9419            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9420        synchronized (this) {
9421            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9422            if (!isDebuggable) {
9423                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9424                    throw new SecurityException("Process not debuggable: " + app.packageName);
9425                }
9426            }
9427            mProfileApp = processName;
9428            mProfileFile = profileFile;
9429            if (mProfileFd != null) {
9430                try {
9431                    mProfileFd.close();
9432                } catch (IOException e) {
9433                }
9434                mProfileFd = null;
9435            }
9436            mProfileFd = profileFd;
9437            mProfileType = 0;
9438            mAutoStopProfiler = autoStopProfiler;
9439        }
9440    }
9441
9442    @Override
9443    public void setAlwaysFinish(boolean enabled) {
9444        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9445                "setAlwaysFinish()");
9446
9447        Settings.Global.putInt(
9448                mContext.getContentResolver(),
9449                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9450
9451        synchronized (this) {
9452            mAlwaysFinishActivities = enabled;
9453        }
9454    }
9455
9456    @Override
9457    public void setActivityController(IActivityController controller) {
9458        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9459                "setActivityController()");
9460        synchronized (this) {
9461            mController = controller;
9462            Watchdog.getInstance().setActivityController(controller);
9463        }
9464    }
9465
9466    @Override
9467    public void setUserIsMonkey(boolean userIsMonkey) {
9468        synchronized (this) {
9469            synchronized (mPidsSelfLocked) {
9470                final int callingPid = Binder.getCallingPid();
9471                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9472                if (precessRecord == null) {
9473                    throw new SecurityException("Unknown process: " + callingPid);
9474                }
9475                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9476                    throw new SecurityException("Only an instrumentation process "
9477                            + "with a UiAutomation can call setUserIsMonkey");
9478                }
9479            }
9480            mUserIsMonkey = userIsMonkey;
9481        }
9482    }
9483
9484    @Override
9485    public boolean isUserAMonkey() {
9486        synchronized (this) {
9487            // If there is a controller also implies the user is a monkey.
9488            return (mUserIsMonkey || mController != null);
9489        }
9490    }
9491
9492    public void requestBugReport() {
9493        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9494        SystemProperties.set("ctl.start", "bugreport");
9495    }
9496
9497    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9498        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9499    }
9500
9501    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9502        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9503            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9504        }
9505        return KEY_DISPATCHING_TIMEOUT;
9506    }
9507
9508    @Override
9509    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9510        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9511                != PackageManager.PERMISSION_GRANTED) {
9512            throw new SecurityException("Requires permission "
9513                    + android.Manifest.permission.FILTER_EVENTS);
9514        }
9515        ProcessRecord proc;
9516        long timeout;
9517        synchronized (this) {
9518            synchronized (mPidsSelfLocked) {
9519                proc = mPidsSelfLocked.get(pid);
9520            }
9521            timeout = getInputDispatchingTimeoutLocked(proc);
9522        }
9523
9524        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9525            return -1;
9526        }
9527
9528        return timeout;
9529    }
9530
9531    /**
9532     * Handle input dispatching timeouts.
9533     * Returns whether input dispatching should be aborted or not.
9534     */
9535    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9536            final ActivityRecord activity, final ActivityRecord parent,
9537            final boolean aboveSystem, String reason) {
9538        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9539                != PackageManager.PERMISSION_GRANTED) {
9540            throw new SecurityException("Requires permission "
9541                    + android.Manifest.permission.FILTER_EVENTS);
9542        }
9543
9544        final String annotation;
9545        if (reason == null) {
9546            annotation = "Input dispatching timed out";
9547        } else {
9548            annotation = "Input dispatching timed out (" + reason + ")";
9549        }
9550
9551        if (proc != null) {
9552            synchronized (this) {
9553                if (proc.debugging) {
9554                    return false;
9555                }
9556
9557                if (mDidDexOpt) {
9558                    // Give more time since we were dexopting.
9559                    mDidDexOpt = false;
9560                    return false;
9561                }
9562
9563                if (proc.instrumentationClass != null) {
9564                    Bundle info = new Bundle();
9565                    info.putString("shortMsg", "keyDispatchingTimedOut");
9566                    info.putString("longMsg", annotation);
9567                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9568                    return true;
9569                }
9570            }
9571            mHandler.post(new Runnable() {
9572                @Override
9573                public void run() {
9574                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9575                }
9576            });
9577        }
9578
9579        return true;
9580    }
9581
9582    public Bundle getAssistContextExtras(int requestType) {
9583        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9584                "getAssistContextExtras()");
9585        PendingAssistExtras pae;
9586        Bundle extras = new Bundle();
9587        synchronized (this) {
9588            ActivityRecord activity = getFocusedStack().mResumedActivity;
9589            if (activity == null) {
9590                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9591                return null;
9592            }
9593            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9594            if (activity.app == null || activity.app.thread == null) {
9595                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9596                return extras;
9597            }
9598            if (activity.app.pid == Binder.getCallingPid()) {
9599                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9600                return extras;
9601            }
9602            pae = new PendingAssistExtras(activity);
9603            try {
9604                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9605                        requestType);
9606                mPendingAssistExtras.add(pae);
9607                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9608            } catch (RemoteException e) {
9609                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9610                return extras;
9611            }
9612        }
9613        synchronized (pae) {
9614            while (!pae.haveResult) {
9615                try {
9616                    pae.wait();
9617                } catch (InterruptedException e) {
9618                }
9619            }
9620            if (pae.result != null) {
9621                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9622            }
9623        }
9624        synchronized (this) {
9625            mPendingAssistExtras.remove(pae);
9626            mHandler.removeCallbacks(pae);
9627        }
9628        return extras;
9629    }
9630
9631    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9632        PendingAssistExtras pae = (PendingAssistExtras)token;
9633        synchronized (pae) {
9634            pae.result = extras;
9635            pae.haveResult = true;
9636            pae.notifyAll();
9637        }
9638    }
9639
9640    public void registerProcessObserver(IProcessObserver observer) {
9641        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9642                "registerProcessObserver()");
9643        synchronized (this) {
9644            mProcessObservers.register(observer);
9645        }
9646    }
9647
9648    @Override
9649    public void unregisterProcessObserver(IProcessObserver observer) {
9650        synchronized (this) {
9651            mProcessObservers.unregister(observer);
9652        }
9653    }
9654
9655    @Override
9656    public boolean convertFromTranslucent(IBinder token) {
9657        final long origId = Binder.clearCallingIdentity();
9658        try {
9659            synchronized (this) {
9660                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9661                if (r == null) {
9662                    return false;
9663                }
9664                if (r.changeWindowTranslucency(true)) {
9665                    mWindowManager.setAppFullscreen(token, true);
9666                    r.task.stack.releaseMediaResources();
9667                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9668                    return true;
9669                }
9670                return false;
9671            }
9672        } finally {
9673            Binder.restoreCallingIdentity(origId);
9674        }
9675    }
9676
9677    @Override
9678    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9679        final long origId = Binder.clearCallingIdentity();
9680        try {
9681            synchronized (this) {
9682                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9683                if (r == null) {
9684                    return false;
9685                }
9686                int index = r.task.mActivities.lastIndexOf(r);
9687                if (index > 0) {
9688                    ActivityRecord under = r.task.mActivities.get(index - 1);
9689                    under.returningOptions = options;
9690                }
9691                if (r.changeWindowTranslucency(false)) {
9692                    r.task.stack.convertToTranslucent(r);
9693                    mWindowManager.setAppFullscreen(token, false);
9694                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9695                    return true;
9696                } else {
9697                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9698                    return false;
9699                }
9700            }
9701        } finally {
9702            Binder.restoreCallingIdentity(origId);
9703        }
9704    }
9705
9706    @Override
9707    public boolean setMediaPlaying(IBinder token, boolean playing) {
9708        final long origId = Binder.clearCallingIdentity();
9709        try {
9710            synchronized (this) {
9711                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9712                if (r != null) {
9713                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9714                }
9715            }
9716            return false;
9717        } finally {
9718            Binder.restoreCallingIdentity(origId);
9719        }
9720    }
9721
9722    @Override
9723    public boolean isBackgroundMediaPlaying(IBinder token) {
9724        final long origId = Binder.clearCallingIdentity();
9725        try {
9726            synchronized (this) {
9727                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9728                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9729                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9730                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9731                return playing;
9732            }
9733        } finally {
9734            Binder.restoreCallingIdentity(origId);
9735        }
9736    }
9737
9738    @Override
9739    public ActivityOptions getActivityOptions(IBinder token) {
9740        final long origId = Binder.clearCallingIdentity();
9741        try {
9742            synchronized (this) {
9743                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9744                if (r != null) {
9745                    final ActivityOptions activityOptions = r.pendingOptions;
9746                    r.pendingOptions = null;
9747                    return activityOptions;
9748                }
9749                return null;
9750            }
9751        } finally {
9752            Binder.restoreCallingIdentity(origId);
9753        }
9754    }
9755
9756    @Override
9757    public void setImmersive(IBinder token, boolean immersive) {
9758        synchronized(this) {
9759            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9760            if (r == null) {
9761                throw new IllegalArgumentException();
9762            }
9763            r.immersive = immersive;
9764
9765            // update associated state if we're frontmost
9766            if (r == mFocusedActivity) {
9767                if (DEBUG_IMMERSIVE) {
9768                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9769                }
9770                applyUpdateLockStateLocked(r);
9771            }
9772        }
9773    }
9774
9775    @Override
9776    public boolean isImmersive(IBinder token) {
9777        synchronized (this) {
9778            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9779            if (r == null) {
9780                throw new IllegalArgumentException();
9781            }
9782            return r.immersive;
9783        }
9784    }
9785
9786    public boolean isTopActivityImmersive() {
9787        enforceNotIsolatedCaller("startActivity");
9788        synchronized (this) {
9789            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9790            return (r != null) ? r.immersive : false;
9791        }
9792    }
9793
9794    @Override
9795    public boolean isTopOfTask(IBinder token) {
9796        synchronized (this) {
9797            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9798            if (r == null) {
9799                throw new IllegalArgumentException();
9800            }
9801            return r.task.getTopActivity() == r;
9802        }
9803    }
9804
9805    public final void enterSafeMode() {
9806        synchronized(this) {
9807            // It only makes sense to do this before the system is ready
9808            // and started launching other packages.
9809            if (!mSystemReady) {
9810                try {
9811                    AppGlobals.getPackageManager().enterSafeMode();
9812                } catch (RemoteException e) {
9813                }
9814            }
9815
9816            mSafeMode = true;
9817        }
9818    }
9819
9820    public final void showSafeModeOverlay() {
9821        View v = LayoutInflater.from(mContext).inflate(
9822                com.android.internal.R.layout.safe_mode, null);
9823        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9824        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9825        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9826        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9827        lp.gravity = Gravity.BOTTOM | Gravity.START;
9828        lp.format = v.getBackground().getOpacity();
9829        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9830                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9831        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9832        ((WindowManager)mContext.getSystemService(
9833                Context.WINDOW_SERVICE)).addView(v, lp);
9834    }
9835
9836    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9837        if (!(sender instanceof PendingIntentRecord)) {
9838            return;
9839        }
9840        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9841        synchronized (stats) {
9842            if (mBatteryStatsService.isOnBattery()) {
9843                mBatteryStatsService.enforceCallingPermission();
9844                PendingIntentRecord rec = (PendingIntentRecord)sender;
9845                int MY_UID = Binder.getCallingUid();
9846                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9847                BatteryStatsImpl.Uid.Pkg pkg =
9848                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9849                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9850                pkg.incWakeupsLocked();
9851            }
9852        }
9853    }
9854
9855    public boolean killPids(int[] pids, String pReason, boolean secure) {
9856        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9857            throw new SecurityException("killPids only available to the system");
9858        }
9859        String reason = (pReason == null) ? "Unknown" : pReason;
9860        // XXX Note: don't acquire main activity lock here, because the window
9861        // manager calls in with its locks held.
9862
9863        boolean killed = false;
9864        synchronized (mPidsSelfLocked) {
9865            int[] types = new int[pids.length];
9866            int worstType = 0;
9867            for (int i=0; i<pids.length; i++) {
9868                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9869                if (proc != null) {
9870                    int type = proc.setAdj;
9871                    types[i] = type;
9872                    if (type > worstType) {
9873                        worstType = type;
9874                    }
9875                }
9876            }
9877
9878            // If the worst oom_adj is somewhere in the cached proc LRU range,
9879            // then constrain it so we will kill all cached procs.
9880            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9881                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9882                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9883            }
9884
9885            // If this is not a secure call, don't let it kill processes that
9886            // are important.
9887            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9888                worstType = ProcessList.SERVICE_ADJ;
9889            }
9890
9891            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9892            for (int i=0; i<pids.length; i++) {
9893                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9894                if (proc == null) {
9895                    continue;
9896                }
9897                int adj = proc.setAdj;
9898                if (adj >= worstType && !proc.killedByAm) {
9899                    killUnneededProcessLocked(proc, reason);
9900                    killed = true;
9901                }
9902            }
9903        }
9904        return killed;
9905    }
9906
9907    @Override
9908    public void killUid(int uid, String reason) {
9909        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9910            throw new SecurityException("killUid only available to the system");
9911        }
9912        synchronized (this) {
9913            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9914                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9915                    reason != null ? reason : "kill uid");
9916        }
9917    }
9918
9919    @Override
9920    public boolean killProcessesBelowForeground(String reason) {
9921        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9922            throw new SecurityException("killProcessesBelowForeground() only available to system");
9923        }
9924
9925        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9926    }
9927
9928    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9929        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9930            throw new SecurityException("killProcessesBelowAdj() only available to system");
9931        }
9932
9933        boolean killed = false;
9934        synchronized (mPidsSelfLocked) {
9935            final int size = mPidsSelfLocked.size();
9936            for (int i = 0; i < size; i++) {
9937                final int pid = mPidsSelfLocked.keyAt(i);
9938                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9939                if (proc == null) continue;
9940
9941                final int adj = proc.setAdj;
9942                if (adj > belowAdj && !proc.killedByAm) {
9943                    killUnneededProcessLocked(proc, reason);
9944                    killed = true;
9945                }
9946            }
9947        }
9948        return killed;
9949    }
9950
9951    @Override
9952    public void hang(final IBinder who, boolean allowRestart) {
9953        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9954                != PackageManager.PERMISSION_GRANTED) {
9955            throw new SecurityException("Requires permission "
9956                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9957        }
9958
9959        final IBinder.DeathRecipient death = new DeathRecipient() {
9960            @Override
9961            public void binderDied() {
9962                synchronized (this) {
9963                    notifyAll();
9964                }
9965            }
9966        };
9967
9968        try {
9969            who.linkToDeath(death, 0);
9970        } catch (RemoteException e) {
9971            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9972            return;
9973        }
9974
9975        synchronized (this) {
9976            Watchdog.getInstance().setAllowRestart(allowRestart);
9977            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9978            synchronized (death) {
9979                while (who.isBinderAlive()) {
9980                    try {
9981                        death.wait();
9982                    } catch (InterruptedException e) {
9983                    }
9984                }
9985            }
9986            Watchdog.getInstance().setAllowRestart(true);
9987        }
9988    }
9989
9990    @Override
9991    public void restart() {
9992        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9993                != PackageManager.PERMISSION_GRANTED) {
9994            throw new SecurityException("Requires permission "
9995                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9996        }
9997
9998        Log.i(TAG, "Sending shutdown broadcast...");
9999
10000        BroadcastReceiver br = new BroadcastReceiver() {
10001            @Override public void onReceive(Context context, Intent intent) {
10002                // Now the broadcast is done, finish up the low-level shutdown.
10003                Log.i(TAG, "Shutting down activity manager...");
10004                shutdown(10000);
10005                Log.i(TAG, "Shutdown complete, restarting!");
10006                Process.killProcess(Process.myPid());
10007                System.exit(10);
10008            }
10009        };
10010
10011        // First send the high-level shut down broadcast.
10012        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10013        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10014        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10015        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10016        mContext.sendOrderedBroadcastAsUser(intent,
10017                UserHandle.ALL, null, br, mHandler, 0, null, null);
10018        */
10019        br.onReceive(mContext, intent);
10020    }
10021
10022    private long getLowRamTimeSinceIdle(long now) {
10023        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10024    }
10025
10026    @Override
10027    public void performIdleMaintenance() {
10028        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10029                != PackageManager.PERMISSION_GRANTED) {
10030            throw new SecurityException("Requires permission "
10031                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10032        }
10033
10034        synchronized (this) {
10035            final long now = SystemClock.uptimeMillis();
10036            final long timeSinceLastIdle = now - mLastIdleTime;
10037            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10038            mLastIdleTime = now;
10039            mLowRamTimeSinceLastIdle = 0;
10040            if (mLowRamStartTime != 0) {
10041                mLowRamStartTime = now;
10042            }
10043
10044            StringBuilder sb = new StringBuilder(128);
10045            sb.append("Idle maintenance over ");
10046            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10047            sb.append(" low RAM for ");
10048            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10049            Slog.i(TAG, sb.toString());
10050
10051            // If at least 1/3 of our time since the last idle period has been spent
10052            // with RAM low, then we want to kill processes.
10053            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10054
10055            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10056                ProcessRecord proc = mLruProcesses.get(i);
10057                if (proc.notCachedSinceIdle) {
10058                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10059                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10060                        if (doKilling && proc.initialIdlePss != 0
10061                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10062                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
10063                                    + " from " + proc.initialIdlePss + ")");
10064                        }
10065                    }
10066                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10067                    proc.notCachedSinceIdle = true;
10068                    proc.initialIdlePss = 0;
10069                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10070                            isSleeping(), now);
10071                }
10072            }
10073
10074            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10075            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10076        }
10077    }
10078
10079    private void retrieveSettings() {
10080        final ContentResolver resolver = mContext.getContentResolver();
10081        String debugApp = Settings.Global.getString(
10082            resolver, Settings.Global.DEBUG_APP);
10083        boolean waitForDebugger = Settings.Global.getInt(
10084            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10085        boolean alwaysFinishActivities = Settings.Global.getInt(
10086            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10087        boolean forceRtl = Settings.Global.getInt(
10088                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10089        // Transfer any global setting for forcing RTL layout, into a System Property
10090        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10091
10092        Configuration configuration = new Configuration();
10093        Settings.System.getConfiguration(resolver, configuration);
10094        if (forceRtl) {
10095            // This will take care of setting the correct layout direction flags
10096            configuration.setLayoutDirection(configuration.locale);
10097        }
10098
10099        synchronized (this) {
10100            mDebugApp = mOrigDebugApp = debugApp;
10101            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10102            mAlwaysFinishActivities = alwaysFinishActivities;
10103            // This happens before any activities are started, so we can
10104            // change mConfiguration in-place.
10105            updateConfigurationLocked(configuration, null, false, true);
10106            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10107        }
10108    }
10109
10110    public boolean testIsSystemReady() {
10111        // no need to synchronize(this) just to read & return the value
10112        return mSystemReady;
10113    }
10114
10115    private static File getCalledPreBootReceiversFile() {
10116        File dataDir = Environment.getDataDirectory();
10117        File systemDir = new File(dataDir, "system");
10118        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10119        return fname;
10120    }
10121
10122    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10123        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10124        File file = getCalledPreBootReceiversFile();
10125        FileInputStream fis = null;
10126        try {
10127            fis = new FileInputStream(file);
10128            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10129            int fvers = dis.readInt();
10130            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10131                String vers = dis.readUTF();
10132                String codename = dis.readUTF();
10133                String build = dis.readUTF();
10134                if (android.os.Build.VERSION.RELEASE.equals(vers)
10135                        && android.os.Build.VERSION.CODENAME.equals(codename)
10136                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10137                    int num = dis.readInt();
10138                    while (num > 0) {
10139                        num--;
10140                        String pkg = dis.readUTF();
10141                        String cls = dis.readUTF();
10142                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10143                    }
10144                }
10145            }
10146        } catch (FileNotFoundException e) {
10147        } catch (IOException e) {
10148            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10149        } finally {
10150            if (fis != null) {
10151                try {
10152                    fis.close();
10153                } catch (IOException e) {
10154                }
10155            }
10156        }
10157        return lastDoneReceivers;
10158    }
10159
10160    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10161        File file = getCalledPreBootReceiversFile();
10162        FileOutputStream fos = null;
10163        DataOutputStream dos = null;
10164        try {
10165            fos = new FileOutputStream(file);
10166            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10167            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10168            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10169            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10170            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10171            dos.writeInt(list.size());
10172            for (int i=0; i<list.size(); i++) {
10173                dos.writeUTF(list.get(i).getPackageName());
10174                dos.writeUTF(list.get(i).getClassName());
10175            }
10176        } catch (IOException e) {
10177            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10178            file.delete();
10179        } finally {
10180            FileUtils.sync(fos);
10181            if (dos != null) {
10182                try {
10183                    dos.close();
10184                } catch (IOException e) {
10185                    // TODO Auto-generated catch block
10186                    e.printStackTrace();
10187                }
10188            }
10189        }
10190    }
10191
10192    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10193            ArrayList<ComponentName> doneReceivers, int userId) {
10194        boolean waitingUpdate = false;
10195        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10196        List<ResolveInfo> ris = null;
10197        try {
10198            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10199                    intent, null, 0, userId);
10200        } catch (RemoteException e) {
10201        }
10202        if (ris != null) {
10203            for (int i=ris.size()-1; i>=0; i--) {
10204                if ((ris.get(i).activityInfo.applicationInfo.flags
10205                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10206                    ris.remove(i);
10207                }
10208            }
10209            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10210
10211            // For User 0, load the version number. When delivering to a new user, deliver
10212            // to all receivers.
10213            if (userId == UserHandle.USER_OWNER) {
10214                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10215                for (int i=0; i<ris.size(); i++) {
10216                    ActivityInfo ai = ris.get(i).activityInfo;
10217                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10218                    if (lastDoneReceivers.contains(comp)) {
10219                        // We already did the pre boot receiver for this app with the current
10220                        // platform version, so don't do it again...
10221                        ris.remove(i);
10222                        i--;
10223                        // ...however, do keep it as one that has been done, so we don't
10224                        // forget about it when rewriting the file of last done receivers.
10225                        doneReceivers.add(comp);
10226                    }
10227                }
10228            }
10229
10230            // If primary user, send broadcast to all available users, else just to userId
10231            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10232                    : new int[] { userId };
10233            for (int i = 0; i < ris.size(); i++) {
10234                ActivityInfo ai = ris.get(i).activityInfo;
10235                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10236                doneReceivers.add(comp);
10237                intent.setComponent(comp);
10238                for (int j=0; j<users.length; j++) {
10239                    IIntentReceiver finisher = null;
10240                    // On last receiver and user, set up a completion callback
10241                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10242                        finisher = new IIntentReceiver.Stub() {
10243                            public void performReceive(Intent intent, int resultCode,
10244                                    String data, Bundle extras, boolean ordered,
10245                                    boolean sticky, int sendingUser) {
10246                                // The raw IIntentReceiver interface is called
10247                                // with the AM lock held, so redispatch to
10248                                // execute our code without the lock.
10249                                mHandler.post(onFinishCallback);
10250                            }
10251                        };
10252                    }
10253                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10254                            + " for user " + users[j]);
10255                    broadcastIntentLocked(null, null, intent, null, finisher,
10256                            0, null, null, null, AppOpsManager.OP_NONE,
10257                            true, false, MY_PID, Process.SYSTEM_UID,
10258                            users[j]);
10259                    if (finisher != null) {
10260                        waitingUpdate = true;
10261                    }
10262                }
10263            }
10264        }
10265
10266        return waitingUpdate;
10267    }
10268
10269    public void systemReady(final Runnable goingCallback) {
10270        synchronized(this) {
10271            if (mSystemReady) {
10272                // If we're done calling all the receivers, run the next "boot phase" passed in
10273                // by the SystemServer
10274                if (goingCallback != null) {
10275                    goingCallback.run();
10276                }
10277                return;
10278            }
10279
10280            // Make sure we have the current profile info, since it is needed for
10281            // security checks.
10282            updateCurrentProfileIdsLocked();
10283
10284            if (mRecentTasks == null) {
10285                mRecentTasks = mTaskPersister.restoreTasksLocked();
10286                if (!mRecentTasks.isEmpty()) {
10287                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10288                }
10289                mTaskPersister.startPersisting();
10290            }
10291
10292            // Check to see if there are any update receivers to run.
10293            if (!mDidUpdate) {
10294                if (mWaitingUpdate) {
10295                    return;
10296                }
10297                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10298                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10299                    public void run() {
10300                        synchronized (ActivityManagerService.this) {
10301                            mDidUpdate = true;
10302                        }
10303                        writeLastDonePreBootReceivers(doneReceivers);
10304                        showBootMessage(mContext.getText(
10305                                R.string.android_upgrading_complete),
10306                                false);
10307                        systemReady(goingCallback);
10308                    }
10309                }, doneReceivers, UserHandle.USER_OWNER);
10310
10311                if (mWaitingUpdate) {
10312                    return;
10313                }
10314                mDidUpdate = true;
10315            }
10316
10317            mAppOpsService.systemReady();
10318            mSystemReady = true;
10319        }
10320
10321        ArrayList<ProcessRecord> procsToKill = null;
10322        synchronized(mPidsSelfLocked) {
10323            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10324                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10325                if (!isAllowedWhileBooting(proc.info)){
10326                    if (procsToKill == null) {
10327                        procsToKill = new ArrayList<ProcessRecord>();
10328                    }
10329                    procsToKill.add(proc);
10330                }
10331            }
10332        }
10333
10334        synchronized(this) {
10335            if (procsToKill != null) {
10336                for (int i=procsToKill.size()-1; i>=0; i--) {
10337                    ProcessRecord proc = procsToKill.get(i);
10338                    Slog.i(TAG, "Removing system update proc: " + proc);
10339                    removeProcessLocked(proc, true, false, "system update done");
10340                }
10341            }
10342
10343            // Now that we have cleaned up any update processes, we
10344            // are ready to start launching real processes and know that
10345            // we won't trample on them any more.
10346            mProcessesReady = true;
10347        }
10348
10349        Slog.i(TAG, "System now ready");
10350        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10351            SystemClock.uptimeMillis());
10352
10353        synchronized(this) {
10354            // Make sure we have no pre-ready processes sitting around.
10355
10356            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10357                ResolveInfo ri = mContext.getPackageManager()
10358                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10359                                STOCK_PM_FLAGS);
10360                CharSequence errorMsg = null;
10361                if (ri != null) {
10362                    ActivityInfo ai = ri.activityInfo;
10363                    ApplicationInfo app = ai.applicationInfo;
10364                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10365                        mTopAction = Intent.ACTION_FACTORY_TEST;
10366                        mTopData = null;
10367                        mTopComponent = new ComponentName(app.packageName,
10368                                ai.name);
10369                    } else {
10370                        errorMsg = mContext.getResources().getText(
10371                                com.android.internal.R.string.factorytest_not_system);
10372                    }
10373                } else {
10374                    errorMsg = mContext.getResources().getText(
10375                            com.android.internal.R.string.factorytest_no_action);
10376                }
10377                if (errorMsg != null) {
10378                    mTopAction = null;
10379                    mTopData = null;
10380                    mTopComponent = null;
10381                    Message msg = Message.obtain();
10382                    msg.what = SHOW_FACTORY_ERROR_MSG;
10383                    msg.getData().putCharSequence("msg", errorMsg);
10384                    mHandler.sendMessage(msg);
10385                }
10386            }
10387        }
10388
10389        retrieveSettings();
10390
10391        synchronized (this) {
10392            readGrantedUriPermissionsLocked();
10393        }
10394
10395        if (goingCallback != null) goingCallback.run();
10396
10397        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10398                Integer.toString(mCurrentUserId), mCurrentUserId);
10399        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10400                Integer.toString(mCurrentUserId), mCurrentUserId);
10401        mSystemServiceManager.startUser(mCurrentUserId);
10402
10403        synchronized (this) {
10404            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10405                try {
10406                    List apps = AppGlobals.getPackageManager().
10407                        getPersistentApplications(STOCK_PM_FLAGS);
10408                    if (apps != null) {
10409                        int N = apps.size();
10410                        int i;
10411                        for (i=0; i<N; i++) {
10412                            ApplicationInfo info
10413                                = (ApplicationInfo)apps.get(i);
10414                            if (info != null &&
10415                                    !info.packageName.equals("android")) {
10416                                addAppLocked(info, false, null /* ABI override */);
10417                            }
10418                        }
10419                    }
10420                } catch (RemoteException ex) {
10421                    // pm is in same process, this will never happen.
10422                }
10423            }
10424
10425            // Start up initial activity.
10426            mBooting = true;
10427
10428            try {
10429                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10430                    Message msg = Message.obtain();
10431                    msg.what = SHOW_UID_ERROR_MSG;
10432                    mHandler.sendMessage(msg);
10433                }
10434            } catch (RemoteException e) {
10435            }
10436
10437            long ident = Binder.clearCallingIdentity();
10438            try {
10439                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10440                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10441                        | Intent.FLAG_RECEIVER_FOREGROUND);
10442                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10443                broadcastIntentLocked(null, null, intent,
10444                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10445                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10446                intent = new Intent(Intent.ACTION_USER_STARTING);
10447                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10448                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10449                broadcastIntentLocked(null, null, intent,
10450                        null, new IIntentReceiver.Stub() {
10451                            @Override
10452                            public void performReceive(Intent intent, int resultCode, String data,
10453                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10454                                    throws RemoteException {
10455                            }
10456                        }, 0, null, null,
10457                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10458                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10459            } catch (Throwable t) {
10460                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10461            } finally {
10462                Binder.restoreCallingIdentity(ident);
10463            }
10464            mStackSupervisor.resumeTopActivitiesLocked();
10465            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10466        }
10467    }
10468
10469    private boolean makeAppCrashingLocked(ProcessRecord app,
10470            String shortMsg, String longMsg, String stackTrace) {
10471        app.crashing = true;
10472        app.crashingReport = generateProcessError(app,
10473                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10474        startAppProblemLocked(app);
10475        app.stopFreezingAllLocked();
10476        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10477    }
10478
10479    private void makeAppNotRespondingLocked(ProcessRecord app,
10480            String activity, String shortMsg, String longMsg) {
10481        app.notResponding = true;
10482        app.notRespondingReport = generateProcessError(app,
10483                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10484                activity, shortMsg, longMsg, null);
10485        startAppProblemLocked(app);
10486        app.stopFreezingAllLocked();
10487    }
10488
10489    /**
10490     * Generate a process error record, suitable for attachment to a ProcessRecord.
10491     *
10492     * @param app The ProcessRecord in which the error occurred.
10493     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10494     *                      ActivityManager.AppErrorStateInfo
10495     * @param activity The activity associated with the crash, if known.
10496     * @param shortMsg Short message describing the crash.
10497     * @param longMsg Long message describing the crash.
10498     * @param stackTrace Full crash stack trace, may be null.
10499     *
10500     * @return Returns a fully-formed AppErrorStateInfo record.
10501     */
10502    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10503            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10504        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10505
10506        report.condition = condition;
10507        report.processName = app.processName;
10508        report.pid = app.pid;
10509        report.uid = app.info.uid;
10510        report.tag = activity;
10511        report.shortMsg = shortMsg;
10512        report.longMsg = longMsg;
10513        report.stackTrace = stackTrace;
10514
10515        return report;
10516    }
10517
10518    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10519        synchronized (this) {
10520            app.crashing = false;
10521            app.crashingReport = null;
10522            app.notResponding = false;
10523            app.notRespondingReport = null;
10524            if (app.anrDialog == fromDialog) {
10525                app.anrDialog = null;
10526            }
10527            if (app.waitDialog == fromDialog) {
10528                app.waitDialog = null;
10529            }
10530            if (app.pid > 0 && app.pid != MY_PID) {
10531                handleAppCrashLocked(app, null, null, null);
10532                killUnneededProcessLocked(app, "user request after error");
10533            }
10534        }
10535    }
10536
10537    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10538            String stackTrace) {
10539        long now = SystemClock.uptimeMillis();
10540
10541        Long crashTime;
10542        if (!app.isolated) {
10543            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10544        } else {
10545            crashTime = null;
10546        }
10547        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10548            // This process loses!
10549            Slog.w(TAG, "Process " + app.info.processName
10550                    + " has crashed too many times: killing!");
10551            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10552                    app.userId, app.info.processName, app.uid);
10553            mStackSupervisor.handleAppCrashLocked(app);
10554            if (!app.persistent) {
10555                // We don't want to start this process again until the user
10556                // explicitly does so...  but for persistent process, we really
10557                // need to keep it running.  If a persistent process is actually
10558                // repeatedly crashing, then badness for everyone.
10559                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10560                        app.info.processName);
10561                if (!app.isolated) {
10562                    // XXX We don't have a way to mark isolated processes
10563                    // as bad, since they don't have a peristent identity.
10564                    mBadProcesses.put(app.info.processName, app.uid,
10565                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10566                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10567                }
10568                app.bad = true;
10569                app.removed = true;
10570                // Don't let services in this process be restarted and potentially
10571                // annoy the user repeatedly.  Unless it is persistent, since those
10572                // processes run critical code.
10573                removeProcessLocked(app, false, false, "crash");
10574                mStackSupervisor.resumeTopActivitiesLocked();
10575                return false;
10576            }
10577            mStackSupervisor.resumeTopActivitiesLocked();
10578        } else {
10579            mStackSupervisor.finishTopRunningActivityLocked(app);
10580        }
10581
10582        // Bump up the crash count of any services currently running in the proc.
10583        for (int i=app.services.size()-1; i>=0; i--) {
10584            // Any services running in the application need to be placed
10585            // back in the pending list.
10586            ServiceRecord sr = app.services.valueAt(i);
10587            sr.crashCount++;
10588        }
10589
10590        // If the crashing process is what we consider to be the "home process" and it has been
10591        // replaced by a third-party app, clear the package preferred activities from packages
10592        // with a home activity running in the process to prevent a repeatedly crashing app
10593        // from blocking the user to manually clear the list.
10594        final ArrayList<ActivityRecord> activities = app.activities;
10595        if (app == mHomeProcess && activities.size() > 0
10596                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10597            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10598                final ActivityRecord r = activities.get(activityNdx);
10599                if (r.isHomeActivity()) {
10600                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10601                    try {
10602                        ActivityThread.getPackageManager()
10603                                .clearPackagePreferredActivities(r.packageName);
10604                    } catch (RemoteException c) {
10605                        // pm is in same process, this will never happen.
10606                    }
10607                }
10608            }
10609        }
10610
10611        if (!app.isolated) {
10612            // XXX Can't keep track of crash times for isolated processes,
10613            // because they don't have a perisistent identity.
10614            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10615        }
10616
10617        if (app.crashHandler != null) mHandler.post(app.crashHandler);
10618        return true;
10619    }
10620
10621    void startAppProblemLocked(ProcessRecord app) {
10622        // If this app is not running under the current user, then we
10623        // can't give it a report button because that would require
10624        // launching the report UI under a different user.
10625        app.errorReportReceiver = null;
10626
10627        for (int userId : mCurrentProfileIds) {
10628            if (app.userId == userId) {
10629                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10630                        mContext, app.info.packageName, app.info.flags);
10631            }
10632        }
10633        skipCurrentReceiverLocked(app);
10634    }
10635
10636    void skipCurrentReceiverLocked(ProcessRecord app) {
10637        for (BroadcastQueue queue : mBroadcastQueues) {
10638            queue.skipCurrentReceiverLocked(app);
10639        }
10640    }
10641
10642    /**
10643     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10644     * The application process will exit immediately after this call returns.
10645     * @param app object of the crashing app, null for the system server
10646     * @param crashInfo describing the exception
10647     */
10648    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10649        ProcessRecord r = findAppProcess(app, "Crash");
10650        final String processName = app == null ? "system_server"
10651                : (r == null ? "unknown" : r.processName);
10652
10653        handleApplicationCrashInner("crash", r, processName, crashInfo);
10654    }
10655
10656    /* Native crash reporting uses this inner version because it needs to be somewhat
10657     * decoupled from the AM-managed cleanup lifecycle
10658     */
10659    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10660            ApplicationErrorReport.CrashInfo crashInfo) {
10661        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10662                UserHandle.getUserId(Binder.getCallingUid()), processName,
10663                r == null ? -1 : r.info.flags,
10664                crashInfo.exceptionClassName,
10665                crashInfo.exceptionMessage,
10666                crashInfo.throwFileName,
10667                crashInfo.throwLineNumber);
10668
10669        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10670
10671        crashApplication(r, crashInfo);
10672    }
10673
10674    public void handleApplicationStrictModeViolation(
10675            IBinder app,
10676            int violationMask,
10677            StrictMode.ViolationInfo info) {
10678        ProcessRecord r = findAppProcess(app, "StrictMode");
10679        if (r == null) {
10680            return;
10681        }
10682
10683        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10684            Integer stackFingerprint = info.hashCode();
10685            boolean logIt = true;
10686            synchronized (mAlreadyLoggedViolatedStacks) {
10687                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10688                    logIt = false;
10689                    // TODO: sub-sample into EventLog for these, with
10690                    // the info.durationMillis?  Then we'd get
10691                    // the relative pain numbers, without logging all
10692                    // the stack traces repeatedly.  We'd want to do
10693                    // likewise in the client code, which also does
10694                    // dup suppression, before the Binder call.
10695                } else {
10696                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10697                        mAlreadyLoggedViolatedStacks.clear();
10698                    }
10699                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10700                }
10701            }
10702            if (logIt) {
10703                logStrictModeViolationToDropBox(r, info);
10704            }
10705        }
10706
10707        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10708            AppErrorResult result = new AppErrorResult();
10709            synchronized (this) {
10710                final long origId = Binder.clearCallingIdentity();
10711
10712                Message msg = Message.obtain();
10713                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10714                HashMap<String, Object> data = new HashMap<String, Object>();
10715                data.put("result", result);
10716                data.put("app", r);
10717                data.put("violationMask", violationMask);
10718                data.put("info", info);
10719                msg.obj = data;
10720                mHandler.sendMessage(msg);
10721
10722                Binder.restoreCallingIdentity(origId);
10723            }
10724            int res = result.get();
10725            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10726        }
10727    }
10728
10729    // Depending on the policy in effect, there could be a bunch of
10730    // these in quick succession so we try to batch these together to
10731    // minimize disk writes, number of dropbox entries, and maximize
10732    // compression, by having more fewer, larger records.
10733    private void logStrictModeViolationToDropBox(
10734            ProcessRecord process,
10735            StrictMode.ViolationInfo info) {
10736        if (info == null) {
10737            return;
10738        }
10739        final boolean isSystemApp = process == null ||
10740                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10741                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10742        final String processName = process == null ? "unknown" : process.processName;
10743        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10744        final DropBoxManager dbox = (DropBoxManager)
10745                mContext.getSystemService(Context.DROPBOX_SERVICE);
10746
10747        // Exit early if the dropbox isn't configured to accept this report type.
10748        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10749
10750        boolean bufferWasEmpty;
10751        boolean needsFlush;
10752        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10753        synchronized (sb) {
10754            bufferWasEmpty = sb.length() == 0;
10755            appendDropBoxProcessHeaders(process, processName, sb);
10756            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10757            sb.append("System-App: ").append(isSystemApp).append("\n");
10758            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10759            if (info.violationNumThisLoop != 0) {
10760                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10761            }
10762            if (info.numAnimationsRunning != 0) {
10763                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10764            }
10765            if (info.broadcastIntentAction != null) {
10766                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10767            }
10768            if (info.durationMillis != -1) {
10769                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10770            }
10771            if (info.numInstances != -1) {
10772                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10773            }
10774            if (info.tags != null) {
10775                for (String tag : info.tags) {
10776                    sb.append("Span-Tag: ").append(tag).append("\n");
10777                }
10778            }
10779            sb.append("\n");
10780            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10781                sb.append(info.crashInfo.stackTrace);
10782            }
10783            sb.append("\n");
10784
10785            // Only buffer up to ~64k.  Various logging bits truncate
10786            // things at 128k.
10787            needsFlush = (sb.length() > 64 * 1024);
10788        }
10789
10790        // Flush immediately if the buffer's grown too large, or this
10791        // is a non-system app.  Non-system apps are isolated with a
10792        // different tag & policy and not batched.
10793        //
10794        // Batching is useful during internal testing with
10795        // StrictMode settings turned up high.  Without batching,
10796        // thousands of separate files could be created on boot.
10797        if (!isSystemApp || needsFlush) {
10798            new Thread("Error dump: " + dropboxTag) {
10799                @Override
10800                public void run() {
10801                    String report;
10802                    synchronized (sb) {
10803                        report = sb.toString();
10804                        sb.delete(0, sb.length());
10805                        sb.trimToSize();
10806                    }
10807                    if (report.length() != 0) {
10808                        dbox.addText(dropboxTag, report);
10809                    }
10810                }
10811            }.start();
10812            return;
10813        }
10814
10815        // System app batching:
10816        if (!bufferWasEmpty) {
10817            // An existing dropbox-writing thread is outstanding, so
10818            // we don't need to start it up.  The existing thread will
10819            // catch the buffer appends we just did.
10820            return;
10821        }
10822
10823        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10824        // (After this point, we shouldn't access AMS internal data structures.)
10825        new Thread("Error dump: " + dropboxTag) {
10826            @Override
10827            public void run() {
10828                // 5 second sleep to let stacks arrive and be batched together
10829                try {
10830                    Thread.sleep(5000);  // 5 seconds
10831                } catch (InterruptedException e) {}
10832
10833                String errorReport;
10834                synchronized (mStrictModeBuffer) {
10835                    errorReport = mStrictModeBuffer.toString();
10836                    if (errorReport.length() == 0) {
10837                        return;
10838                    }
10839                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10840                    mStrictModeBuffer.trimToSize();
10841                }
10842                dbox.addText(dropboxTag, errorReport);
10843            }
10844        }.start();
10845    }
10846
10847    /**
10848     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10849     * @param app object of the crashing app, null for the system server
10850     * @param tag reported by the caller
10851     * @param crashInfo describing the context of the error
10852     * @return true if the process should exit immediately (WTF is fatal)
10853     */
10854    public boolean handleApplicationWtf(IBinder app, String tag,
10855            ApplicationErrorReport.CrashInfo crashInfo) {
10856        ProcessRecord r = findAppProcess(app, "WTF");
10857        final String processName = app == null ? "system_server"
10858                : (r == null ? "unknown" : r.processName);
10859
10860        EventLog.writeEvent(EventLogTags.AM_WTF,
10861                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10862                processName,
10863                r == null ? -1 : r.info.flags,
10864                tag, crashInfo.exceptionMessage);
10865
10866        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10867
10868        if (r != null && r.pid != Process.myPid() &&
10869                Settings.Global.getInt(mContext.getContentResolver(),
10870                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10871            crashApplication(r, crashInfo);
10872            return true;
10873        } else {
10874            return false;
10875        }
10876    }
10877
10878    /**
10879     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10880     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10881     */
10882    private ProcessRecord findAppProcess(IBinder app, String reason) {
10883        if (app == null) {
10884            return null;
10885        }
10886
10887        synchronized (this) {
10888            final int NP = mProcessNames.getMap().size();
10889            for (int ip=0; ip<NP; ip++) {
10890                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10891                final int NA = apps.size();
10892                for (int ia=0; ia<NA; ia++) {
10893                    ProcessRecord p = apps.valueAt(ia);
10894                    if (p.thread != null && p.thread.asBinder() == app) {
10895                        return p;
10896                    }
10897                }
10898            }
10899
10900            Slog.w(TAG, "Can't find mystery application for " + reason
10901                    + " from pid=" + Binder.getCallingPid()
10902                    + " uid=" + Binder.getCallingUid() + ": " + app);
10903            return null;
10904        }
10905    }
10906
10907    /**
10908     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10909     * to append various headers to the dropbox log text.
10910     */
10911    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10912            StringBuilder sb) {
10913        // Watchdog thread ends up invoking this function (with
10914        // a null ProcessRecord) to add the stack file to dropbox.
10915        // Do not acquire a lock on this (am) in such cases, as it
10916        // could cause a potential deadlock, if and when watchdog
10917        // is invoked due to unavailability of lock on am and it
10918        // would prevent watchdog from killing system_server.
10919        if (process == null) {
10920            sb.append("Process: ").append(processName).append("\n");
10921            return;
10922        }
10923        // Note: ProcessRecord 'process' is guarded by the service
10924        // instance.  (notably process.pkgList, which could otherwise change
10925        // concurrently during execution of this method)
10926        synchronized (this) {
10927            sb.append("Process: ").append(processName).append("\n");
10928            int flags = process.info.flags;
10929            IPackageManager pm = AppGlobals.getPackageManager();
10930            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10931            for (int ip=0; ip<process.pkgList.size(); ip++) {
10932                String pkg = process.pkgList.keyAt(ip);
10933                sb.append("Package: ").append(pkg);
10934                try {
10935                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10936                    if (pi != null) {
10937                        sb.append(" v").append(pi.versionCode);
10938                        if (pi.versionName != null) {
10939                            sb.append(" (").append(pi.versionName).append(")");
10940                        }
10941                    }
10942                } catch (RemoteException e) {
10943                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10944                }
10945                sb.append("\n");
10946            }
10947        }
10948    }
10949
10950    private static String processClass(ProcessRecord process) {
10951        if (process == null || process.pid == MY_PID) {
10952            return "system_server";
10953        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10954            return "system_app";
10955        } else {
10956            return "data_app";
10957        }
10958    }
10959
10960    /**
10961     * Write a description of an error (crash, WTF, ANR) to the drop box.
10962     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10963     * @param process which caused the error, null means the system server
10964     * @param activity which triggered the error, null if unknown
10965     * @param parent activity related to the error, null if unknown
10966     * @param subject line related to the error, null if absent
10967     * @param report in long form describing the error, null if absent
10968     * @param logFile to include in the report, null if none
10969     * @param crashInfo giving an application stack trace, null if absent
10970     */
10971    public void addErrorToDropBox(String eventType,
10972            ProcessRecord process, String processName, ActivityRecord activity,
10973            ActivityRecord parent, String subject,
10974            final String report, final File logFile,
10975            final ApplicationErrorReport.CrashInfo crashInfo) {
10976        // NOTE -- this must never acquire the ActivityManagerService lock,
10977        // otherwise the watchdog may be prevented from resetting the system.
10978
10979        final String dropboxTag = processClass(process) + "_" + eventType;
10980        final DropBoxManager dbox = (DropBoxManager)
10981                mContext.getSystemService(Context.DROPBOX_SERVICE);
10982
10983        // Exit early if the dropbox isn't configured to accept this report type.
10984        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10985
10986        final StringBuilder sb = new StringBuilder(1024);
10987        appendDropBoxProcessHeaders(process, processName, sb);
10988        if (activity != null) {
10989            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10990        }
10991        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10992            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10993        }
10994        if (parent != null && parent != activity) {
10995            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10996        }
10997        if (subject != null) {
10998            sb.append("Subject: ").append(subject).append("\n");
10999        }
11000        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11001        if (Debug.isDebuggerConnected()) {
11002            sb.append("Debugger: Connected\n");
11003        }
11004        sb.append("\n");
11005
11006        // Do the rest in a worker thread to avoid blocking the caller on I/O
11007        // (After this point, we shouldn't access AMS internal data structures.)
11008        Thread worker = new Thread("Error dump: " + dropboxTag) {
11009            @Override
11010            public void run() {
11011                if (report != null) {
11012                    sb.append(report);
11013                }
11014                if (logFile != null) {
11015                    try {
11016                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11017                                    "\n\n[[TRUNCATED]]"));
11018                    } catch (IOException e) {
11019                        Slog.e(TAG, "Error reading " + logFile, e);
11020                    }
11021                }
11022                if (crashInfo != null && crashInfo.stackTrace != null) {
11023                    sb.append(crashInfo.stackTrace);
11024                }
11025
11026                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11027                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11028                if (lines > 0) {
11029                    sb.append("\n");
11030
11031                    // Merge several logcat streams, and take the last N lines
11032                    InputStreamReader input = null;
11033                    try {
11034                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11035                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11036                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11037
11038                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11039                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11040                        input = new InputStreamReader(logcat.getInputStream());
11041
11042                        int num;
11043                        char[] buf = new char[8192];
11044                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11045                    } catch (IOException e) {
11046                        Slog.e(TAG, "Error running logcat", e);
11047                    } finally {
11048                        if (input != null) try { input.close(); } catch (IOException e) {}
11049                    }
11050                }
11051
11052                dbox.addText(dropboxTag, sb.toString());
11053            }
11054        };
11055
11056        if (process == null) {
11057            // If process is null, we are being called from some internal code
11058            // and may be about to die -- run this synchronously.
11059            worker.run();
11060        } else {
11061            worker.start();
11062        }
11063    }
11064
11065    /**
11066     * Bring up the "unexpected error" dialog box for a crashing app.
11067     * Deal with edge cases (intercepts from instrumented applications,
11068     * ActivityController, error intent receivers, that sort of thing).
11069     * @param r the application crashing
11070     * @param crashInfo describing the failure
11071     */
11072    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11073        long timeMillis = System.currentTimeMillis();
11074        String shortMsg = crashInfo.exceptionClassName;
11075        String longMsg = crashInfo.exceptionMessage;
11076        String stackTrace = crashInfo.stackTrace;
11077        if (shortMsg != null && longMsg != null) {
11078            longMsg = shortMsg + ": " + longMsg;
11079        } else if (shortMsg != null) {
11080            longMsg = shortMsg;
11081        }
11082
11083        AppErrorResult result = new AppErrorResult();
11084        synchronized (this) {
11085            if (mController != null) {
11086                try {
11087                    String name = r != null ? r.processName : null;
11088                    int pid = r != null ? r.pid : Binder.getCallingPid();
11089                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11090                    if (!mController.appCrashed(name, pid,
11091                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11092                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11093                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11094                            Slog.w(TAG, "Skip killing native crashed app " + name
11095                                    + "(" + pid + ") during testing");
11096                        } else {
11097                            Slog.w(TAG, "Force-killing crashed app " + name
11098                                    + " at watcher's request");
11099                            Process.killProcess(pid);
11100                            if (r != null) {
11101                                Process.killProcessGroup(uid, pid);
11102                            }
11103                        }
11104                        return;
11105                    }
11106                } catch (RemoteException e) {
11107                    mController = null;
11108                    Watchdog.getInstance().setActivityController(null);
11109                }
11110            }
11111
11112            final long origId = Binder.clearCallingIdentity();
11113
11114            // If this process is running instrumentation, finish it.
11115            if (r != null && r.instrumentationClass != null) {
11116                Slog.w(TAG, "Error in app " + r.processName
11117                      + " running instrumentation " + r.instrumentationClass + ":");
11118                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11119                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11120                Bundle info = new Bundle();
11121                info.putString("shortMsg", shortMsg);
11122                info.putString("longMsg", longMsg);
11123                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11124                Binder.restoreCallingIdentity(origId);
11125                return;
11126            }
11127
11128            // If we can't identify the process or it's already exceeded its crash quota,
11129            // quit right away without showing a crash dialog.
11130            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11131                Binder.restoreCallingIdentity(origId);
11132                return;
11133            }
11134
11135            Message msg = Message.obtain();
11136            msg.what = SHOW_ERROR_MSG;
11137            HashMap data = new HashMap();
11138            data.put("result", result);
11139            data.put("app", r);
11140            msg.obj = data;
11141            mHandler.sendMessage(msg);
11142
11143            Binder.restoreCallingIdentity(origId);
11144        }
11145
11146        int res = result.get();
11147
11148        Intent appErrorIntent = null;
11149        synchronized (this) {
11150            if (r != null && !r.isolated) {
11151                // XXX Can't keep track of crash time for isolated processes,
11152                // since they don't have a persistent identity.
11153                mProcessCrashTimes.put(r.info.processName, r.uid,
11154                        SystemClock.uptimeMillis());
11155            }
11156            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11157                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11158            }
11159        }
11160
11161        if (appErrorIntent != null) {
11162            try {
11163                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11164            } catch (ActivityNotFoundException e) {
11165                Slog.w(TAG, "bug report receiver dissappeared", e);
11166            }
11167        }
11168    }
11169
11170    Intent createAppErrorIntentLocked(ProcessRecord r,
11171            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11172        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11173        if (report == null) {
11174            return null;
11175        }
11176        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11177        result.setComponent(r.errorReportReceiver);
11178        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11179        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11180        return result;
11181    }
11182
11183    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11184            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11185        if (r.errorReportReceiver == null) {
11186            return null;
11187        }
11188
11189        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11190            return null;
11191        }
11192
11193        ApplicationErrorReport report = new ApplicationErrorReport();
11194        report.packageName = r.info.packageName;
11195        report.installerPackageName = r.errorReportReceiver.getPackageName();
11196        report.processName = r.processName;
11197        report.time = timeMillis;
11198        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11199
11200        if (r.crashing || r.forceCrashReport) {
11201            report.type = ApplicationErrorReport.TYPE_CRASH;
11202            report.crashInfo = crashInfo;
11203        } else if (r.notResponding) {
11204            report.type = ApplicationErrorReport.TYPE_ANR;
11205            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11206
11207            report.anrInfo.activity = r.notRespondingReport.tag;
11208            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11209            report.anrInfo.info = r.notRespondingReport.longMsg;
11210        }
11211
11212        return report;
11213    }
11214
11215    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11216        enforceNotIsolatedCaller("getProcessesInErrorState");
11217        // assume our apps are happy - lazy create the list
11218        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11219
11220        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11221                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11222        int userId = UserHandle.getUserId(Binder.getCallingUid());
11223
11224        synchronized (this) {
11225
11226            // iterate across all processes
11227            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11228                ProcessRecord app = mLruProcesses.get(i);
11229                if (!allUsers && app.userId != userId) {
11230                    continue;
11231                }
11232                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11233                    // This one's in trouble, so we'll generate a report for it
11234                    // crashes are higher priority (in case there's a crash *and* an anr)
11235                    ActivityManager.ProcessErrorStateInfo report = null;
11236                    if (app.crashing) {
11237                        report = app.crashingReport;
11238                    } else if (app.notResponding) {
11239                        report = app.notRespondingReport;
11240                    }
11241
11242                    if (report != null) {
11243                        if (errList == null) {
11244                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11245                        }
11246                        errList.add(report);
11247                    } else {
11248                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11249                                " crashing = " + app.crashing +
11250                                " notResponding = " + app.notResponding);
11251                    }
11252                }
11253            }
11254        }
11255
11256        return errList;
11257    }
11258
11259    static int procStateToImportance(int procState, int memAdj,
11260            ActivityManager.RunningAppProcessInfo currApp) {
11261        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11262        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11263            currApp.lru = memAdj;
11264        } else {
11265            currApp.lru = 0;
11266        }
11267        return imp;
11268    }
11269
11270    private void fillInProcMemInfo(ProcessRecord app,
11271            ActivityManager.RunningAppProcessInfo outInfo) {
11272        outInfo.pid = app.pid;
11273        outInfo.uid = app.info.uid;
11274        if (mHeavyWeightProcess == app) {
11275            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11276        }
11277        if (app.persistent) {
11278            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11279        }
11280        if (app.activities.size() > 0) {
11281            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11282        }
11283        outInfo.lastTrimLevel = app.trimMemoryLevel;
11284        int adj = app.curAdj;
11285        int procState = app.curProcState;
11286        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11287        outInfo.importanceReasonCode = app.adjTypeCode;
11288        outInfo.processState = app.curProcState;
11289    }
11290
11291    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11292        enforceNotIsolatedCaller("getRunningAppProcesses");
11293        // Lazy instantiation of list
11294        List<ActivityManager.RunningAppProcessInfo> runList = null;
11295        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11296                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11297        int userId = UserHandle.getUserId(Binder.getCallingUid());
11298        synchronized (this) {
11299            // Iterate across all processes
11300            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11301                ProcessRecord app = mLruProcesses.get(i);
11302                if (!allUsers && app.userId != userId) {
11303                    continue;
11304                }
11305                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11306                    // Generate process state info for running application
11307                    ActivityManager.RunningAppProcessInfo currApp =
11308                        new ActivityManager.RunningAppProcessInfo(app.processName,
11309                                app.pid, app.getPackageList());
11310                    fillInProcMemInfo(app, currApp);
11311                    if (app.adjSource instanceof ProcessRecord) {
11312                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11313                        currApp.importanceReasonImportance =
11314                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11315                                        app.adjSourceProcState);
11316                    } else if (app.adjSource instanceof ActivityRecord) {
11317                        ActivityRecord r = (ActivityRecord)app.adjSource;
11318                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11319                    }
11320                    if (app.adjTarget instanceof ComponentName) {
11321                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11322                    }
11323                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11324                    //        + " lru=" + currApp.lru);
11325                    if (runList == null) {
11326                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11327                    }
11328                    runList.add(currApp);
11329                }
11330            }
11331        }
11332        return runList;
11333    }
11334
11335    public List<ApplicationInfo> getRunningExternalApplications() {
11336        enforceNotIsolatedCaller("getRunningExternalApplications");
11337        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11338        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11339        if (runningApps != null && runningApps.size() > 0) {
11340            Set<String> extList = new HashSet<String>();
11341            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11342                if (app.pkgList != null) {
11343                    for (String pkg : app.pkgList) {
11344                        extList.add(pkg);
11345                    }
11346                }
11347            }
11348            IPackageManager pm = AppGlobals.getPackageManager();
11349            for (String pkg : extList) {
11350                try {
11351                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11352                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11353                        retList.add(info);
11354                    }
11355                } catch (RemoteException e) {
11356                }
11357            }
11358        }
11359        return retList;
11360    }
11361
11362    @Override
11363    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11364        enforceNotIsolatedCaller("getMyMemoryState");
11365        synchronized (this) {
11366            ProcessRecord proc;
11367            synchronized (mPidsSelfLocked) {
11368                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11369            }
11370            fillInProcMemInfo(proc, outInfo);
11371        }
11372    }
11373
11374    @Override
11375    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11376        if (checkCallingPermission(android.Manifest.permission.DUMP)
11377                != PackageManager.PERMISSION_GRANTED) {
11378            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11379                    + Binder.getCallingPid()
11380                    + ", uid=" + Binder.getCallingUid()
11381                    + " without permission "
11382                    + android.Manifest.permission.DUMP);
11383            return;
11384        }
11385
11386        boolean dumpAll = false;
11387        boolean dumpClient = false;
11388        String dumpPackage = null;
11389
11390        int opti = 0;
11391        while (opti < args.length) {
11392            String opt = args[opti];
11393            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11394                break;
11395            }
11396            opti++;
11397            if ("-a".equals(opt)) {
11398                dumpAll = true;
11399            } else if ("-c".equals(opt)) {
11400                dumpClient = true;
11401            } else if ("-h".equals(opt)) {
11402                pw.println("Activity manager dump options:");
11403                pw.println("  [-a] [-c] [-h] [cmd] ...");
11404                pw.println("  cmd may be one of:");
11405                pw.println("    a[ctivities]: activity stack state");
11406                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11407                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11408                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11409                pw.println("    o[om]: out of memory management");
11410                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11411                pw.println("    provider [COMP_SPEC]: provider client-side state");
11412                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11413                pw.println("    service [COMP_SPEC]: service client-side state");
11414                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11415                pw.println("    all: dump all activities");
11416                pw.println("    top: dump the top activity");
11417                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11418                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11419                pw.println("    a partial substring in a component name, a");
11420                pw.println("    hex object identifier.");
11421                pw.println("  -a: include all available server state.");
11422                pw.println("  -c: include client state.");
11423                return;
11424            } else {
11425                pw.println("Unknown argument: " + opt + "; use -h for help");
11426            }
11427        }
11428
11429        long origId = Binder.clearCallingIdentity();
11430        boolean more = false;
11431        // Is the caller requesting to dump a particular piece of data?
11432        if (opti < args.length) {
11433            String cmd = args[opti];
11434            opti++;
11435            if ("activities".equals(cmd) || "a".equals(cmd)) {
11436                synchronized (this) {
11437                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11438                }
11439            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11440                String[] newArgs;
11441                String name;
11442                if (opti >= args.length) {
11443                    name = null;
11444                    newArgs = EMPTY_STRING_ARRAY;
11445                } else {
11446                    name = args[opti];
11447                    opti++;
11448                    newArgs = new String[args.length - opti];
11449                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11450                            args.length - opti);
11451                }
11452                synchronized (this) {
11453                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11454                }
11455            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11456                String[] newArgs;
11457                String name;
11458                if (opti >= args.length) {
11459                    name = null;
11460                    newArgs = EMPTY_STRING_ARRAY;
11461                } else {
11462                    name = args[opti];
11463                    opti++;
11464                    newArgs = new String[args.length - opti];
11465                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11466                            args.length - opti);
11467                }
11468                synchronized (this) {
11469                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11470                }
11471            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11472                String[] newArgs;
11473                String name;
11474                if (opti >= args.length) {
11475                    name = null;
11476                    newArgs = EMPTY_STRING_ARRAY;
11477                } else {
11478                    name = args[opti];
11479                    opti++;
11480                    newArgs = new String[args.length - opti];
11481                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11482                            args.length - opti);
11483                }
11484                synchronized (this) {
11485                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11486                }
11487            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11488                synchronized (this) {
11489                    dumpOomLocked(fd, pw, args, opti, true);
11490                }
11491            } else if ("provider".equals(cmd)) {
11492                String[] newArgs;
11493                String name;
11494                if (opti >= args.length) {
11495                    name = null;
11496                    newArgs = EMPTY_STRING_ARRAY;
11497                } else {
11498                    name = args[opti];
11499                    opti++;
11500                    newArgs = new String[args.length - opti];
11501                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11502                }
11503                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11504                    pw.println("No providers match: " + name);
11505                    pw.println("Use -h for help.");
11506                }
11507            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11508                synchronized (this) {
11509                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11510                }
11511            } else if ("service".equals(cmd)) {
11512                String[] newArgs;
11513                String name;
11514                if (opti >= args.length) {
11515                    name = null;
11516                    newArgs = EMPTY_STRING_ARRAY;
11517                } else {
11518                    name = args[opti];
11519                    opti++;
11520                    newArgs = new String[args.length - opti];
11521                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11522                            args.length - opti);
11523                }
11524                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11525                    pw.println("No services match: " + name);
11526                    pw.println("Use -h for help.");
11527                }
11528            } else if ("package".equals(cmd)) {
11529                String[] newArgs;
11530                if (opti >= args.length) {
11531                    pw.println("package: no package name specified");
11532                    pw.println("Use -h for help.");
11533                } else {
11534                    dumpPackage = args[opti];
11535                    opti++;
11536                    newArgs = new String[args.length - opti];
11537                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11538                            args.length - opti);
11539                    args = newArgs;
11540                    opti = 0;
11541                    more = true;
11542                }
11543            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11544                synchronized (this) {
11545                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11546                }
11547            } else {
11548                // Dumping a single activity?
11549                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11550                    pw.println("Bad activity command, or no activities match: " + cmd);
11551                    pw.println("Use -h for help.");
11552                }
11553            }
11554            if (!more) {
11555                Binder.restoreCallingIdentity(origId);
11556                return;
11557            }
11558        }
11559
11560        // No piece of data specified, dump everything.
11561        synchronized (this) {
11562            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11563            pw.println();
11564            if (dumpAll) {
11565                pw.println("-------------------------------------------------------------------------------");
11566            }
11567            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11568            pw.println();
11569            if (dumpAll) {
11570                pw.println("-------------------------------------------------------------------------------");
11571            }
11572            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11573            pw.println();
11574            if (dumpAll) {
11575                pw.println("-------------------------------------------------------------------------------");
11576            }
11577            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11578            pw.println();
11579            if (dumpAll) {
11580                pw.println("-------------------------------------------------------------------------------");
11581            }
11582            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11583            pw.println();
11584            if (dumpAll) {
11585                pw.println("-------------------------------------------------------------------------------");
11586            }
11587            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11588        }
11589        Binder.restoreCallingIdentity(origId);
11590    }
11591
11592    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11593            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11594        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11595
11596        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11597                dumpPackage);
11598        boolean needSep = printedAnything;
11599
11600        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11601                dumpPackage, needSep, "  mFocusedActivity: ");
11602        if (printed) {
11603            printedAnything = true;
11604            needSep = false;
11605        }
11606
11607        if (dumpPackage == null) {
11608            if (needSep) {
11609                pw.println();
11610            }
11611            needSep = true;
11612            printedAnything = true;
11613            mStackSupervisor.dump(pw, "  ");
11614        }
11615
11616        if (mRecentTasks.size() > 0) {
11617            boolean printedHeader = false;
11618
11619            final int N = mRecentTasks.size();
11620            for (int i=0; i<N; i++) {
11621                TaskRecord tr = mRecentTasks.get(i);
11622                if (dumpPackage != null) {
11623                    if (tr.realActivity == null ||
11624                            !dumpPackage.equals(tr.realActivity)) {
11625                        continue;
11626                    }
11627                }
11628                if (!printedHeader) {
11629                    if (needSep) {
11630                        pw.println();
11631                    }
11632                    pw.println("  Recent tasks:");
11633                    printedHeader = true;
11634                    printedAnything = true;
11635                }
11636                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11637                        pw.println(tr);
11638                if (dumpAll) {
11639                    mRecentTasks.get(i).dump(pw, "    ");
11640                }
11641            }
11642        }
11643
11644        if (!printedAnything) {
11645            pw.println("  (nothing)");
11646        }
11647    }
11648
11649    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11650            int opti, boolean dumpAll, String dumpPackage) {
11651        boolean needSep = false;
11652        boolean printedAnything = false;
11653        int numPers = 0;
11654
11655        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11656
11657        if (dumpAll) {
11658            final int NP = mProcessNames.getMap().size();
11659            for (int ip=0; ip<NP; ip++) {
11660                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11661                final int NA = procs.size();
11662                for (int ia=0; ia<NA; ia++) {
11663                    ProcessRecord r = procs.valueAt(ia);
11664                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11665                        continue;
11666                    }
11667                    if (!needSep) {
11668                        pw.println("  All known processes:");
11669                        needSep = true;
11670                        printedAnything = true;
11671                    }
11672                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11673                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11674                        pw.print(" "); pw.println(r);
11675                    r.dump(pw, "    ");
11676                    if (r.persistent) {
11677                        numPers++;
11678                    }
11679                }
11680            }
11681        }
11682
11683        if (mIsolatedProcesses.size() > 0) {
11684            boolean printed = false;
11685            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11686                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11687                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11688                    continue;
11689                }
11690                if (!printed) {
11691                    if (needSep) {
11692                        pw.println();
11693                    }
11694                    pw.println("  Isolated process list (sorted by uid):");
11695                    printedAnything = true;
11696                    printed = true;
11697                    needSep = true;
11698                }
11699                pw.println(String.format("%sIsolated #%2d: %s",
11700                        "    ", i, r.toString()));
11701            }
11702        }
11703
11704        if (mLruProcesses.size() > 0) {
11705            if (needSep) {
11706                pw.println();
11707            }
11708            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11709                    pw.print(" total, non-act at ");
11710                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11711                    pw.print(", non-svc at ");
11712                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11713                    pw.println("):");
11714            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11715            needSep = true;
11716            printedAnything = true;
11717        }
11718
11719        if (dumpAll || dumpPackage != null) {
11720            synchronized (mPidsSelfLocked) {
11721                boolean printed = false;
11722                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11723                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11724                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11725                        continue;
11726                    }
11727                    if (!printed) {
11728                        if (needSep) pw.println();
11729                        needSep = true;
11730                        pw.println("  PID mappings:");
11731                        printed = true;
11732                        printedAnything = true;
11733                    }
11734                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11735                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11736                }
11737            }
11738        }
11739
11740        if (mForegroundProcesses.size() > 0) {
11741            synchronized (mPidsSelfLocked) {
11742                boolean printed = false;
11743                for (int i=0; i<mForegroundProcesses.size(); i++) {
11744                    ProcessRecord r = mPidsSelfLocked.get(
11745                            mForegroundProcesses.valueAt(i).pid);
11746                    if (dumpPackage != null && (r == null
11747                            || !r.pkgList.containsKey(dumpPackage))) {
11748                        continue;
11749                    }
11750                    if (!printed) {
11751                        if (needSep) pw.println();
11752                        needSep = true;
11753                        pw.println("  Foreground Processes:");
11754                        printed = true;
11755                        printedAnything = true;
11756                    }
11757                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11758                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11759                }
11760            }
11761        }
11762
11763        if (mPersistentStartingProcesses.size() > 0) {
11764            if (needSep) pw.println();
11765            needSep = true;
11766            printedAnything = true;
11767            pw.println("  Persisent processes that are starting:");
11768            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11769                    "Starting Norm", "Restarting PERS", dumpPackage);
11770        }
11771
11772        if (mRemovedProcesses.size() > 0) {
11773            if (needSep) pw.println();
11774            needSep = true;
11775            printedAnything = true;
11776            pw.println("  Processes that are being removed:");
11777            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11778                    "Removed Norm", "Removed PERS", dumpPackage);
11779        }
11780
11781        if (mProcessesOnHold.size() > 0) {
11782            if (needSep) pw.println();
11783            needSep = true;
11784            printedAnything = true;
11785            pw.println("  Processes that are on old until the system is ready:");
11786            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11787                    "OnHold Norm", "OnHold PERS", dumpPackage);
11788        }
11789
11790        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11791
11792        if (mProcessCrashTimes.getMap().size() > 0) {
11793            boolean printed = false;
11794            long now = SystemClock.uptimeMillis();
11795            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11796            final int NP = pmap.size();
11797            for (int ip=0; ip<NP; ip++) {
11798                String pname = pmap.keyAt(ip);
11799                SparseArray<Long> uids = pmap.valueAt(ip);
11800                final int N = uids.size();
11801                for (int i=0; i<N; i++) {
11802                    int puid = uids.keyAt(i);
11803                    ProcessRecord r = mProcessNames.get(pname, puid);
11804                    if (dumpPackage != null && (r == null
11805                            || !r.pkgList.containsKey(dumpPackage))) {
11806                        continue;
11807                    }
11808                    if (!printed) {
11809                        if (needSep) pw.println();
11810                        needSep = true;
11811                        pw.println("  Time since processes crashed:");
11812                        printed = true;
11813                        printedAnything = true;
11814                    }
11815                    pw.print("    Process "); pw.print(pname);
11816                            pw.print(" uid "); pw.print(puid);
11817                            pw.print(": last crashed ");
11818                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11819                            pw.println(" ago");
11820                }
11821            }
11822        }
11823
11824        if (mBadProcesses.getMap().size() > 0) {
11825            boolean printed = false;
11826            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11827            final int NP = pmap.size();
11828            for (int ip=0; ip<NP; ip++) {
11829                String pname = pmap.keyAt(ip);
11830                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11831                final int N = uids.size();
11832                for (int i=0; i<N; i++) {
11833                    int puid = uids.keyAt(i);
11834                    ProcessRecord r = mProcessNames.get(pname, puid);
11835                    if (dumpPackage != null && (r == null
11836                            || !r.pkgList.containsKey(dumpPackage))) {
11837                        continue;
11838                    }
11839                    if (!printed) {
11840                        if (needSep) pw.println();
11841                        needSep = true;
11842                        pw.println("  Bad processes:");
11843                        printedAnything = true;
11844                    }
11845                    BadProcessInfo info = uids.valueAt(i);
11846                    pw.print("    Bad process "); pw.print(pname);
11847                            pw.print(" uid "); pw.print(puid);
11848                            pw.print(": crashed at time "); pw.println(info.time);
11849                    if (info.shortMsg != null) {
11850                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11851                    }
11852                    if (info.longMsg != null) {
11853                        pw.print("      Long msg: "); pw.println(info.longMsg);
11854                    }
11855                    if (info.stack != null) {
11856                        pw.println("      Stack:");
11857                        int lastPos = 0;
11858                        for (int pos=0; pos<info.stack.length(); pos++) {
11859                            if (info.stack.charAt(pos) == '\n') {
11860                                pw.print("        ");
11861                                pw.write(info.stack, lastPos, pos-lastPos);
11862                                pw.println();
11863                                lastPos = pos+1;
11864                            }
11865                        }
11866                        if (lastPos < info.stack.length()) {
11867                            pw.print("        ");
11868                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11869                            pw.println();
11870                        }
11871                    }
11872                }
11873            }
11874        }
11875
11876        if (dumpPackage == null) {
11877            pw.println();
11878            needSep = false;
11879            pw.println("  mStartedUsers:");
11880            for (int i=0; i<mStartedUsers.size(); i++) {
11881                UserStartedState uss = mStartedUsers.valueAt(i);
11882                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11883                        pw.print(": "); uss.dump("", pw);
11884            }
11885            pw.print("  mStartedUserArray: [");
11886            for (int i=0; i<mStartedUserArray.length; i++) {
11887                if (i > 0) pw.print(", ");
11888                pw.print(mStartedUserArray[i]);
11889            }
11890            pw.println("]");
11891            pw.print("  mUserLru: [");
11892            for (int i=0; i<mUserLru.size(); i++) {
11893                if (i > 0) pw.print(", ");
11894                pw.print(mUserLru.get(i));
11895            }
11896            pw.println("]");
11897            if (dumpAll) {
11898                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11899            }
11900            synchronized (mUserProfileGroupIdsSelfLocked) {
11901                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11902                    pw.println("  mUserProfileGroupIds:");
11903                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11904                        pw.print("    User #");
11905                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11906                        pw.print(" -> profile #");
11907                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11908                    }
11909                }
11910            }
11911        }
11912        if (mHomeProcess != null && (dumpPackage == null
11913                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11914            if (needSep) {
11915                pw.println();
11916                needSep = false;
11917            }
11918            pw.println("  mHomeProcess: " + mHomeProcess);
11919        }
11920        if (mPreviousProcess != null && (dumpPackage == null
11921                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11922            if (needSep) {
11923                pw.println();
11924                needSep = false;
11925            }
11926            pw.println("  mPreviousProcess: " + mPreviousProcess);
11927        }
11928        if (dumpAll) {
11929            StringBuilder sb = new StringBuilder(128);
11930            sb.append("  mPreviousProcessVisibleTime: ");
11931            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11932            pw.println(sb);
11933        }
11934        if (mHeavyWeightProcess != null && (dumpPackage == null
11935                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11936            if (needSep) {
11937                pw.println();
11938                needSep = false;
11939            }
11940            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11941        }
11942        if (dumpPackage == null) {
11943            pw.println("  mConfiguration: " + mConfiguration);
11944        }
11945        if (dumpAll) {
11946            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11947            if (mCompatModePackages.getPackages().size() > 0) {
11948                boolean printed = false;
11949                for (Map.Entry<String, Integer> entry
11950                        : mCompatModePackages.getPackages().entrySet()) {
11951                    String pkg = entry.getKey();
11952                    int mode = entry.getValue();
11953                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11954                        continue;
11955                    }
11956                    if (!printed) {
11957                        pw.println("  mScreenCompatPackages:");
11958                        printed = true;
11959                    }
11960                    pw.print("    "); pw.print(pkg); pw.print(": ");
11961                            pw.print(mode); pw.println();
11962                }
11963            }
11964        }
11965        if (dumpPackage == null) {
11966            if (mSleeping || mWentToSleep || mLockScreenShown) {
11967                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11968                        + " mLockScreenShown " + mLockScreenShown);
11969            }
11970            if (mShuttingDown || mRunningVoice) {
11971                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11972            }
11973        }
11974        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11975                || mOrigWaitForDebugger) {
11976            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11977                    || dumpPackage.equals(mOrigDebugApp)) {
11978                if (needSep) {
11979                    pw.println();
11980                    needSep = false;
11981                }
11982                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11983                        + " mDebugTransient=" + mDebugTransient
11984                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11985            }
11986        }
11987        if (mOpenGlTraceApp != null) {
11988            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11989                if (needSep) {
11990                    pw.println();
11991                    needSep = false;
11992                }
11993                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11994            }
11995        }
11996        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11997                || mProfileFd != null) {
11998            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11999                if (needSep) {
12000                    pw.println();
12001                    needSep = false;
12002                }
12003                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12004                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12005                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
12006                        + mAutoStopProfiler);
12007            }
12008        }
12009        if (dumpPackage == null) {
12010            if (mAlwaysFinishActivities || mController != null) {
12011                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12012                        + " mController=" + mController);
12013            }
12014            if (dumpAll) {
12015                pw.println("  Total persistent processes: " + numPers);
12016                pw.println("  mProcessesReady=" + mProcessesReady
12017                        + " mSystemReady=" + mSystemReady);
12018                pw.println("  mBooting=" + mBooting
12019                        + " mBooted=" + mBooted
12020                        + " mFactoryTest=" + mFactoryTest);
12021                pw.print("  mLastPowerCheckRealtime=");
12022                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12023                        pw.println("");
12024                pw.print("  mLastPowerCheckUptime=");
12025                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12026                        pw.println("");
12027                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12028                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12029                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12030                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12031                        + " (" + mLruProcesses.size() + " total)"
12032                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12033                        + " mNumServiceProcs=" + mNumServiceProcs
12034                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12035                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12036                        + " mLastMemoryLevel" + mLastMemoryLevel
12037                        + " mLastNumProcesses" + mLastNumProcesses);
12038                long now = SystemClock.uptimeMillis();
12039                pw.print("  mLastIdleTime=");
12040                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12041                        pw.print(" mLowRamSinceLastIdle=");
12042                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12043                        pw.println();
12044            }
12045        }
12046
12047        if (!printedAnything) {
12048            pw.println("  (nothing)");
12049        }
12050    }
12051
12052    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12053            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12054        if (mProcessesToGc.size() > 0) {
12055            boolean printed = false;
12056            long now = SystemClock.uptimeMillis();
12057            for (int i=0; i<mProcessesToGc.size(); i++) {
12058                ProcessRecord proc = mProcessesToGc.get(i);
12059                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12060                    continue;
12061                }
12062                if (!printed) {
12063                    if (needSep) pw.println();
12064                    needSep = true;
12065                    pw.println("  Processes that are waiting to GC:");
12066                    printed = true;
12067                }
12068                pw.print("    Process "); pw.println(proc);
12069                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12070                        pw.print(", last gced=");
12071                        pw.print(now-proc.lastRequestedGc);
12072                        pw.print(" ms ago, last lowMem=");
12073                        pw.print(now-proc.lastLowMemory);
12074                        pw.println(" ms ago");
12075
12076            }
12077        }
12078        return needSep;
12079    }
12080
12081    void printOomLevel(PrintWriter pw, String name, int adj) {
12082        pw.print("    ");
12083        if (adj >= 0) {
12084            pw.print(' ');
12085            if (adj < 10) pw.print(' ');
12086        } else {
12087            if (adj > -10) pw.print(' ');
12088        }
12089        pw.print(adj);
12090        pw.print(": ");
12091        pw.print(name);
12092        pw.print(" (");
12093        pw.print(mProcessList.getMemLevel(adj)/1024);
12094        pw.println(" kB)");
12095    }
12096
12097    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12098            int opti, boolean dumpAll) {
12099        boolean needSep = false;
12100
12101        if (mLruProcesses.size() > 0) {
12102            if (needSep) pw.println();
12103            needSep = true;
12104            pw.println("  OOM levels:");
12105            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12106            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12107            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12108            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12109            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12110            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12111            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12112            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12113            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12114            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12115            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12116            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12117            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12118
12119            if (needSep) pw.println();
12120            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12121                    pw.print(" total, non-act at ");
12122                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12123                    pw.print(", non-svc at ");
12124                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12125                    pw.println("):");
12126            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12127            needSep = true;
12128        }
12129
12130        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12131
12132        pw.println();
12133        pw.println("  mHomeProcess: " + mHomeProcess);
12134        pw.println("  mPreviousProcess: " + mPreviousProcess);
12135        if (mHeavyWeightProcess != null) {
12136            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12137        }
12138
12139        return true;
12140    }
12141
12142    /**
12143     * There are three ways to call this:
12144     *  - no provider specified: dump all the providers
12145     *  - a flattened component name that matched an existing provider was specified as the
12146     *    first arg: dump that one provider
12147     *  - the first arg isn't the flattened component name of an existing provider:
12148     *    dump all providers whose component contains the first arg as a substring
12149     */
12150    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12151            int opti, boolean dumpAll) {
12152        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12153    }
12154
12155    static class ItemMatcher {
12156        ArrayList<ComponentName> components;
12157        ArrayList<String> strings;
12158        ArrayList<Integer> objects;
12159        boolean all;
12160
12161        ItemMatcher() {
12162            all = true;
12163        }
12164
12165        void build(String name) {
12166            ComponentName componentName = ComponentName.unflattenFromString(name);
12167            if (componentName != null) {
12168                if (components == null) {
12169                    components = new ArrayList<ComponentName>();
12170                }
12171                components.add(componentName);
12172                all = false;
12173            } else {
12174                int objectId = 0;
12175                // Not a '/' separated full component name; maybe an object ID?
12176                try {
12177                    objectId = Integer.parseInt(name, 16);
12178                    if (objects == null) {
12179                        objects = new ArrayList<Integer>();
12180                    }
12181                    objects.add(objectId);
12182                    all = false;
12183                } catch (RuntimeException e) {
12184                    // Not an integer; just do string match.
12185                    if (strings == null) {
12186                        strings = new ArrayList<String>();
12187                    }
12188                    strings.add(name);
12189                    all = false;
12190                }
12191            }
12192        }
12193
12194        int build(String[] args, int opti) {
12195            for (; opti<args.length; opti++) {
12196                String name = args[opti];
12197                if ("--".equals(name)) {
12198                    return opti+1;
12199                }
12200                build(name);
12201            }
12202            return opti;
12203        }
12204
12205        boolean match(Object object, ComponentName comp) {
12206            if (all) {
12207                return true;
12208            }
12209            if (components != null) {
12210                for (int i=0; i<components.size(); i++) {
12211                    if (components.get(i).equals(comp)) {
12212                        return true;
12213                    }
12214                }
12215            }
12216            if (objects != null) {
12217                for (int i=0; i<objects.size(); i++) {
12218                    if (System.identityHashCode(object) == objects.get(i)) {
12219                        return true;
12220                    }
12221                }
12222            }
12223            if (strings != null) {
12224                String flat = comp.flattenToString();
12225                for (int i=0; i<strings.size(); i++) {
12226                    if (flat.contains(strings.get(i))) {
12227                        return true;
12228                    }
12229                }
12230            }
12231            return false;
12232        }
12233    }
12234
12235    /**
12236     * There are three things that cmd can be:
12237     *  - a flattened component name that matches an existing activity
12238     *  - the cmd arg isn't the flattened component name of an existing activity:
12239     *    dump all activity whose component contains the cmd as a substring
12240     *  - A hex number of the ActivityRecord object instance.
12241     */
12242    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12243            int opti, boolean dumpAll) {
12244        ArrayList<ActivityRecord> activities;
12245
12246        synchronized (this) {
12247            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12248        }
12249
12250        if (activities.size() <= 0) {
12251            return false;
12252        }
12253
12254        String[] newArgs = new String[args.length - opti];
12255        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12256
12257        TaskRecord lastTask = null;
12258        boolean needSep = false;
12259        for (int i=activities.size()-1; i>=0; i--) {
12260            ActivityRecord r = activities.get(i);
12261            if (needSep) {
12262                pw.println();
12263            }
12264            needSep = true;
12265            synchronized (this) {
12266                if (lastTask != r.task) {
12267                    lastTask = r.task;
12268                    pw.print("TASK "); pw.print(lastTask.affinity);
12269                            pw.print(" id="); pw.println(lastTask.taskId);
12270                    if (dumpAll) {
12271                        lastTask.dump(pw, "  ");
12272                    }
12273                }
12274            }
12275            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12276        }
12277        return true;
12278    }
12279
12280    /**
12281     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12282     * there is a thread associated with the activity.
12283     */
12284    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12285            final ActivityRecord r, String[] args, boolean dumpAll) {
12286        String innerPrefix = prefix + "  ";
12287        synchronized (this) {
12288            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12289                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12290                    pw.print(" pid=");
12291                    if (r.app != null) pw.println(r.app.pid);
12292                    else pw.println("(not running)");
12293            if (dumpAll) {
12294                r.dump(pw, innerPrefix);
12295            }
12296        }
12297        if (r.app != null && r.app.thread != null) {
12298            // flush anything that is already in the PrintWriter since the thread is going
12299            // to write to the file descriptor directly
12300            pw.flush();
12301            try {
12302                TransferPipe tp = new TransferPipe();
12303                try {
12304                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12305                            r.appToken, innerPrefix, args);
12306                    tp.go(fd);
12307                } finally {
12308                    tp.kill();
12309                }
12310            } catch (IOException e) {
12311                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12312            } catch (RemoteException e) {
12313                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12314            }
12315        }
12316    }
12317
12318    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12319            int opti, boolean dumpAll, String dumpPackage) {
12320        boolean needSep = false;
12321        boolean onlyHistory = false;
12322        boolean printedAnything = false;
12323
12324        if ("history".equals(dumpPackage)) {
12325            if (opti < args.length && "-s".equals(args[opti])) {
12326                dumpAll = false;
12327            }
12328            onlyHistory = true;
12329            dumpPackage = null;
12330        }
12331
12332        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12333        if (!onlyHistory && dumpAll) {
12334            if (mRegisteredReceivers.size() > 0) {
12335                boolean printed = false;
12336                Iterator it = mRegisteredReceivers.values().iterator();
12337                while (it.hasNext()) {
12338                    ReceiverList r = (ReceiverList)it.next();
12339                    if (dumpPackage != null && (r.app == null ||
12340                            !dumpPackage.equals(r.app.info.packageName))) {
12341                        continue;
12342                    }
12343                    if (!printed) {
12344                        pw.println("  Registered Receivers:");
12345                        needSep = true;
12346                        printed = true;
12347                        printedAnything = true;
12348                    }
12349                    pw.print("  * "); pw.println(r);
12350                    r.dump(pw, "    ");
12351                }
12352            }
12353
12354            if (mReceiverResolver.dump(pw, needSep ?
12355                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12356                    "    ", dumpPackage, false)) {
12357                needSep = true;
12358                printedAnything = true;
12359            }
12360        }
12361
12362        for (BroadcastQueue q : mBroadcastQueues) {
12363            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12364            printedAnything |= needSep;
12365        }
12366
12367        needSep = true;
12368
12369        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12370            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12371                if (needSep) {
12372                    pw.println();
12373                }
12374                needSep = true;
12375                printedAnything = true;
12376                pw.print("  Sticky broadcasts for user ");
12377                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12378                StringBuilder sb = new StringBuilder(128);
12379                for (Map.Entry<String, ArrayList<Intent>> ent
12380                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12381                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12382                    if (dumpAll) {
12383                        pw.println(":");
12384                        ArrayList<Intent> intents = ent.getValue();
12385                        final int N = intents.size();
12386                        for (int i=0; i<N; i++) {
12387                            sb.setLength(0);
12388                            sb.append("    Intent: ");
12389                            intents.get(i).toShortString(sb, false, true, false, false);
12390                            pw.println(sb.toString());
12391                            Bundle bundle = intents.get(i).getExtras();
12392                            if (bundle != null) {
12393                                pw.print("      ");
12394                                pw.println(bundle.toString());
12395                            }
12396                        }
12397                    } else {
12398                        pw.println("");
12399                    }
12400                }
12401            }
12402        }
12403
12404        if (!onlyHistory && dumpAll) {
12405            pw.println();
12406            for (BroadcastQueue queue : mBroadcastQueues) {
12407                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12408                        + queue.mBroadcastsScheduled);
12409            }
12410            pw.println("  mHandler:");
12411            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12412            needSep = true;
12413            printedAnything = true;
12414        }
12415
12416        if (!printedAnything) {
12417            pw.println("  (nothing)");
12418        }
12419    }
12420
12421    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12422            int opti, boolean dumpAll, String dumpPackage) {
12423        boolean needSep;
12424        boolean printedAnything = false;
12425
12426        ItemMatcher matcher = new ItemMatcher();
12427        matcher.build(args, opti);
12428
12429        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12430
12431        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12432        printedAnything |= needSep;
12433
12434        if (mLaunchingProviders.size() > 0) {
12435            boolean printed = false;
12436            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12437                ContentProviderRecord r = mLaunchingProviders.get(i);
12438                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12439                    continue;
12440                }
12441                if (!printed) {
12442                    if (needSep) pw.println();
12443                    needSep = true;
12444                    pw.println("  Launching content providers:");
12445                    printed = true;
12446                    printedAnything = true;
12447                }
12448                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12449                        pw.println(r);
12450            }
12451        }
12452
12453        if (mGrantedUriPermissions.size() > 0) {
12454            boolean printed = false;
12455            int dumpUid = -2;
12456            if (dumpPackage != null) {
12457                try {
12458                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12459                } catch (NameNotFoundException e) {
12460                    dumpUid = -1;
12461                }
12462            }
12463            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12464                int uid = mGrantedUriPermissions.keyAt(i);
12465                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12466                    continue;
12467                }
12468                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12469                if (!printed) {
12470                    if (needSep) pw.println();
12471                    needSep = true;
12472                    pw.println("  Granted Uri Permissions:");
12473                    printed = true;
12474                    printedAnything = true;
12475                }
12476                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12477                for (UriPermission perm : perms.values()) {
12478                    pw.print("    "); pw.println(perm);
12479                    if (dumpAll) {
12480                        perm.dump(pw, "      ");
12481                    }
12482                }
12483            }
12484        }
12485
12486        if (!printedAnything) {
12487            pw.println("  (nothing)");
12488        }
12489    }
12490
12491    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12492            int opti, boolean dumpAll, String dumpPackage) {
12493        boolean printed = false;
12494
12495        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12496
12497        if (mIntentSenderRecords.size() > 0) {
12498            Iterator<WeakReference<PendingIntentRecord>> it
12499                    = mIntentSenderRecords.values().iterator();
12500            while (it.hasNext()) {
12501                WeakReference<PendingIntentRecord> ref = it.next();
12502                PendingIntentRecord rec = ref != null ? ref.get(): null;
12503                if (dumpPackage != null && (rec == null
12504                        || !dumpPackage.equals(rec.key.packageName))) {
12505                    continue;
12506                }
12507                printed = true;
12508                if (rec != null) {
12509                    pw.print("  * "); pw.println(rec);
12510                    if (dumpAll) {
12511                        rec.dump(pw, "    ");
12512                    }
12513                } else {
12514                    pw.print("  * "); pw.println(ref);
12515                }
12516            }
12517        }
12518
12519        if (!printed) {
12520            pw.println("  (nothing)");
12521        }
12522    }
12523
12524    private static final int dumpProcessList(PrintWriter pw,
12525            ActivityManagerService service, List list,
12526            String prefix, String normalLabel, String persistentLabel,
12527            String dumpPackage) {
12528        int numPers = 0;
12529        final int N = list.size()-1;
12530        for (int i=N; i>=0; i--) {
12531            ProcessRecord r = (ProcessRecord)list.get(i);
12532            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12533                continue;
12534            }
12535            pw.println(String.format("%s%s #%2d: %s",
12536                    prefix, (r.persistent ? persistentLabel : normalLabel),
12537                    i, r.toString()));
12538            if (r.persistent) {
12539                numPers++;
12540            }
12541        }
12542        return numPers;
12543    }
12544
12545    private static final boolean dumpProcessOomList(PrintWriter pw,
12546            ActivityManagerService service, List<ProcessRecord> origList,
12547            String prefix, String normalLabel, String persistentLabel,
12548            boolean inclDetails, String dumpPackage) {
12549
12550        ArrayList<Pair<ProcessRecord, Integer>> list
12551                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12552        for (int i=0; i<origList.size(); i++) {
12553            ProcessRecord r = origList.get(i);
12554            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12555                continue;
12556            }
12557            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12558        }
12559
12560        if (list.size() <= 0) {
12561            return false;
12562        }
12563
12564        Comparator<Pair<ProcessRecord, Integer>> comparator
12565                = new Comparator<Pair<ProcessRecord, Integer>>() {
12566            @Override
12567            public int compare(Pair<ProcessRecord, Integer> object1,
12568                    Pair<ProcessRecord, Integer> object2) {
12569                if (object1.first.setAdj != object2.first.setAdj) {
12570                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12571                }
12572                if (object1.second.intValue() != object2.second.intValue()) {
12573                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12574                }
12575                return 0;
12576            }
12577        };
12578
12579        Collections.sort(list, comparator);
12580
12581        final long curRealtime = SystemClock.elapsedRealtime();
12582        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12583        final long curUptime = SystemClock.uptimeMillis();
12584        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12585
12586        for (int i=list.size()-1; i>=0; i--) {
12587            ProcessRecord r = list.get(i).first;
12588            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12589            char schedGroup;
12590            switch (r.setSchedGroup) {
12591                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12592                    schedGroup = 'B';
12593                    break;
12594                case Process.THREAD_GROUP_DEFAULT:
12595                    schedGroup = 'F';
12596                    break;
12597                default:
12598                    schedGroup = '?';
12599                    break;
12600            }
12601            char foreground;
12602            if (r.foregroundActivities) {
12603                foreground = 'A';
12604            } else if (r.foregroundServices) {
12605                foreground = 'S';
12606            } else {
12607                foreground = ' ';
12608            }
12609            String procState = ProcessList.makeProcStateString(r.curProcState);
12610            pw.print(prefix);
12611            pw.print(r.persistent ? persistentLabel : normalLabel);
12612            pw.print(" #");
12613            int num = (origList.size()-1)-list.get(i).second;
12614            if (num < 10) pw.print(' ');
12615            pw.print(num);
12616            pw.print(": ");
12617            pw.print(oomAdj);
12618            pw.print(' ');
12619            pw.print(schedGroup);
12620            pw.print('/');
12621            pw.print(foreground);
12622            pw.print('/');
12623            pw.print(procState);
12624            pw.print(" trm:");
12625            if (r.trimMemoryLevel < 10) pw.print(' ');
12626            pw.print(r.trimMemoryLevel);
12627            pw.print(' ');
12628            pw.print(r.toShortString());
12629            pw.print(" (");
12630            pw.print(r.adjType);
12631            pw.println(')');
12632            if (r.adjSource != null || r.adjTarget != null) {
12633                pw.print(prefix);
12634                pw.print("    ");
12635                if (r.adjTarget instanceof ComponentName) {
12636                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12637                } else if (r.adjTarget != null) {
12638                    pw.print(r.adjTarget.toString());
12639                } else {
12640                    pw.print("{null}");
12641                }
12642                pw.print("<=");
12643                if (r.adjSource instanceof ProcessRecord) {
12644                    pw.print("Proc{");
12645                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12646                    pw.println("}");
12647                } else if (r.adjSource != null) {
12648                    pw.println(r.adjSource.toString());
12649                } else {
12650                    pw.println("{null}");
12651                }
12652            }
12653            if (inclDetails) {
12654                pw.print(prefix);
12655                pw.print("    ");
12656                pw.print("oom: max="); pw.print(r.maxAdj);
12657                pw.print(" curRaw="); pw.print(r.curRawAdj);
12658                pw.print(" setRaw="); pw.print(r.setRawAdj);
12659                pw.print(" cur="); pw.print(r.curAdj);
12660                pw.print(" set="); pw.println(r.setAdj);
12661                pw.print(prefix);
12662                pw.print("    ");
12663                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12664                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12665                pw.print(" lastPss="); pw.print(r.lastPss);
12666                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12667                pw.print(prefix);
12668                pw.print("    ");
12669                pw.print("cached="); pw.print(r.cached);
12670                pw.print(" empty="); pw.print(r.empty);
12671                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12672
12673                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12674                    if (r.lastWakeTime != 0) {
12675                        long wtime;
12676                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12677                        synchronized (stats) {
12678                            wtime = stats.getProcessWakeTime(r.info.uid,
12679                                    r.pid, curRealtime);
12680                        }
12681                        long timeUsed = wtime - r.lastWakeTime;
12682                        pw.print(prefix);
12683                        pw.print("    ");
12684                        pw.print("keep awake over ");
12685                        TimeUtils.formatDuration(realtimeSince, pw);
12686                        pw.print(" used ");
12687                        TimeUtils.formatDuration(timeUsed, pw);
12688                        pw.print(" (");
12689                        pw.print((timeUsed*100)/realtimeSince);
12690                        pw.println("%)");
12691                    }
12692                    if (r.lastCpuTime != 0) {
12693                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12694                        pw.print(prefix);
12695                        pw.print("    ");
12696                        pw.print("run cpu over ");
12697                        TimeUtils.formatDuration(uptimeSince, pw);
12698                        pw.print(" used ");
12699                        TimeUtils.formatDuration(timeUsed, pw);
12700                        pw.print(" (");
12701                        pw.print((timeUsed*100)/uptimeSince);
12702                        pw.println("%)");
12703                    }
12704                }
12705            }
12706        }
12707        return true;
12708    }
12709
12710    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12711        ArrayList<ProcessRecord> procs;
12712        synchronized (this) {
12713            if (args != null && args.length > start
12714                    && args[start].charAt(0) != '-') {
12715                procs = new ArrayList<ProcessRecord>();
12716                int pid = -1;
12717                try {
12718                    pid = Integer.parseInt(args[start]);
12719                } catch (NumberFormatException e) {
12720                }
12721                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12722                    ProcessRecord proc = mLruProcesses.get(i);
12723                    if (proc.pid == pid) {
12724                        procs.add(proc);
12725                    } else if (proc.processName.equals(args[start])) {
12726                        procs.add(proc);
12727                    }
12728                }
12729                if (procs.size() <= 0) {
12730                    return null;
12731                }
12732            } else {
12733                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12734            }
12735        }
12736        return procs;
12737    }
12738
12739    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12740            PrintWriter pw, String[] args) {
12741        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12742        if (procs == null) {
12743            pw.println("No process found for: " + args[0]);
12744            return;
12745        }
12746
12747        long uptime = SystemClock.uptimeMillis();
12748        long realtime = SystemClock.elapsedRealtime();
12749        pw.println("Applications Graphics Acceleration Info:");
12750        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12751
12752        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12753            ProcessRecord r = procs.get(i);
12754            if (r.thread != null) {
12755                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12756                pw.flush();
12757                try {
12758                    TransferPipe tp = new TransferPipe();
12759                    try {
12760                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12761                        tp.go(fd);
12762                    } finally {
12763                        tp.kill();
12764                    }
12765                } catch (IOException e) {
12766                    pw.println("Failure while dumping the app: " + r);
12767                    pw.flush();
12768                } catch (RemoteException e) {
12769                    pw.println("Got a RemoteException while dumping the app " + r);
12770                    pw.flush();
12771                }
12772            }
12773        }
12774    }
12775
12776    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12777        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12778        if (procs == null) {
12779            pw.println("No process found for: " + args[0]);
12780            return;
12781        }
12782
12783        pw.println("Applications Database Info:");
12784
12785        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12786            ProcessRecord r = procs.get(i);
12787            if (r.thread != null) {
12788                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12789                pw.flush();
12790                try {
12791                    TransferPipe tp = new TransferPipe();
12792                    try {
12793                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12794                        tp.go(fd);
12795                    } finally {
12796                        tp.kill();
12797                    }
12798                } catch (IOException e) {
12799                    pw.println("Failure while dumping the app: " + r);
12800                    pw.flush();
12801                } catch (RemoteException e) {
12802                    pw.println("Got a RemoteException while dumping the app " + r);
12803                    pw.flush();
12804                }
12805            }
12806        }
12807    }
12808
12809    final static class MemItem {
12810        final boolean isProc;
12811        final String label;
12812        final String shortLabel;
12813        final long pss;
12814        final int id;
12815        final boolean hasActivities;
12816        ArrayList<MemItem> subitems;
12817
12818        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12819                boolean _hasActivities) {
12820            isProc = true;
12821            label = _label;
12822            shortLabel = _shortLabel;
12823            pss = _pss;
12824            id = _id;
12825            hasActivities = _hasActivities;
12826        }
12827
12828        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12829            isProc = false;
12830            label = _label;
12831            shortLabel = _shortLabel;
12832            pss = _pss;
12833            id = _id;
12834            hasActivities = false;
12835        }
12836    }
12837
12838    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12839            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12840        if (sort && !isCompact) {
12841            Collections.sort(items, new Comparator<MemItem>() {
12842                @Override
12843                public int compare(MemItem lhs, MemItem rhs) {
12844                    if (lhs.pss < rhs.pss) {
12845                        return 1;
12846                    } else if (lhs.pss > rhs.pss) {
12847                        return -1;
12848                    }
12849                    return 0;
12850                }
12851            });
12852        }
12853
12854        for (int i=0; i<items.size(); i++) {
12855            MemItem mi = items.get(i);
12856            if (!isCompact) {
12857                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12858            } else if (mi.isProc) {
12859                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12860                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12861                pw.println(mi.hasActivities ? ",a" : ",e");
12862            } else {
12863                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12864                pw.println(mi.pss);
12865            }
12866            if (mi.subitems != null) {
12867                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12868                        true, isCompact);
12869            }
12870        }
12871    }
12872
12873    // These are in KB.
12874    static final long[] DUMP_MEM_BUCKETS = new long[] {
12875        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12876        120*1024, 160*1024, 200*1024,
12877        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12878        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12879    };
12880
12881    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12882            boolean stackLike) {
12883        int start = label.lastIndexOf('.');
12884        if (start >= 0) start++;
12885        else start = 0;
12886        int end = label.length();
12887        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12888            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12889                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12890                out.append(bucket);
12891                out.append(stackLike ? "MB." : "MB ");
12892                out.append(label, start, end);
12893                return;
12894            }
12895        }
12896        out.append(memKB/1024);
12897        out.append(stackLike ? "MB." : "MB ");
12898        out.append(label, start, end);
12899    }
12900
12901    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12902            ProcessList.NATIVE_ADJ,
12903            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12904            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12905            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12906            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12907            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12908    };
12909    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12910            "Native",
12911            "System", "Persistent", "Foreground",
12912            "Visible", "Perceptible",
12913            "Heavy Weight", "Backup",
12914            "A Services", "Home",
12915            "Previous", "B Services", "Cached"
12916    };
12917    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12918            "native",
12919            "sys", "pers", "fore",
12920            "vis", "percept",
12921            "heavy", "backup",
12922            "servicea", "home",
12923            "prev", "serviceb", "cached"
12924    };
12925
12926    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12927            long realtime, boolean isCheckinRequest, boolean isCompact) {
12928        if (isCheckinRequest || isCompact) {
12929            // short checkin version
12930            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12931        } else {
12932            pw.println("Applications Memory Usage (kB):");
12933            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12934        }
12935    }
12936
12937    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12938            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12939        boolean dumpDetails = false;
12940        boolean dumpFullDetails = false;
12941        boolean dumpDalvik = false;
12942        boolean oomOnly = false;
12943        boolean isCompact = false;
12944        boolean localOnly = false;
12945
12946        int opti = 0;
12947        while (opti < args.length) {
12948            String opt = args[opti];
12949            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12950                break;
12951            }
12952            opti++;
12953            if ("-a".equals(opt)) {
12954                dumpDetails = true;
12955                dumpFullDetails = true;
12956                dumpDalvik = true;
12957            } else if ("-d".equals(opt)) {
12958                dumpDalvik = true;
12959            } else if ("-c".equals(opt)) {
12960                isCompact = true;
12961            } else if ("--oom".equals(opt)) {
12962                oomOnly = true;
12963            } else if ("--local".equals(opt)) {
12964                localOnly = true;
12965            } else if ("-h".equals(opt)) {
12966                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12967                pw.println("  -a: include all available information for each process.");
12968                pw.println("  -d: include dalvik details when dumping process details.");
12969                pw.println("  -c: dump in a compact machine-parseable representation.");
12970                pw.println("  --oom: only show processes organized by oom adj.");
12971                pw.println("  --local: only collect details locally, don't call process.");
12972                pw.println("If [process] is specified it can be the name or ");
12973                pw.println("pid of a specific process to dump.");
12974                return;
12975            } else {
12976                pw.println("Unknown argument: " + opt + "; use -h for help");
12977            }
12978        }
12979
12980        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12981        long uptime = SystemClock.uptimeMillis();
12982        long realtime = SystemClock.elapsedRealtime();
12983        final long[] tmpLong = new long[1];
12984
12985        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12986        if (procs == null) {
12987            // No Java processes.  Maybe they want to print a native process.
12988            if (args != null && args.length > opti
12989                    && args[opti].charAt(0) != '-') {
12990                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12991                        = new ArrayList<ProcessCpuTracker.Stats>();
12992                updateCpuStatsNow();
12993                int findPid = -1;
12994                try {
12995                    findPid = Integer.parseInt(args[opti]);
12996                } catch (NumberFormatException e) {
12997                }
12998                synchronized (mProcessCpuThread) {
12999                    final int N = mProcessCpuTracker.countStats();
13000                    for (int i=0; i<N; i++) {
13001                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13002                        if (st.pid == findPid || (st.baseName != null
13003                                && st.baseName.equals(args[opti]))) {
13004                            nativeProcs.add(st);
13005                        }
13006                    }
13007                }
13008                if (nativeProcs.size() > 0) {
13009                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13010                            isCompact);
13011                    Debug.MemoryInfo mi = null;
13012                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13013                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13014                        final int pid = r.pid;
13015                        if (!isCheckinRequest && dumpDetails) {
13016                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13017                        }
13018                        if (mi == null) {
13019                            mi = new Debug.MemoryInfo();
13020                        }
13021                        if (dumpDetails || (!brief && !oomOnly)) {
13022                            Debug.getMemoryInfo(pid, mi);
13023                        } else {
13024                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13025                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13026                        }
13027                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13028                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13029                        if (isCheckinRequest) {
13030                            pw.println();
13031                        }
13032                    }
13033                    return;
13034                }
13035            }
13036            pw.println("No process found for: " + args[opti]);
13037            return;
13038        }
13039
13040        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13041            dumpDetails = true;
13042        }
13043
13044        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13045
13046        String[] innerArgs = new String[args.length-opti];
13047        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13048
13049        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13050        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13051        long nativePss=0, dalvikPss=0, otherPss=0;
13052        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13053
13054        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13055        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13056                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13057
13058        long totalPss = 0;
13059        long cachedPss = 0;
13060
13061        Debug.MemoryInfo mi = null;
13062        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13063            final ProcessRecord r = procs.get(i);
13064            final IApplicationThread thread;
13065            final int pid;
13066            final int oomAdj;
13067            final boolean hasActivities;
13068            synchronized (this) {
13069                thread = r.thread;
13070                pid = r.pid;
13071                oomAdj = r.getSetAdjWithServices();
13072                hasActivities = r.activities.size() > 0;
13073            }
13074            if (thread != null) {
13075                if (!isCheckinRequest && dumpDetails) {
13076                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13077                }
13078                if (mi == null) {
13079                    mi = new Debug.MemoryInfo();
13080                }
13081                if (dumpDetails || (!brief && !oomOnly)) {
13082                    Debug.getMemoryInfo(pid, mi);
13083                } else {
13084                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13085                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13086                }
13087                if (dumpDetails) {
13088                    if (localOnly) {
13089                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13090                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13091                        if (isCheckinRequest) {
13092                            pw.println();
13093                        }
13094                    } else {
13095                        try {
13096                            pw.flush();
13097                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13098                                    dumpDalvik, innerArgs);
13099                        } catch (RemoteException e) {
13100                            if (!isCheckinRequest) {
13101                                pw.println("Got RemoteException!");
13102                                pw.flush();
13103                            }
13104                        }
13105                    }
13106                }
13107
13108                final long myTotalPss = mi.getTotalPss();
13109                final long myTotalUss = mi.getTotalUss();
13110
13111                synchronized (this) {
13112                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13113                        // Record this for posterity if the process has been stable.
13114                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13115                    }
13116                }
13117
13118                if (!isCheckinRequest && mi != null) {
13119                    totalPss += myTotalPss;
13120                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13121                            (hasActivities ? " / activities)" : ")"),
13122                            r.processName, myTotalPss, pid, hasActivities);
13123                    procMems.add(pssItem);
13124                    procMemsMap.put(pid, pssItem);
13125
13126                    nativePss += mi.nativePss;
13127                    dalvikPss += mi.dalvikPss;
13128                    otherPss += mi.otherPss;
13129                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13130                        long mem = mi.getOtherPss(j);
13131                        miscPss[j] += mem;
13132                        otherPss -= mem;
13133                    }
13134
13135                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13136                        cachedPss += myTotalPss;
13137                    }
13138
13139                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13140                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13141                                || oomIndex == (oomPss.length-1)) {
13142                            oomPss[oomIndex] += myTotalPss;
13143                            if (oomProcs[oomIndex] == null) {
13144                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13145                            }
13146                            oomProcs[oomIndex].add(pssItem);
13147                            break;
13148                        }
13149                    }
13150                }
13151            }
13152        }
13153
13154        long nativeProcTotalPss = 0;
13155
13156        if (!isCheckinRequest && procs.size() > 1) {
13157            // If we are showing aggregations, also look for native processes to
13158            // include so that our aggregations are more accurate.
13159            updateCpuStatsNow();
13160            synchronized (mProcessCpuThread) {
13161                final int N = mProcessCpuTracker.countStats();
13162                for (int i=0; i<N; i++) {
13163                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13164                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13165                        if (mi == null) {
13166                            mi = new Debug.MemoryInfo();
13167                        }
13168                        if (!brief && !oomOnly) {
13169                            Debug.getMemoryInfo(st.pid, mi);
13170                        } else {
13171                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13172                            mi.nativePrivateDirty = (int)tmpLong[0];
13173                        }
13174
13175                        final long myTotalPss = mi.getTotalPss();
13176                        totalPss += myTotalPss;
13177                        nativeProcTotalPss += myTotalPss;
13178
13179                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13180                                st.name, myTotalPss, st.pid, false);
13181                        procMems.add(pssItem);
13182
13183                        nativePss += mi.nativePss;
13184                        dalvikPss += mi.dalvikPss;
13185                        otherPss += mi.otherPss;
13186                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13187                            long mem = mi.getOtherPss(j);
13188                            miscPss[j] += mem;
13189                            otherPss -= mem;
13190                        }
13191                        oomPss[0] += myTotalPss;
13192                        if (oomProcs[0] == null) {
13193                            oomProcs[0] = new ArrayList<MemItem>();
13194                        }
13195                        oomProcs[0].add(pssItem);
13196                    }
13197                }
13198            }
13199
13200            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13201
13202            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13203            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13204            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13205            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13206                String label = Debug.MemoryInfo.getOtherLabel(j);
13207                catMems.add(new MemItem(label, label, miscPss[j], j));
13208            }
13209
13210            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13211            for (int j=0; j<oomPss.length; j++) {
13212                if (oomPss[j] != 0) {
13213                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13214                            : DUMP_MEM_OOM_LABEL[j];
13215                    MemItem item = new MemItem(label, label, oomPss[j],
13216                            DUMP_MEM_OOM_ADJ[j]);
13217                    item.subitems = oomProcs[j];
13218                    oomMems.add(item);
13219                }
13220            }
13221
13222            if (!brief && !oomOnly && !isCompact) {
13223                pw.println();
13224                pw.println("Total PSS by process:");
13225                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13226                pw.println();
13227            }
13228            if (!isCompact) {
13229                pw.println("Total PSS by OOM adjustment:");
13230            }
13231            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13232            if (!brief && !oomOnly) {
13233                PrintWriter out = categoryPw != null ? categoryPw : pw;
13234                if (!isCompact) {
13235                    out.println();
13236                    out.println("Total PSS by category:");
13237                }
13238                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13239            }
13240            if (!isCompact) {
13241                pw.println();
13242            }
13243            MemInfoReader memInfo = new MemInfoReader();
13244            memInfo.readMemInfo();
13245            if (nativeProcTotalPss > 0) {
13246                synchronized (this) {
13247                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13248                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13249                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13250                            nativeProcTotalPss);
13251                }
13252            }
13253            if (!brief) {
13254                if (!isCompact) {
13255                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13256                    pw.print(" kB (status ");
13257                    switch (mLastMemoryLevel) {
13258                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13259                            pw.println("normal)");
13260                            break;
13261                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13262                            pw.println("moderate)");
13263                            break;
13264                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13265                            pw.println("low)");
13266                            break;
13267                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13268                            pw.println("critical)");
13269                            break;
13270                        default:
13271                            pw.print(mLastMemoryLevel);
13272                            pw.println(")");
13273                            break;
13274                    }
13275                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13276                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13277                            pw.print(cachedPss); pw.print(" cached pss + ");
13278                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13279                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13280                } else {
13281                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13282                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13283                            + memInfo.getFreeSizeKb()); pw.print(",");
13284                    pw.println(totalPss - cachedPss);
13285                }
13286            }
13287            if (!isCompact) {
13288                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13289                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13290                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13291                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13292                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13293                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13294                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13295                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13296                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13297                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13298                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13299            }
13300            if (!brief) {
13301                if (memInfo.getZramTotalSizeKb() != 0) {
13302                    if (!isCompact) {
13303                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13304                                pw.print(" kB physical used for ");
13305                                pw.print(memInfo.getSwapTotalSizeKb()
13306                                        - memInfo.getSwapFreeSizeKb());
13307                                pw.print(" kB in swap (");
13308                                pw.print(memInfo.getSwapTotalSizeKb());
13309                                pw.println(" kB total swap)");
13310                    } else {
13311                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13312                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13313                                pw.println(memInfo.getSwapFreeSizeKb());
13314                    }
13315                }
13316                final int[] SINGLE_LONG_FORMAT = new int[] {
13317                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13318                };
13319                long[] longOut = new long[1];
13320                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13321                        SINGLE_LONG_FORMAT, null, longOut, null);
13322                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13323                longOut[0] = 0;
13324                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13325                        SINGLE_LONG_FORMAT, null, longOut, null);
13326                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13327                longOut[0] = 0;
13328                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13329                        SINGLE_LONG_FORMAT, null, longOut, null);
13330                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13331                longOut[0] = 0;
13332                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13333                        SINGLE_LONG_FORMAT, null, longOut, null);
13334                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13335                if (!isCompact) {
13336                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13337                        pw.print("      KSM: "); pw.print(sharing);
13338                                pw.print(" kB saved from shared ");
13339                                pw.print(shared); pw.println(" kB");
13340                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13341                                pw.print(voltile); pw.println(" kB volatile");
13342                    }
13343                    pw.print("   Tuning: ");
13344                    pw.print(ActivityManager.staticGetMemoryClass());
13345                    pw.print(" (large ");
13346                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13347                    pw.print("), oom ");
13348                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13349                    pw.print(" kB");
13350                    pw.print(", restore limit ");
13351                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13352                    pw.print(" kB");
13353                    if (ActivityManager.isLowRamDeviceStatic()) {
13354                        pw.print(" (low-ram)");
13355                    }
13356                    if (ActivityManager.isHighEndGfx()) {
13357                        pw.print(" (high-end-gfx)");
13358                    }
13359                    pw.println();
13360                } else {
13361                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13362                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13363                    pw.println(voltile);
13364                    pw.print("tuning,");
13365                    pw.print(ActivityManager.staticGetMemoryClass());
13366                    pw.print(',');
13367                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13368                    pw.print(',');
13369                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13370                    if (ActivityManager.isLowRamDeviceStatic()) {
13371                        pw.print(",low-ram");
13372                    }
13373                    if (ActivityManager.isHighEndGfx()) {
13374                        pw.print(",high-end-gfx");
13375                    }
13376                    pw.println();
13377                }
13378            }
13379        }
13380    }
13381
13382    /**
13383     * Searches array of arguments for the specified string
13384     * @param args array of argument strings
13385     * @param value value to search for
13386     * @return true if the value is contained in the array
13387     */
13388    private static boolean scanArgs(String[] args, String value) {
13389        if (args != null) {
13390            for (String arg : args) {
13391                if (value.equals(arg)) {
13392                    return true;
13393                }
13394            }
13395        }
13396        return false;
13397    }
13398
13399    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13400            ContentProviderRecord cpr, boolean always) {
13401        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13402
13403        if (!inLaunching || always) {
13404            synchronized (cpr) {
13405                cpr.launchingApp = null;
13406                cpr.notifyAll();
13407            }
13408            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13409            String names[] = cpr.info.authority.split(";");
13410            for (int j = 0; j < names.length; j++) {
13411                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13412            }
13413        }
13414
13415        for (int i=0; i<cpr.connections.size(); i++) {
13416            ContentProviderConnection conn = cpr.connections.get(i);
13417            if (conn.waiting) {
13418                // If this connection is waiting for the provider, then we don't
13419                // need to mess with its process unless we are always removing
13420                // or for some reason the provider is not currently launching.
13421                if (inLaunching && !always) {
13422                    continue;
13423                }
13424            }
13425            ProcessRecord capp = conn.client;
13426            conn.dead = true;
13427            if (conn.stableCount > 0) {
13428                if (!capp.persistent && capp.thread != null
13429                        && capp.pid != 0
13430                        && capp.pid != MY_PID) {
13431                    killUnneededProcessLocked(capp, "depends on provider "
13432                            + cpr.name.flattenToShortString()
13433                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13434                }
13435            } else if (capp.thread != null && conn.provider.provider != null) {
13436                try {
13437                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13438                } catch (RemoteException e) {
13439                }
13440                // In the protocol here, we don't expect the client to correctly
13441                // clean up this connection, we'll just remove it.
13442                cpr.connections.remove(i);
13443                conn.client.conProviders.remove(conn);
13444            }
13445        }
13446
13447        if (inLaunching && always) {
13448            mLaunchingProviders.remove(cpr);
13449        }
13450        return inLaunching;
13451    }
13452
13453    /**
13454     * Main code for cleaning up a process when it has gone away.  This is
13455     * called both as a result of the process dying, or directly when stopping
13456     * a process when running in single process mode.
13457     */
13458    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13459            boolean restarting, boolean allowRestart, int index) {
13460        if (index >= 0) {
13461            removeLruProcessLocked(app);
13462            ProcessList.remove(app.pid);
13463        }
13464
13465        mProcessesToGc.remove(app);
13466        mPendingPssProcesses.remove(app);
13467
13468        // Dismiss any open dialogs.
13469        if (app.crashDialog != null && !app.forceCrashReport) {
13470            app.crashDialog.dismiss();
13471            app.crashDialog = null;
13472        }
13473        if (app.anrDialog != null) {
13474            app.anrDialog.dismiss();
13475            app.anrDialog = null;
13476        }
13477        if (app.waitDialog != null) {
13478            app.waitDialog.dismiss();
13479            app.waitDialog = null;
13480        }
13481
13482        app.crashing = false;
13483        app.notResponding = false;
13484
13485        app.resetPackageList(mProcessStats);
13486        app.unlinkDeathRecipient();
13487        app.makeInactive(mProcessStats);
13488        app.waitingToKill = null;
13489        app.forcingToForeground = null;
13490        updateProcessForegroundLocked(app, false, false);
13491        app.foregroundActivities = false;
13492        app.hasShownUi = false;
13493        app.treatLikeActivity = false;
13494        app.hasAboveClient = false;
13495        app.hasClientActivities = false;
13496
13497        mServices.killServicesLocked(app, allowRestart);
13498
13499        boolean restart = false;
13500
13501        // Remove published content providers.
13502        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13503            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13504            final boolean always = app.bad || !allowRestart;
13505            if (removeDyingProviderLocked(app, cpr, always) || always) {
13506                // We left the provider in the launching list, need to
13507                // restart it.
13508                restart = true;
13509            }
13510
13511            cpr.provider = null;
13512            cpr.proc = null;
13513        }
13514        app.pubProviders.clear();
13515
13516        // Take care of any launching providers waiting for this process.
13517        if (checkAppInLaunchingProvidersLocked(app, false)) {
13518            restart = true;
13519        }
13520
13521        // Unregister from connected content providers.
13522        if (!app.conProviders.isEmpty()) {
13523            for (int i=0; i<app.conProviders.size(); i++) {
13524                ContentProviderConnection conn = app.conProviders.get(i);
13525                conn.provider.connections.remove(conn);
13526            }
13527            app.conProviders.clear();
13528        }
13529
13530        // At this point there may be remaining entries in mLaunchingProviders
13531        // where we were the only one waiting, so they are no longer of use.
13532        // Look for these and clean up if found.
13533        // XXX Commented out for now.  Trying to figure out a way to reproduce
13534        // the actual situation to identify what is actually going on.
13535        if (false) {
13536            for (int i=0; i<mLaunchingProviders.size(); i++) {
13537                ContentProviderRecord cpr = (ContentProviderRecord)
13538                        mLaunchingProviders.get(i);
13539                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13540                    synchronized (cpr) {
13541                        cpr.launchingApp = null;
13542                        cpr.notifyAll();
13543                    }
13544                }
13545            }
13546        }
13547
13548        skipCurrentReceiverLocked(app);
13549
13550        // Unregister any receivers.
13551        for (int i=app.receivers.size()-1; i>=0; i--) {
13552            removeReceiverLocked(app.receivers.valueAt(i));
13553        }
13554        app.receivers.clear();
13555
13556        // If the app is undergoing backup, tell the backup manager about it
13557        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13558            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13559                    + mBackupTarget.appInfo + " died during backup");
13560            try {
13561                IBackupManager bm = IBackupManager.Stub.asInterface(
13562                        ServiceManager.getService(Context.BACKUP_SERVICE));
13563                bm.agentDisconnected(app.info.packageName);
13564            } catch (RemoteException e) {
13565                // can't happen; backup manager is local
13566            }
13567        }
13568
13569        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13570            ProcessChangeItem item = mPendingProcessChanges.get(i);
13571            if (item.pid == app.pid) {
13572                mPendingProcessChanges.remove(i);
13573                mAvailProcessChanges.add(item);
13574            }
13575        }
13576        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13577
13578        // If the caller is restarting this app, then leave it in its
13579        // current lists and let the caller take care of it.
13580        if (restarting) {
13581            return;
13582        }
13583
13584        if (!app.persistent || app.isolated) {
13585            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13586                    "Removing non-persistent process during cleanup: " + app);
13587            mProcessNames.remove(app.processName, app.uid);
13588            mIsolatedProcesses.remove(app.uid);
13589            if (mHeavyWeightProcess == app) {
13590                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13591                        mHeavyWeightProcess.userId, 0));
13592                mHeavyWeightProcess = null;
13593            }
13594        } else if (!app.removed) {
13595            // This app is persistent, so we need to keep its record around.
13596            // If it is not already on the pending app list, add it there
13597            // and start a new process for it.
13598            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13599                mPersistentStartingProcesses.add(app);
13600                restart = true;
13601            }
13602        }
13603        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13604                "Clean-up removing on hold: " + app);
13605        mProcessesOnHold.remove(app);
13606
13607        if (app == mHomeProcess) {
13608            mHomeProcess = null;
13609        }
13610        if (app == mPreviousProcess) {
13611            mPreviousProcess = null;
13612        }
13613
13614        if (restart && !app.isolated) {
13615            // We have components that still need to be running in the
13616            // process, so re-launch it.
13617            mProcessNames.put(app.processName, app.uid, app);
13618            startProcessLocked(app, "restart", app.processName);
13619        } else if (app.pid > 0 && app.pid != MY_PID) {
13620            // Goodbye!
13621            boolean removed;
13622            synchronized (mPidsSelfLocked) {
13623                mPidsSelfLocked.remove(app.pid);
13624                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13625            }
13626            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13627            if (app.isolated) {
13628                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13629            }
13630            app.setPid(0);
13631        }
13632    }
13633
13634    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13635        // Look through the content providers we are waiting to have launched,
13636        // and if any run in this process then either schedule a restart of
13637        // the process or kill the client waiting for it if this process has
13638        // gone bad.
13639        int NL = mLaunchingProviders.size();
13640        boolean restart = false;
13641        for (int i=0; i<NL; i++) {
13642            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13643            if (cpr.launchingApp == app) {
13644                if (!alwaysBad && !app.bad) {
13645                    restart = true;
13646                } else {
13647                    removeDyingProviderLocked(app, cpr, true);
13648                    // cpr should have been removed from mLaunchingProviders
13649                    NL = mLaunchingProviders.size();
13650                    i--;
13651                }
13652            }
13653        }
13654        return restart;
13655    }
13656
13657    // =========================================================
13658    // SERVICES
13659    // =========================================================
13660
13661    @Override
13662    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13663            int flags) {
13664        enforceNotIsolatedCaller("getServices");
13665        synchronized (this) {
13666            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13667        }
13668    }
13669
13670    @Override
13671    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13672        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13673        synchronized (this) {
13674            return mServices.getRunningServiceControlPanelLocked(name);
13675        }
13676    }
13677
13678    @Override
13679    public ComponentName startService(IApplicationThread caller, Intent service,
13680            String resolvedType, int userId) {
13681        enforceNotIsolatedCaller("startService");
13682        // Refuse possible leaked file descriptors
13683        if (service != null && service.hasFileDescriptors() == true) {
13684            throw new IllegalArgumentException("File descriptors passed in Intent");
13685        }
13686
13687        if (DEBUG_SERVICE)
13688            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13689        synchronized(this) {
13690            final int callingPid = Binder.getCallingPid();
13691            final int callingUid = Binder.getCallingUid();
13692            final long origId = Binder.clearCallingIdentity();
13693            ComponentName res = mServices.startServiceLocked(caller, service,
13694                    resolvedType, callingPid, callingUid, userId);
13695            Binder.restoreCallingIdentity(origId);
13696            return res;
13697        }
13698    }
13699
13700    ComponentName startServiceInPackage(int uid,
13701            Intent service, String resolvedType, int userId) {
13702        synchronized(this) {
13703            if (DEBUG_SERVICE)
13704                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13705            final long origId = Binder.clearCallingIdentity();
13706            ComponentName res = mServices.startServiceLocked(null, service,
13707                    resolvedType, -1, uid, userId);
13708            Binder.restoreCallingIdentity(origId);
13709            return res;
13710        }
13711    }
13712
13713    @Override
13714    public int stopService(IApplicationThread caller, Intent service,
13715            String resolvedType, int userId) {
13716        enforceNotIsolatedCaller("stopService");
13717        // Refuse possible leaked file descriptors
13718        if (service != null && service.hasFileDescriptors() == true) {
13719            throw new IllegalArgumentException("File descriptors passed in Intent");
13720        }
13721
13722        synchronized(this) {
13723            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13724        }
13725    }
13726
13727    @Override
13728    public IBinder peekService(Intent service, String resolvedType) {
13729        enforceNotIsolatedCaller("peekService");
13730        // Refuse possible leaked file descriptors
13731        if (service != null && service.hasFileDescriptors() == true) {
13732            throw new IllegalArgumentException("File descriptors passed in Intent");
13733        }
13734        synchronized(this) {
13735            return mServices.peekServiceLocked(service, resolvedType);
13736        }
13737    }
13738
13739    @Override
13740    public boolean stopServiceToken(ComponentName className, IBinder token,
13741            int startId) {
13742        synchronized(this) {
13743            return mServices.stopServiceTokenLocked(className, token, startId);
13744        }
13745    }
13746
13747    @Override
13748    public void setServiceForeground(ComponentName className, IBinder token,
13749            int id, Notification notification, boolean removeNotification) {
13750        synchronized(this) {
13751            mServices.setServiceForegroundLocked(className, token, id, notification,
13752                    removeNotification);
13753        }
13754    }
13755
13756    @Override
13757    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13758            boolean requireFull, String name, String callerPackage) {
13759        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13760                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13761    }
13762
13763    int unsafeConvertIncomingUser(int userId) {
13764        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13765                ? mCurrentUserId : userId;
13766    }
13767
13768    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13769            int allowMode, String name, String callerPackage) {
13770        final int callingUserId = UserHandle.getUserId(callingUid);
13771        if (callingUserId == userId) {
13772            return userId;
13773        }
13774
13775        // Note that we may be accessing mCurrentUserId outside of a lock...
13776        // shouldn't be a big deal, if this is being called outside
13777        // of a locked context there is intrinsically a race with
13778        // the value the caller will receive and someone else changing it.
13779        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13780        // we will switch to the calling user if access to the current user fails.
13781        int targetUserId = unsafeConvertIncomingUser(userId);
13782
13783        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13784            final boolean allow;
13785            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13786                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13787                // If the caller has this permission, they always pass go.  And collect $200.
13788                allow = true;
13789            } else if (allowMode == ALLOW_FULL_ONLY) {
13790                // We require full access, sucks to be you.
13791                allow = false;
13792            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13793                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13794                // If the caller does not have either permission, they are always doomed.
13795                allow = false;
13796            } else if (allowMode == ALLOW_NON_FULL) {
13797                // We are blanket allowing non-full access, you lucky caller!
13798                allow = true;
13799            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13800                // We may or may not allow this depending on whether the two users are
13801                // in the same profile.
13802                synchronized (mUserProfileGroupIdsSelfLocked) {
13803                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13804                            UserInfo.NO_PROFILE_GROUP_ID);
13805                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13806                            UserInfo.NO_PROFILE_GROUP_ID);
13807                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13808                            && callingProfile == targetProfile;
13809                }
13810            } else {
13811                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13812            }
13813            if (!allow) {
13814                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13815                    // In this case, they would like to just execute as their
13816                    // owner user instead of failing.
13817                    targetUserId = callingUserId;
13818                } else {
13819                    StringBuilder builder = new StringBuilder(128);
13820                    builder.append("Permission Denial: ");
13821                    builder.append(name);
13822                    if (callerPackage != null) {
13823                        builder.append(" from ");
13824                        builder.append(callerPackage);
13825                    }
13826                    builder.append(" asks to run as user ");
13827                    builder.append(userId);
13828                    builder.append(" but is calling from user ");
13829                    builder.append(UserHandle.getUserId(callingUid));
13830                    builder.append("; this requires ");
13831                    builder.append(INTERACT_ACROSS_USERS_FULL);
13832                    if (allowMode != ALLOW_FULL_ONLY) {
13833                        builder.append(" or ");
13834                        builder.append(INTERACT_ACROSS_USERS);
13835                    }
13836                    String msg = builder.toString();
13837                    Slog.w(TAG, msg);
13838                    throw new SecurityException(msg);
13839                }
13840            }
13841        }
13842        if (!allowAll && targetUserId < 0) {
13843            throw new IllegalArgumentException(
13844                    "Call does not support special user #" + targetUserId);
13845        }
13846        return targetUserId;
13847    }
13848
13849    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13850            String className, int flags) {
13851        boolean result = false;
13852        // For apps that don't have pre-defined UIDs, check for permission
13853        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13854            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13855                if (ActivityManager.checkUidPermission(
13856                        INTERACT_ACROSS_USERS,
13857                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13858                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13859                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13860                            + " requests FLAG_SINGLE_USER, but app does not hold "
13861                            + INTERACT_ACROSS_USERS;
13862                    Slog.w(TAG, msg);
13863                    throw new SecurityException(msg);
13864                }
13865                // Permission passed
13866                result = true;
13867            }
13868        } else if ("system".equals(componentProcessName)) {
13869            result = true;
13870        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
13871                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13872            // Phone app is allowed to export singleuser providers.
13873            result = true;
13874        } else {
13875            // App with pre-defined UID, check if it's a persistent app
13876            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13877        }
13878        if (DEBUG_MU) {
13879            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13880                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13881        }
13882        return result;
13883    }
13884
13885    /**
13886     * Checks to see if the caller is in the same app as the singleton
13887     * component, or the component is in a special app. It allows special apps
13888     * to export singleton components but prevents exporting singleton
13889     * components for regular apps.
13890     */
13891    boolean isValidSingletonCall(int callingUid, int componentUid) {
13892        int componentAppId = UserHandle.getAppId(componentUid);
13893        return UserHandle.isSameApp(callingUid, componentUid)
13894                || componentAppId == Process.SYSTEM_UID
13895                || componentAppId == Process.PHONE_UID
13896                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13897                        == PackageManager.PERMISSION_GRANTED;
13898    }
13899
13900    public int bindService(IApplicationThread caller, IBinder token,
13901            Intent service, String resolvedType,
13902            IServiceConnection connection, int flags, int userId) {
13903        enforceNotIsolatedCaller("bindService");
13904        // Refuse possible leaked file descriptors
13905        if (service != null && service.hasFileDescriptors() == true) {
13906            throw new IllegalArgumentException("File descriptors passed in Intent");
13907        }
13908
13909        synchronized(this) {
13910            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13911                    connection, flags, userId);
13912        }
13913    }
13914
13915    public boolean unbindService(IServiceConnection connection) {
13916        synchronized (this) {
13917            return mServices.unbindServiceLocked(connection);
13918        }
13919    }
13920
13921    public void publishService(IBinder token, Intent intent, IBinder service) {
13922        // Refuse possible leaked file descriptors
13923        if (intent != null && intent.hasFileDescriptors() == true) {
13924            throw new IllegalArgumentException("File descriptors passed in Intent");
13925        }
13926
13927        synchronized(this) {
13928            if (!(token instanceof ServiceRecord)) {
13929                throw new IllegalArgumentException("Invalid service token");
13930            }
13931            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13932        }
13933    }
13934
13935    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13936        // Refuse possible leaked file descriptors
13937        if (intent != null && intent.hasFileDescriptors() == true) {
13938            throw new IllegalArgumentException("File descriptors passed in Intent");
13939        }
13940
13941        synchronized(this) {
13942            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13943        }
13944    }
13945
13946    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13947        synchronized(this) {
13948            if (!(token instanceof ServiceRecord)) {
13949                throw new IllegalArgumentException("Invalid service token");
13950            }
13951            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13952        }
13953    }
13954
13955    // =========================================================
13956    // BACKUP AND RESTORE
13957    // =========================================================
13958
13959    // Cause the target app to be launched if necessary and its backup agent
13960    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13961    // activity manager to announce its creation.
13962    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13963        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13964        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13965
13966        synchronized(this) {
13967            // !!! TODO: currently no check here that we're already bound
13968            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13969            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13970            synchronized (stats) {
13971                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13972            }
13973
13974            // Backup agent is now in use, its package can't be stopped.
13975            try {
13976                AppGlobals.getPackageManager().setPackageStoppedState(
13977                        app.packageName, false, UserHandle.getUserId(app.uid));
13978            } catch (RemoteException e) {
13979            } catch (IllegalArgumentException e) {
13980                Slog.w(TAG, "Failed trying to unstop package "
13981                        + app.packageName + ": " + e);
13982            }
13983
13984            BackupRecord r = new BackupRecord(ss, app, backupMode);
13985            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13986                    ? new ComponentName(app.packageName, app.backupAgentName)
13987                    : new ComponentName("android", "FullBackupAgent");
13988            // startProcessLocked() returns existing proc's record if it's already running
13989            ProcessRecord proc = startProcessLocked(app.processName, app,
13990                    false, 0, "backup", hostingName, false, false, false);
13991            if (proc == null) {
13992                Slog.e(TAG, "Unable to start backup agent process " + r);
13993                return false;
13994            }
13995
13996            r.app = proc;
13997            mBackupTarget = r;
13998            mBackupAppName = app.packageName;
13999
14000            // Try not to kill the process during backup
14001            updateOomAdjLocked(proc);
14002
14003            // If the process is already attached, schedule the creation of the backup agent now.
14004            // If it is not yet live, this will be done when it attaches to the framework.
14005            if (proc.thread != null) {
14006                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14007                try {
14008                    proc.thread.scheduleCreateBackupAgent(app,
14009                            compatibilityInfoForPackageLocked(app), backupMode);
14010                } catch (RemoteException e) {
14011                    // Will time out on the backup manager side
14012                }
14013            } else {
14014                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14015            }
14016            // Invariants: at this point, the target app process exists and the application
14017            // is either already running or in the process of coming up.  mBackupTarget and
14018            // mBackupAppName describe the app, so that when it binds back to the AM we
14019            // know that it's scheduled for a backup-agent operation.
14020        }
14021
14022        return true;
14023    }
14024
14025    @Override
14026    public void clearPendingBackup() {
14027        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14028        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14029
14030        synchronized (this) {
14031            mBackupTarget = null;
14032            mBackupAppName = null;
14033        }
14034    }
14035
14036    // A backup agent has just come up
14037    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14038        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14039                + " = " + agent);
14040
14041        synchronized(this) {
14042            if (!agentPackageName.equals(mBackupAppName)) {
14043                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14044                return;
14045            }
14046        }
14047
14048        long oldIdent = Binder.clearCallingIdentity();
14049        try {
14050            IBackupManager bm = IBackupManager.Stub.asInterface(
14051                    ServiceManager.getService(Context.BACKUP_SERVICE));
14052            bm.agentConnected(agentPackageName, agent);
14053        } catch (RemoteException e) {
14054            // can't happen; the backup manager service is local
14055        } catch (Exception e) {
14056            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14057            e.printStackTrace();
14058        } finally {
14059            Binder.restoreCallingIdentity(oldIdent);
14060        }
14061    }
14062
14063    // done with this agent
14064    public void unbindBackupAgent(ApplicationInfo appInfo) {
14065        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14066        if (appInfo == null) {
14067            Slog.w(TAG, "unbind backup agent for null app");
14068            return;
14069        }
14070
14071        synchronized(this) {
14072            try {
14073                if (mBackupAppName == null) {
14074                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14075                    return;
14076                }
14077
14078                if (!mBackupAppName.equals(appInfo.packageName)) {
14079                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14080                    return;
14081                }
14082
14083                // Not backing this app up any more; reset its OOM adjustment
14084                final ProcessRecord proc = mBackupTarget.app;
14085                updateOomAdjLocked(proc);
14086
14087                // If the app crashed during backup, 'thread' will be null here
14088                if (proc.thread != null) {
14089                    try {
14090                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14091                                compatibilityInfoForPackageLocked(appInfo));
14092                    } catch (Exception e) {
14093                        Slog.e(TAG, "Exception when unbinding backup agent:");
14094                        e.printStackTrace();
14095                    }
14096                }
14097            } finally {
14098                mBackupTarget = null;
14099                mBackupAppName = null;
14100            }
14101        }
14102    }
14103    // =========================================================
14104    // BROADCASTS
14105    // =========================================================
14106
14107    private final List getStickiesLocked(String action, IntentFilter filter,
14108            List cur, int userId) {
14109        final ContentResolver resolver = mContext.getContentResolver();
14110        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14111        if (stickies == null) {
14112            return cur;
14113        }
14114        final ArrayList<Intent> list = stickies.get(action);
14115        if (list == null) {
14116            return cur;
14117        }
14118        int N = list.size();
14119        for (int i=0; i<N; i++) {
14120            Intent intent = list.get(i);
14121            if (filter.match(resolver, intent, true, TAG) >= 0) {
14122                if (cur == null) {
14123                    cur = new ArrayList<Intent>();
14124                }
14125                cur.add(intent);
14126            }
14127        }
14128        return cur;
14129    }
14130
14131    boolean isPendingBroadcastProcessLocked(int pid) {
14132        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14133                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14134    }
14135
14136    void skipPendingBroadcastLocked(int pid) {
14137            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14138            for (BroadcastQueue queue : mBroadcastQueues) {
14139                queue.skipPendingBroadcastLocked(pid);
14140            }
14141    }
14142
14143    // The app just attached; send any pending broadcasts that it should receive
14144    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14145        boolean didSomething = false;
14146        for (BroadcastQueue queue : mBroadcastQueues) {
14147            didSomething |= queue.sendPendingBroadcastsLocked(app);
14148        }
14149        return didSomething;
14150    }
14151
14152    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14153            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14154        enforceNotIsolatedCaller("registerReceiver");
14155        int callingUid;
14156        int callingPid;
14157        synchronized(this) {
14158            ProcessRecord callerApp = null;
14159            if (caller != null) {
14160                callerApp = getRecordForAppLocked(caller);
14161                if (callerApp == null) {
14162                    throw new SecurityException(
14163                            "Unable to find app for caller " + caller
14164                            + " (pid=" + Binder.getCallingPid()
14165                            + ") when registering receiver " + receiver);
14166                }
14167                if (callerApp.info.uid != Process.SYSTEM_UID &&
14168                        !callerApp.pkgList.containsKey(callerPackage) &&
14169                        !"android".equals(callerPackage)) {
14170                    throw new SecurityException("Given caller package " + callerPackage
14171                            + " is not running in process " + callerApp);
14172                }
14173                callingUid = callerApp.info.uid;
14174                callingPid = callerApp.pid;
14175            } else {
14176                callerPackage = null;
14177                callingUid = Binder.getCallingUid();
14178                callingPid = Binder.getCallingPid();
14179            }
14180
14181            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14182                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14183
14184            List allSticky = null;
14185
14186            // Look for any matching sticky broadcasts...
14187            Iterator actions = filter.actionsIterator();
14188            if (actions != null) {
14189                while (actions.hasNext()) {
14190                    String action = (String)actions.next();
14191                    allSticky = getStickiesLocked(action, filter, allSticky,
14192                            UserHandle.USER_ALL);
14193                    allSticky = getStickiesLocked(action, filter, allSticky,
14194                            UserHandle.getUserId(callingUid));
14195                }
14196            } else {
14197                allSticky = getStickiesLocked(null, filter, allSticky,
14198                        UserHandle.USER_ALL);
14199                allSticky = getStickiesLocked(null, filter, allSticky,
14200                        UserHandle.getUserId(callingUid));
14201            }
14202
14203            // The first sticky in the list is returned directly back to
14204            // the client.
14205            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14206
14207            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14208                    + ": " + sticky);
14209
14210            if (receiver == null) {
14211                return sticky;
14212            }
14213
14214            ReceiverList rl
14215                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14216            if (rl == null) {
14217                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14218                        userId, receiver);
14219                if (rl.app != null) {
14220                    rl.app.receivers.add(rl);
14221                } else {
14222                    try {
14223                        receiver.asBinder().linkToDeath(rl, 0);
14224                    } catch (RemoteException e) {
14225                        return sticky;
14226                    }
14227                    rl.linkedToDeath = true;
14228                }
14229                mRegisteredReceivers.put(receiver.asBinder(), rl);
14230            } else if (rl.uid != callingUid) {
14231                throw new IllegalArgumentException(
14232                        "Receiver requested to register for uid " + callingUid
14233                        + " was previously registered for uid " + rl.uid);
14234            } else if (rl.pid != callingPid) {
14235                throw new IllegalArgumentException(
14236                        "Receiver requested to register for pid " + callingPid
14237                        + " was previously registered for pid " + rl.pid);
14238            } else if (rl.userId != userId) {
14239                throw new IllegalArgumentException(
14240                        "Receiver requested to register for user " + userId
14241                        + " was previously registered for user " + rl.userId);
14242            }
14243            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14244                    permission, callingUid, userId);
14245            rl.add(bf);
14246            if (!bf.debugCheck()) {
14247                Slog.w(TAG, "==> For Dynamic broadast");
14248            }
14249            mReceiverResolver.addFilter(bf);
14250
14251            // Enqueue broadcasts for all existing stickies that match
14252            // this filter.
14253            if (allSticky != null) {
14254                ArrayList receivers = new ArrayList();
14255                receivers.add(bf);
14256
14257                int N = allSticky.size();
14258                for (int i=0; i<N; i++) {
14259                    Intent intent = (Intent)allSticky.get(i);
14260                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14261                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14262                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14263                            null, null, false, true, true, -1);
14264                    queue.enqueueParallelBroadcastLocked(r);
14265                    queue.scheduleBroadcastsLocked();
14266                }
14267            }
14268
14269            return sticky;
14270        }
14271    }
14272
14273    public void unregisterReceiver(IIntentReceiver receiver) {
14274        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14275
14276        final long origId = Binder.clearCallingIdentity();
14277        try {
14278            boolean doTrim = false;
14279
14280            synchronized(this) {
14281                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14282                if (rl != null) {
14283                    if (rl.curBroadcast != null) {
14284                        BroadcastRecord r = rl.curBroadcast;
14285                        final boolean doNext = finishReceiverLocked(
14286                                receiver.asBinder(), r.resultCode, r.resultData,
14287                                r.resultExtras, r.resultAbort);
14288                        if (doNext) {
14289                            doTrim = true;
14290                            r.queue.processNextBroadcast(false);
14291                        }
14292                    }
14293
14294                    if (rl.app != null) {
14295                        rl.app.receivers.remove(rl);
14296                    }
14297                    removeReceiverLocked(rl);
14298                    if (rl.linkedToDeath) {
14299                        rl.linkedToDeath = false;
14300                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14301                    }
14302                }
14303            }
14304
14305            // If we actually concluded any broadcasts, we might now be able
14306            // to trim the recipients' apps from our working set
14307            if (doTrim) {
14308                trimApplications();
14309                return;
14310            }
14311
14312        } finally {
14313            Binder.restoreCallingIdentity(origId);
14314        }
14315    }
14316
14317    void removeReceiverLocked(ReceiverList rl) {
14318        mRegisteredReceivers.remove(rl.receiver.asBinder());
14319        int N = rl.size();
14320        for (int i=0; i<N; i++) {
14321            mReceiverResolver.removeFilter(rl.get(i));
14322        }
14323    }
14324
14325    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14326        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14327            ProcessRecord r = mLruProcesses.get(i);
14328            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14329                try {
14330                    r.thread.dispatchPackageBroadcast(cmd, packages);
14331                } catch (RemoteException ex) {
14332                }
14333            }
14334        }
14335    }
14336
14337    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14338            int[] users) {
14339        List<ResolveInfo> receivers = null;
14340        try {
14341            HashSet<ComponentName> singleUserReceivers = null;
14342            boolean scannedFirstReceivers = false;
14343            for (int user : users) {
14344                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14345                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14346                if (user != 0 && newReceivers != null) {
14347                    // If this is not the primary user, we need to check for
14348                    // any receivers that should be filtered out.
14349                    for (int i=0; i<newReceivers.size(); i++) {
14350                        ResolveInfo ri = newReceivers.get(i);
14351                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14352                            newReceivers.remove(i);
14353                            i--;
14354                        }
14355                    }
14356                }
14357                if (newReceivers != null && newReceivers.size() == 0) {
14358                    newReceivers = null;
14359                }
14360                if (receivers == null) {
14361                    receivers = newReceivers;
14362                } else if (newReceivers != null) {
14363                    // We need to concatenate the additional receivers
14364                    // found with what we have do far.  This would be easy,
14365                    // but we also need to de-dup any receivers that are
14366                    // singleUser.
14367                    if (!scannedFirstReceivers) {
14368                        // Collect any single user receivers we had already retrieved.
14369                        scannedFirstReceivers = true;
14370                        for (int i=0; i<receivers.size(); i++) {
14371                            ResolveInfo ri = receivers.get(i);
14372                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14373                                ComponentName cn = new ComponentName(
14374                                        ri.activityInfo.packageName, ri.activityInfo.name);
14375                                if (singleUserReceivers == null) {
14376                                    singleUserReceivers = new HashSet<ComponentName>();
14377                                }
14378                                singleUserReceivers.add(cn);
14379                            }
14380                        }
14381                    }
14382                    // Add the new results to the existing results, tracking
14383                    // and de-dupping single user receivers.
14384                    for (int i=0; i<newReceivers.size(); i++) {
14385                        ResolveInfo ri = newReceivers.get(i);
14386                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14387                            ComponentName cn = new ComponentName(
14388                                    ri.activityInfo.packageName, ri.activityInfo.name);
14389                            if (singleUserReceivers == null) {
14390                                singleUserReceivers = new HashSet<ComponentName>();
14391                            }
14392                            if (!singleUserReceivers.contains(cn)) {
14393                                singleUserReceivers.add(cn);
14394                                receivers.add(ri);
14395                            }
14396                        } else {
14397                            receivers.add(ri);
14398                        }
14399                    }
14400                }
14401            }
14402        } catch (RemoteException ex) {
14403            // pm is in same process, this will never happen.
14404        }
14405        return receivers;
14406    }
14407
14408    private final int broadcastIntentLocked(ProcessRecord callerApp,
14409            String callerPackage, Intent intent, String resolvedType,
14410            IIntentReceiver resultTo, int resultCode, String resultData,
14411            Bundle map, String requiredPermission, int appOp,
14412            boolean ordered, boolean sticky, int callingPid, int callingUid,
14413            int userId) {
14414        intent = new Intent(intent);
14415
14416        // By default broadcasts do not go to stopped apps.
14417        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14418
14419        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14420            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14421            + " ordered=" + ordered + " userid=" + userId);
14422        if ((resultTo != null) && !ordered) {
14423            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14424        }
14425
14426        userId = handleIncomingUser(callingPid, callingUid, userId,
14427                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14428
14429        // Make sure that the user who is receiving this broadcast is started.
14430        // If not, we will just skip it.
14431
14432
14433        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14434            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14435                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14436                Slog.w(TAG, "Skipping broadcast of " + intent
14437                        + ": user " + userId + " is stopped");
14438                return ActivityManager.BROADCAST_SUCCESS;
14439            }
14440        }
14441
14442        /*
14443         * Prevent non-system code (defined here to be non-persistent
14444         * processes) from sending protected broadcasts.
14445         */
14446        int callingAppId = UserHandle.getAppId(callingUid);
14447        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14448            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14449            || callingAppId == Process.NFC_UID || callingUid == 0) {
14450            // Always okay.
14451        } else if (callerApp == null || !callerApp.persistent) {
14452            try {
14453                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14454                        intent.getAction())) {
14455                    String msg = "Permission Denial: not allowed to send broadcast "
14456                            + intent.getAction() + " from pid="
14457                            + callingPid + ", uid=" + callingUid;
14458                    Slog.w(TAG, msg);
14459                    throw new SecurityException(msg);
14460                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14461                    // Special case for compatibility: we don't want apps to send this,
14462                    // but historically it has not been protected and apps may be using it
14463                    // to poke their own app widget.  So, instead of making it protected,
14464                    // just limit it to the caller.
14465                    if (callerApp == null) {
14466                        String msg = "Permission Denial: not allowed to send broadcast "
14467                                + intent.getAction() + " from unknown caller.";
14468                        Slog.w(TAG, msg);
14469                        throw new SecurityException(msg);
14470                    } else if (intent.getComponent() != null) {
14471                        // They are good enough to send to an explicit component...  verify
14472                        // it is being sent to the calling app.
14473                        if (!intent.getComponent().getPackageName().equals(
14474                                callerApp.info.packageName)) {
14475                            String msg = "Permission Denial: not allowed to send broadcast "
14476                                    + intent.getAction() + " to "
14477                                    + intent.getComponent().getPackageName() + " from "
14478                                    + callerApp.info.packageName;
14479                            Slog.w(TAG, msg);
14480                            throw new SecurityException(msg);
14481                        }
14482                    } else {
14483                        // Limit broadcast to their own package.
14484                        intent.setPackage(callerApp.info.packageName);
14485                    }
14486                }
14487            } catch (RemoteException e) {
14488                Slog.w(TAG, "Remote exception", e);
14489                return ActivityManager.BROADCAST_SUCCESS;
14490            }
14491        }
14492
14493        // Handle special intents: if this broadcast is from the package
14494        // manager about a package being removed, we need to remove all of
14495        // its activities from the history stack.
14496        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14497                intent.getAction());
14498        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14499                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14500                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14501                || uidRemoved) {
14502            if (checkComponentPermission(
14503                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14504                    callingPid, callingUid, -1, true)
14505                    == PackageManager.PERMISSION_GRANTED) {
14506                if (uidRemoved) {
14507                    final Bundle intentExtras = intent.getExtras();
14508                    final int uid = intentExtras != null
14509                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14510                    if (uid >= 0) {
14511                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14512                        synchronized (bs) {
14513                            bs.removeUidStatsLocked(uid);
14514                        }
14515                        mAppOpsService.uidRemoved(uid);
14516                    }
14517                } else {
14518                    // If resources are unavailable just force stop all
14519                    // those packages and flush the attribute cache as well.
14520                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14521                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14522                        if (list != null && (list.length > 0)) {
14523                            for (String pkg : list) {
14524                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14525                                        "storage unmount");
14526                            }
14527                            sendPackageBroadcastLocked(
14528                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14529                        }
14530                    } else {
14531                        Uri data = intent.getData();
14532                        String ssp;
14533                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14534                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14535                                    intent.getAction());
14536                            boolean fullUninstall = removed &&
14537                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14538                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14539                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14540                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14541                                        false, fullUninstall, userId,
14542                                        removed ? "pkg removed" : "pkg changed");
14543                            }
14544                            if (removed) {
14545                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14546                                        new String[] {ssp}, userId);
14547                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14548                                    mAppOpsService.packageRemoved(
14549                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14550
14551                                    // Remove all permissions granted from/to this package
14552                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14553                                }
14554                            }
14555                        }
14556                    }
14557                }
14558            } else {
14559                String msg = "Permission Denial: " + intent.getAction()
14560                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14561                        + ", uid=" + callingUid + ")"
14562                        + " requires "
14563                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14564                Slog.w(TAG, msg);
14565                throw new SecurityException(msg);
14566            }
14567
14568        // Special case for adding a package: by default turn on compatibility
14569        // mode.
14570        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14571            Uri data = intent.getData();
14572            String ssp;
14573            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14574                mCompatModePackages.handlePackageAddedLocked(ssp,
14575                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14576            }
14577        }
14578
14579        /*
14580         * If this is the time zone changed action, queue up a message that will reset the timezone
14581         * of all currently running processes. This message will get queued up before the broadcast
14582         * happens.
14583         */
14584        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14585            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14586        }
14587
14588        /*
14589         * If the user set the time, let all running processes know.
14590         */
14591        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14592            final int is24Hour = intent.getBooleanExtra(
14593                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14594            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14595        }
14596
14597        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14598            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14599        }
14600
14601        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14602            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14603            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14604        }
14605
14606        // Add to the sticky list if requested.
14607        if (sticky) {
14608            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14609                    callingPid, callingUid)
14610                    != PackageManager.PERMISSION_GRANTED) {
14611                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14612                        + callingPid + ", uid=" + callingUid
14613                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14614                Slog.w(TAG, msg);
14615                throw new SecurityException(msg);
14616            }
14617            if (requiredPermission != null) {
14618                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14619                        + " and enforce permission " + requiredPermission);
14620                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14621            }
14622            if (intent.getComponent() != null) {
14623                throw new SecurityException(
14624                        "Sticky broadcasts can't target a specific component");
14625            }
14626            // We use userId directly here, since the "all" target is maintained
14627            // as a separate set of sticky broadcasts.
14628            if (userId != UserHandle.USER_ALL) {
14629                // But first, if this is not a broadcast to all users, then
14630                // make sure it doesn't conflict with an existing broadcast to
14631                // all users.
14632                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14633                        UserHandle.USER_ALL);
14634                if (stickies != null) {
14635                    ArrayList<Intent> list = stickies.get(intent.getAction());
14636                    if (list != null) {
14637                        int N = list.size();
14638                        int i;
14639                        for (i=0; i<N; i++) {
14640                            if (intent.filterEquals(list.get(i))) {
14641                                throw new IllegalArgumentException(
14642                                        "Sticky broadcast " + intent + " for user "
14643                                        + userId + " conflicts with existing global broadcast");
14644                            }
14645                        }
14646                    }
14647                }
14648            }
14649            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14650            if (stickies == null) {
14651                stickies = new ArrayMap<String, ArrayList<Intent>>();
14652                mStickyBroadcasts.put(userId, stickies);
14653            }
14654            ArrayList<Intent> list = stickies.get(intent.getAction());
14655            if (list == null) {
14656                list = new ArrayList<Intent>();
14657                stickies.put(intent.getAction(), list);
14658            }
14659            int N = list.size();
14660            int i;
14661            for (i=0; i<N; i++) {
14662                if (intent.filterEquals(list.get(i))) {
14663                    // This sticky already exists, replace it.
14664                    list.set(i, new Intent(intent));
14665                    break;
14666                }
14667            }
14668            if (i >= N) {
14669                list.add(new Intent(intent));
14670            }
14671        }
14672
14673        int[] users;
14674        if (userId == UserHandle.USER_ALL) {
14675            // Caller wants broadcast to go to all started users.
14676            users = mStartedUserArray;
14677        } else {
14678            // Caller wants broadcast to go to one specific user.
14679            users = new int[] {userId};
14680        }
14681
14682        // Figure out who all will receive this broadcast.
14683        List receivers = null;
14684        List<BroadcastFilter> registeredReceivers = null;
14685        // Need to resolve the intent to interested receivers...
14686        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14687                 == 0) {
14688            receivers = collectReceiverComponents(intent, resolvedType, users);
14689        }
14690        if (intent.getComponent() == null) {
14691            registeredReceivers = mReceiverResolver.queryIntent(intent,
14692                    resolvedType, false, userId);
14693        }
14694
14695        final boolean replacePending =
14696                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14697
14698        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14699                + " replacePending=" + replacePending);
14700
14701        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14702        if (!ordered && NR > 0) {
14703            // If we are not serializing this broadcast, then send the
14704            // registered receivers separately so they don't wait for the
14705            // components to be launched.
14706            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14707            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14708                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14709                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14710                    ordered, sticky, false, userId);
14711            if (DEBUG_BROADCAST) Slog.v(
14712                    TAG, "Enqueueing parallel broadcast " + r);
14713            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14714            if (!replaced) {
14715                queue.enqueueParallelBroadcastLocked(r);
14716                queue.scheduleBroadcastsLocked();
14717            }
14718            registeredReceivers = null;
14719            NR = 0;
14720        }
14721
14722        // Merge into one list.
14723        int ir = 0;
14724        if (receivers != null) {
14725            // A special case for PACKAGE_ADDED: do not allow the package
14726            // being added to see this broadcast.  This prevents them from
14727            // using this as a back door to get run as soon as they are
14728            // installed.  Maybe in the future we want to have a special install
14729            // broadcast or such for apps, but we'd like to deliberately make
14730            // this decision.
14731            String skipPackages[] = null;
14732            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14733                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14734                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14735                Uri data = intent.getData();
14736                if (data != null) {
14737                    String pkgName = data.getSchemeSpecificPart();
14738                    if (pkgName != null) {
14739                        skipPackages = new String[] { pkgName };
14740                    }
14741                }
14742            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14743                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14744            }
14745            if (skipPackages != null && (skipPackages.length > 0)) {
14746                for (String skipPackage : skipPackages) {
14747                    if (skipPackage != null) {
14748                        int NT = receivers.size();
14749                        for (int it=0; it<NT; it++) {
14750                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14751                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14752                                receivers.remove(it);
14753                                it--;
14754                                NT--;
14755                            }
14756                        }
14757                    }
14758                }
14759            }
14760
14761            int NT = receivers != null ? receivers.size() : 0;
14762            int it = 0;
14763            ResolveInfo curt = null;
14764            BroadcastFilter curr = null;
14765            while (it < NT && ir < NR) {
14766                if (curt == null) {
14767                    curt = (ResolveInfo)receivers.get(it);
14768                }
14769                if (curr == null) {
14770                    curr = registeredReceivers.get(ir);
14771                }
14772                if (curr.getPriority() >= curt.priority) {
14773                    // Insert this broadcast record into the final list.
14774                    receivers.add(it, curr);
14775                    ir++;
14776                    curr = null;
14777                    it++;
14778                    NT++;
14779                } else {
14780                    // Skip to the next ResolveInfo in the final list.
14781                    it++;
14782                    curt = null;
14783                }
14784            }
14785        }
14786        while (ir < NR) {
14787            if (receivers == null) {
14788                receivers = new ArrayList();
14789            }
14790            receivers.add(registeredReceivers.get(ir));
14791            ir++;
14792        }
14793
14794        if ((receivers != null && receivers.size() > 0)
14795                || resultTo != null) {
14796            BroadcastQueue queue = broadcastQueueForIntent(intent);
14797            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14798                    callerPackage, callingPid, callingUid, resolvedType,
14799                    requiredPermission, appOp, receivers, resultTo, resultCode,
14800                    resultData, map, ordered, sticky, false, userId);
14801            if (DEBUG_BROADCAST) Slog.v(
14802                    TAG, "Enqueueing ordered broadcast " + r
14803                    + ": prev had " + queue.mOrderedBroadcasts.size());
14804            if (DEBUG_BROADCAST) {
14805                int seq = r.intent.getIntExtra("seq", -1);
14806                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14807            }
14808            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14809            if (!replaced) {
14810                queue.enqueueOrderedBroadcastLocked(r);
14811                queue.scheduleBroadcastsLocked();
14812            }
14813        }
14814
14815        return ActivityManager.BROADCAST_SUCCESS;
14816    }
14817
14818    final Intent verifyBroadcastLocked(Intent intent) {
14819        // Refuse possible leaked file descriptors
14820        if (intent != null && intent.hasFileDescriptors() == true) {
14821            throw new IllegalArgumentException("File descriptors passed in Intent");
14822        }
14823
14824        int flags = intent.getFlags();
14825
14826        if (!mProcessesReady) {
14827            // if the caller really truly claims to know what they're doing, go
14828            // ahead and allow the broadcast without launching any receivers
14829            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14830                intent = new Intent(intent);
14831                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14832            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14833                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14834                        + " before boot completion");
14835                throw new IllegalStateException("Cannot broadcast before boot completed");
14836            }
14837        }
14838
14839        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14840            throw new IllegalArgumentException(
14841                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14842        }
14843
14844        return intent;
14845    }
14846
14847    public final int broadcastIntent(IApplicationThread caller,
14848            Intent intent, String resolvedType, IIntentReceiver resultTo,
14849            int resultCode, String resultData, Bundle map,
14850            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14851        enforceNotIsolatedCaller("broadcastIntent");
14852        synchronized(this) {
14853            intent = verifyBroadcastLocked(intent);
14854
14855            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14856            final int callingPid = Binder.getCallingPid();
14857            final int callingUid = Binder.getCallingUid();
14858            final long origId = Binder.clearCallingIdentity();
14859            int res = broadcastIntentLocked(callerApp,
14860                    callerApp != null ? callerApp.info.packageName : null,
14861                    intent, resolvedType, resultTo,
14862                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14863                    callingPid, callingUid, userId);
14864            Binder.restoreCallingIdentity(origId);
14865            return res;
14866        }
14867    }
14868
14869    int broadcastIntentInPackage(String packageName, int uid,
14870            Intent intent, String resolvedType, IIntentReceiver resultTo,
14871            int resultCode, String resultData, Bundle map,
14872            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14873        synchronized(this) {
14874            intent = verifyBroadcastLocked(intent);
14875
14876            final long origId = Binder.clearCallingIdentity();
14877            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14878                    resultTo, resultCode, resultData, map, requiredPermission,
14879                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14880            Binder.restoreCallingIdentity(origId);
14881            return res;
14882        }
14883    }
14884
14885    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14886        // Refuse possible leaked file descriptors
14887        if (intent != null && intent.hasFileDescriptors() == true) {
14888            throw new IllegalArgumentException("File descriptors passed in Intent");
14889        }
14890
14891        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14892                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14893
14894        synchronized(this) {
14895            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14896                    != PackageManager.PERMISSION_GRANTED) {
14897                String msg = "Permission Denial: unbroadcastIntent() from pid="
14898                        + Binder.getCallingPid()
14899                        + ", uid=" + Binder.getCallingUid()
14900                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14901                Slog.w(TAG, msg);
14902                throw new SecurityException(msg);
14903            }
14904            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14905            if (stickies != null) {
14906                ArrayList<Intent> list = stickies.get(intent.getAction());
14907                if (list != null) {
14908                    int N = list.size();
14909                    int i;
14910                    for (i=0; i<N; i++) {
14911                        if (intent.filterEquals(list.get(i))) {
14912                            list.remove(i);
14913                            break;
14914                        }
14915                    }
14916                    if (list.size() <= 0) {
14917                        stickies.remove(intent.getAction());
14918                    }
14919                }
14920                if (stickies.size() <= 0) {
14921                    mStickyBroadcasts.remove(userId);
14922                }
14923            }
14924        }
14925    }
14926
14927    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14928            String resultData, Bundle resultExtras, boolean resultAbort) {
14929        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14930        if (r == null) {
14931            Slog.w(TAG, "finishReceiver called but not found on queue");
14932            return false;
14933        }
14934
14935        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14936    }
14937
14938    void backgroundServicesFinishedLocked(int userId) {
14939        for (BroadcastQueue queue : mBroadcastQueues) {
14940            queue.backgroundServicesFinishedLocked(userId);
14941        }
14942    }
14943
14944    public void finishReceiver(IBinder who, int resultCode, String resultData,
14945            Bundle resultExtras, boolean resultAbort) {
14946        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14947
14948        // Refuse possible leaked file descriptors
14949        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14950            throw new IllegalArgumentException("File descriptors passed in Bundle");
14951        }
14952
14953        final long origId = Binder.clearCallingIdentity();
14954        try {
14955            boolean doNext = false;
14956            BroadcastRecord r;
14957
14958            synchronized(this) {
14959                r = broadcastRecordForReceiverLocked(who);
14960                if (r != null) {
14961                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14962                        resultData, resultExtras, resultAbort, true);
14963                }
14964            }
14965
14966            if (doNext) {
14967                r.queue.processNextBroadcast(false);
14968            }
14969            trimApplications();
14970        } finally {
14971            Binder.restoreCallingIdentity(origId);
14972        }
14973    }
14974
14975    // =========================================================
14976    // INSTRUMENTATION
14977    // =========================================================
14978
14979    public boolean startInstrumentation(ComponentName className,
14980            String profileFile, int flags, Bundle arguments,
14981            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14982            int userId, String abiOverride) {
14983        enforceNotIsolatedCaller("startInstrumentation");
14984        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14985                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14986        // Refuse possible leaked file descriptors
14987        if (arguments != null && arguments.hasFileDescriptors()) {
14988            throw new IllegalArgumentException("File descriptors passed in Bundle");
14989        }
14990
14991        synchronized(this) {
14992            InstrumentationInfo ii = null;
14993            ApplicationInfo ai = null;
14994            try {
14995                ii = mContext.getPackageManager().getInstrumentationInfo(
14996                    className, STOCK_PM_FLAGS);
14997                ai = AppGlobals.getPackageManager().getApplicationInfo(
14998                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14999            } catch (PackageManager.NameNotFoundException e) {
15000            } catch (RemoteException e) {
15001            }
15002            if (ii == null) {
15003                reportStartInstrumentationFailure(watcher, className,
15004                        "Unable to find instrumentation info for: " + className);
15005                return false;
15006            }
15007            if (ai == null) {
15008                reportStartInstrumentationFailure(watcher, className,
15009                        "Unable to find instrumentation target package: " + ii.targetPackage);
15010                return false;
15011            }
15012
15013            int match = mContext.getPackageManager().checkSignatures(
15014                    ii.targetPackage, ii.packageName);
15015            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15016                String msg = "Permission Denial: starting instrumentation "
15017                        + className + " from pid="
15018                        + Binder.getCallingPid()
15019                        + ", uid=" + Binder.getCallingPid()
15020                        + " not allowed because package " + ii.packageName
15021                        + " does not have a signature matching the target "
15022                        + ii.targetPackage;
15023                reportStartInstrumentationFailure(watcher, className, msg);
15024                throw new SecurityException(msg);
15025            }
15026
15027            final long origId = Binder.clearCallingIdentity();
15028            // Instrumentation can kill and relaunch even persistent processes
15029            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15030                    "start instr");
15031            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15032            app.instrumentationClass = className;
15033            app.instrumentationInfo = ai;
15034            app.instrumentationProfileFile = profileFile;
15035            app.instrumentationArguments = arguments;
15036            app.instrumentationWatcher = watcher;
15037            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15038            app.instrumentationResultClass = className;
15039            Binder.restoreCallingIdentity(origId);
15040        }
15041
15042        return true;
15043    }
15044
15045    /**
15046     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15047     * error to the logs, but if somebody is watching, send the report there too.  This enables
15048     * the "am" command to report errors with more information.
15049     *
15050     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15051     * @param cn The component name of the instrumentation.
15052     * @param report The error report.
15053     */
15054    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15055            ComponentName cn, String report) {
15056        Slog.w(TAG, report);
15057        try {
15058            if (watcher != null) {
15059                Bundle results = new Bundle();
15060                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15061                results.putString("Error", report);
15062                watcher.instrumentationStatus(cn, -1, results);
15063            }
15064        } catch (RemoteException e) {
15065            Slog.w(TAG, e);
15066        }
15067    }
15068
15069    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15070        if (app.instrumentationWatcher != null) {
15071            try {
15072                // NOTE:  IInstrumentationWatcher *must* be oneway here
15073                app.instrumentationWatcher.instrumentationFinished(
15074                    app.instrumentationClass,
15075                    resultCode,
15076                    results);
15077            } catch (RemoteException e) {
15078            }
15079        }
15080        if (app.instrumentationUiAutomationConnection != null) {
15081            try {
15082                app.instrumentationUiAutomationConnection.shutdown();
15083            } catch (RemoteException re) {
15084                /* ignore */
15085            }
15086            // Only a UiAutomation can set this flag and now that
15087            // it is finished we make sure it is reset to its default.
15088            mUserIsMonkey = false;
15089        }
15090        app.instrumentationWatcher = null;
15091        app.instrumentationUiAutomationConnection = null;
15092        app.instrumentationClass = null;
15093        app.instrumentationInfo = null;
15094        app.instrumentationProfileFile = null;
15095        app.instrumentationArguments = null;
15096
15097        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15098                "finished inst");
15099    }
15100
15101    public void finishInstrumentation(IApplicationThread target,
15102            int resultCode, Bundle results) {
15103        int userId = UserHandle.getCallingUserId();
15104        // Refuse possible leaked file descriptors
15105        if (results != null && results.hasFileDescriptors()) {
15106            throw new IllegalArgumentException("File descriptors passed in Intent");
15107        }
15108
15109        synchronized(this) {
15110            ProcessRecord app = getRecordForAppLocked(target);
15111            if (app == null) {
15112                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15113                return;
15114            }
15115            final long origId = Binder.clearCallingIdentity();
15116            finishInstrumentationLocked(app, resultCode, results);
15117            Binder.restoreCallingIdentity(origId);
15118        }
15119    }
15120
15121    // =========================================================
15122    // CONFIGURATION
15123    // =========================================================
15124
15125    public ConfigurationInfo getDeviceConfigurationInfo() {
15126        ConfigurationInfo config = new ConfigurationInfo();
15127        synchronized (this) {
15128            config.reqTouchScreen = mConfiguration.touchscreen;
15129            config.reqKeyboardType = mConfiguration.keyboard;
15130            config.reqNavigation = mConfiguration.navigation;
15131            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15132                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15133                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15134            }
15135            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15136                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15137                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15138            }
15139            config.reqGlEsVersion = GL_ES_VERSION;
15140        }
15141        return config;
15142    }
15143
15144    ActivityStack getFocusedStack() {
15145        return mStackSupervisor.getFocusedStack();
15146    }
15147
15148    public Configuration getConfiguration() {
15149        Configuration ci;
15150        synchronized(this) {
15151            ci = new Configuration(mConfiguration);
15152        }
15153        return ci;
15154    }
15155
15156    public void updatePersistentConfiguration(Configuration values) {
15157        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15158                "updateConfiguration()");
15159        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15160                "updateConfiguration()");
15161        if (values == null) {
15162            throw new NullPointerException("Configuration must not be null");
15163        }
15164
15165        synchronized(this) {
15166            final long origId = Binder.clearCallingIdentity();
15167            updateConfigurationLocked(values, null, true, false);
15168            Binder.restoreCallingIdentity(origId);
15169        }
15170    }
15171
15172    public void updateConfiguration(Configuration values) {
15173        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15174                "updateConfiguration()");
15175
15176        synchronized(this) {
15177            if (values == null && mWindowManager != null) {
15178                // sentinel: fetch the current configuration from the window manager
15179                values = mWindowManager.computeNewConfiguration();
15180            }
15181
15182            if (mWindowManager != null) {
15183                mProcessList.applyDisplaySize(mWindowManager);
15184            }
15185
15186            final long origId = Binder.clearCallingIdentity();
15187            if (values != null) {
15188                Settings.System.clearConfiguration(values);
15189            }
15190            updateConfigurationLocked(values, null, false, false);
15191            Binder.restoreCallingIdentity(origId);
15192        }
15193    }
15194
15195    /**
15196     * Do either or both things: (1) change the current configuration, and (2)
15197     * make sure the given activity is running with the (now) current
15198     * configuration.  Returns true if the activity has been left running, or
15199     * false if <var>starting</var> is being destroyed to match the new
15200     * configuration.
15201     * @param persistent TODO
15202     */
15203    boolean updateConfigurationLocked(Configuration values,
15204            ActivityRecord starting, boolean persistent, boolean initLocale) {
15205        int changes = 0;
15206
15207        if (values != null) {
15208            Configuration newConfig = new Configuration(mConfiguration);
15209            changes = newConfig.updateFrom(values);
15210            if (changes != 0) {
15211                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15212                    Slog.i(TAG, "Updating configuration to: " + values);
15213                }
15214
15215                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15216
15217                if (values.locale != null && !initLocale) {
15218                    saveLocaleLocked(values.locale,
15219                                     !values.locale.equals(mConfiguration.locale),
15220                                     values.userSetLocale);
15221                }
15222
15223                mConfigurationSeq++;
15224                if (mConfigurationSeq <= 0) {
15225                    mConfigurationSeq = 1;
15226                }
15227                newConfig.seq = mConfigurationSeq;
15228                mConfiguration = newConfig;
15229                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15230                //mUsageStatsService.noteStartConfig(newConfig);
15231
15232                final Configuration configCopy = new Configuration(mConfiguration);
15233
15234                // TODO: If our config changes, should we auto dismiss any currently
15235                // showing dialogs?
15236                mShowDialogs = shouldShowDialogs(newConfig);
15237
15238                AttributeCache ac = AttributeCache.instance();
15239                if (ac != null) {
15240                    ac.updateConfiguration(configCopy);
15241                }
15242
15243                // Make sure all resources in our process are updated
15244                // right now, so that anyone who is going to retrieve
15245                // resource values after we return will be sure to get
15246                // the new ones.  This is especially important during
15247                // boot, where the first config change needs to guarantee
15248                // all resources have that config before following boot
15249                // code is executed.
15250                mSystemThread.applyConfigurationToResources(configCopy);
15251
15252                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15253                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15254                    msg.obj = new Configuration(configCopy);
15255                    mHandler.sendMessage(msg);
15256                }
15257
15258                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15259                    ProcessRecord app = mLruProcesses.get(i);
15260                    try {
15261                        if (app.thread != null) {
15262                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15263                                    + app.processName + " new config " + mConfiguration);
15264                            app.thread.scheduleConfigurationChanged(configCopy);
15265                        }
15266                    } catch (Exception e) {
15267                    }
15268                }
15269                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15270                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15271                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15272                        | Intent.FLAG_RECEIVER_FOREGROUND);
15273                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15274                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15275                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15276                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15277                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15278                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15279                    broadcastIntentLocked(null, null, intent,
15280                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15281                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15282                }
15283            }
15284        }
15285
15286        boolean kept = true;
15287        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15288        // mainStack is null during startup.
15289        if (mainStack != null) {
15290            if (changes != 0 && starting == null) {
15291                // If the configuration changed, and the caller is not already
15292                // in the process of starting an activity, then find the top
15293                // activity to check if its configuration needs to change.
15294                starting = mainStack.topRunningActivityLocked(null);
15295            }
15296
15297            if (starting != null) {
15298                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15299                // And we need to make sure at this point that all other activities
15300                // are made visible with the correct configuration.
15301                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15302            }
15303        }
15304
15305        if (values != null && mWindowManager != null) {
15306            mWindowManager.setNewConfiguration(mConfiguration);
15307        }
15308
15309        return kept;
15310    }
15311
15312    /**
15313     * Decide based on the configuration whether we should shouw the ANR,
15314     * crash, etc dialogs.  The idea is that if there is no affordnace to
15315     * press the on-screen buttons, we shouldn't show the dialog.
15316     *
15317     * A thought: SystemUI might also want to get told about this, the Power
15318     * dialog / global actions also might want different behaviors.
15319     */
15320    private static final boolean shouldShowDialogs(Configuration config) {
15321        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15322                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15323    }
15324
15325    /**
15326     * Save the locale.  You must be inside a synchronized (this) block.
15327     */
15328    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15329        if(isDiff) {
15330            SystemProperties.set("user.language", l.getLanguage());
15331            SystemProperties.set("user.region", l.getCountry());
15332        }
15333
15334        if(isPersist) {
15335            SystemProperties.set("persist.sys.language", l.getLanguage());
15336            SystemProperties.set("persist.sys.country", l.getCountry());
15337            SystemProperties.set("persist.sys.localevar", l.getVariant());
15338        }
15339    }
15340
15341    @Override
15342    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15343        ActivityRecord srec = ActivityRecord.forToken(token);
15344        return srec != null && srec.task.affinity != null &&
15345                srec.task.affinity.equals(destAffinity);
15346    }
15347
15348    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15349            Intent resultData) {
15350
15351        synchronized (this) {
15352            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15353            if (stack != null) {
15354                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15355            }
15356            return false;
15357        }
15358    }
15359
15360    public int getLaunchedFromUid(IBinder activityToken) {
15361        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15362        if (srec == null) {
15363            return -1;
15364        }
15365        return srec.launchedFromUid;
15366    }
15367
15368    public String getLaunchedFromPackage(IBinder activityToken) {
15369        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15370        if (srec == null) {
15371            return null;
15372        }
15373        return srec.launchedFromPackage;
15374    }
15375
15376    // =========================================================
15377    // LIFETIME MANAGEMENT
15378    // =========================================================
15379
15380    // Returns which broadcast queue the app is the current [or imminent] receiver
15381    // on, or 'null' if the app is not an active broadcast recipient.
15382    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15383        BroadcastRecord r = app.curReceiver;
15384        if (r != null) {
15385            return r.queue;
15386        }
15387
15388        // It's not the current receiver, but it might be starting up to become one
15389        synchronized (this) {
15390            for (BroadcastQueue queue : mBroadcastQueues) {
15391                r = queue.mPendingBroadcast;
15392                if (r != null && r.curApp == app) {
15393                    // found it; report which queue it's in
15394                    return queue;
15395                }
15396            }
15397        }
15398
15399        return null;
15400    }
15401
15402    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15403            boolean doingAll, long now) {
15404        if (mAdjSeq == app.adjSeq) {
15405            // This adjustment has already been computed.
15406            return app.curRawAdj;
15407        }
15408
15409        if (app.thread == null) {
15410            app.adjSeq = mAdjSeq;
15411            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15412            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15413            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15414        }
15415
15416        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15417        app.adjSource = null;
15418        app.adjTarget = null;
15419        app.empty = false;
15420        app.cached = false;
15421
15422        final int activitiesSize = app.activities.size();
15423
15424        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15425            // The max adjustment doesn't allow this app to be anything
15426            // below foreground, so it is not worth doing work for it.
15427            app.adjType = "fixed";
15428            app.adjSeq = mAdjSeq;
15429            app.curRawAdj = app.maxAdj;
15430            app.foregroundActivities = false;
15431            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15432            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15433            // System processes can do UI, and when they do we want to have
15434            // them trim their memory after the user leaves the UI.  To
15435            // facilitate this, here we need to determine whether or not it
15436            // is currently showing UI.
15437            app.systemNoUi = true;
15438            if (app == TOP_APP) {
15439                app.systemNoUi = false;
15440            } else if (activitiesSize > 0) {
15441                for (int j = 0; j < activitiesSize; j++) {
15442                    final ActivityRecord r = app.activities.get(j);
15443                    if (r.visible) {
15444                        app.systemNoUi = false;
15445                    }
15446                }
15447            }
15448            if (!app.systemNoUi) {
15449                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15450            }
15451            return (app.curAdj=app.maxAdj);
15452        }
15453
15454        app.systemNoUi = false;
15455
15456        // Determine the importance of the process, starting with most
15457        // important to least, and assign an appropriate OOM adjustment.
15458        int adj;
15459        int schedGroup;
15460        int procState;
15461        boolean foregroundActivities = false;
15462        BroadcastQueue queue;
15463        if (app == TOP_APP) {
15464            // The last app on the list is the foreground app.
15465            adj = ProcessList.FOREGROUND_APP_ADJ;
15466            schedGroup = Process.THREAD_GROUP_DEFAULT;
15467            app.adjType = "top-activity";
15468            foregroundActivities = true;
15469            procState = ActivityManager.PROCESS_STATE_TOP;
15470        } else if (app.instrumentationClass != null) {
15471            // Don't want to kill running instrumentation.
15472            adj = ProcessList.FOREGROUND_APP_ADJ;
15473            schedGroup = Process.THREAD_GROUP_DEFAULT;
15474            app.adjType = "instrumentation";
15475            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15476        } else if ((queue = isReceivingBroadcast(app)) != null) {
15477            // An app that is currently receiving a broadcast also
15478            // counts as being in the foreground for OOM killer purposes.
15479            // It's placed in a sched group based on the nature of the
15480            // broadcast as reflected by which queue it's active in.
15481            adj = ProcessList.FOREGROUND_APP_ADJ;
15482            schedGroup = (queue == mFgBroadcastQueue)
15483                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15484            app.adjType = "broadcast";
15485            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15486        } else if (app.executingServices.size() > 0) {
15487            // An app that is currently executing a service callback also
15488            // counts as being in the foreground.
15489            adj = ProcessList.FOREGROUND_APP_ADJ;
15490            schedGroup = app.execServicesFg ?
15491                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15492            app.adjType = "exec-service";
15493            procState = ActivityManager.PROCESS_STATE_SERVICE;
15494            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15495        } else {
15496            // As far as we know the process is empty.  We may change our mind later.
15497            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15498            // At this point we don't actually know the adjustment.  Use the cached adj
15499            // value that the caller wants us to.
15500            adj = cachedAdj;
15501            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15502            app.cached = true;
15503            app.empty = true;
15504            app.adjType = "cch-empty";
15505        }
15506
15507        // Examine all activities if not already foreground.
15508        if (!foregroundActivities && activitiesSize > 0) {
15509            for (int j = 0; j < activitiesSize; j++) {
15510                final ActivityRecord r = app.activities.get(j);
15511                if (r.app != app) {
15512                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15513                            + app + "?!?");
15514                    continue;
15515                }
15516                if (r.visible) {
15517                    // App has a visible activity; only upgrade adjustment.
15518                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15519                        adj = ProcessList.VISIBLE_APP_ADJ;
15520                        app.adjType = "visible";
15521                    }
15522                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15523                        procState = ActivityManager.PROCESS_STATE_TOP;
15524                    }
15525                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15526                    app.cached = false;
15527                    app.empty = false;
15528                    foregroundActivities = true;
15529                    break;
15530                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15531                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15532                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15533                        app.adjType = "pausing";
15534                    }
15535                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15536                        procState = ActivityManager.PROCESS_STATE_TOP;
15537                    }
15538                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15539                    app.cached = false;
15540                    app.empty = false;
15541                    foregroundActivities = true;
15542                } else if (r.state == ActivityState.STOPPING) {
15543                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15544                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15545                        app.adjType = "stopping";
15546                    }
15547                    // For the process state, we will at this point consider the
15548                    // process to be cached.  It will be cached either as an activity
15549                    // or empty depending on whether the activity is finishing.  We do
15550                    // this so that we can treat the process as cached for purposes of
15551                    // memory trimming (determing current memory level, trim command to
15552                    // send to process) since there can be an arbitrary number of stopping
15553                    // processes and they should soon all go into the cached state.
15554                    if (!r.finishing) {
15555                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15556                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15557                        }
15558                    }
15559                    app.cached = false;
15560                    app.empty = false;
15561                    foregroundActivities = true;
15562                } else {
15563                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15564                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15565                        app.adjType = "cch-act";
15566                    }
15567                }
15568            }
15569        }
15570
15571        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15572            if (app.foregroundServices) {
15573                // The user is aware of this app, so make it visible.
15574                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15575                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15576                app.cached = false;
15577                app.adjType = "fg-service";
15578                schedGroup = Process.THREAD_GROUP_DEFAULT;
15579            } else if (app.forcingToForeground != null) {
15580                // The user is aware of this app, so make it visible.
15581                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15582                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15583                app.cached = false;
15584                app.adjType = "force-fg";
15585                app.adjSource = app.forcingToForeground;
15586                schedGroup = Process.THREAD_GROUP_DEFAULT;
15587            }
15588        }
15589
15590        if (app == mHeavyWeightProcess) {
15591            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15592                // We don't want to kill the current heavy-weight process.
15593                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15594                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15595                app.cached = false;
15596                app.adjType = "heavy";
15597            }
15598            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15599                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15600            }
15601        }
15602
15603        if (app == mHomeProcess) {
15604            if (adj > ProcessList.HOME_APP_ADJ) {
15605                // This process is hosting what we currently consider to be the
15606                // home app, so we don't want to let it go into the background.
15607                adj = ProcessList.HOME_APP_ADJ;
15608                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15609                app.cached = false;
15610                app.adjType = "home";
15611            }
15612            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15613                procState = ActivityManager.PROCESS_STATE_HOME;
15614            }
15615        }
15616
15617        if (app == mPreviousProcess && app.activities.size() > 0) {
15618            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15619                // This was the previous process that showed UI to the user.
15620                // We want to try to keep it around more aggressively, to give
15621                // a good experience around switching between two apps.
15622                adj = ProcessList.PREVIOUS_APP_ADJ;
15623                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15624                app.cached = false;
15625                app.adjType = "previous";
15626            }
15627            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15628                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15629            }
15630        }
15631
15632        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15633                + " reason=" + app.adjType);
15634
15635        // By default, we use the computed adjustment.  It may be changed if
15636        // there are applications dependent on our services or providers, but
15637        // this gives us a baseline and makes sure we don't get into an
15638        // infinite recursion.
15639        app.adjSeq = mAdjSeq;
15640        app.curRawAdj = adj;
15641        app.hasStartedServices = false;
15642
15643        if (mBackupTarget != null && app == mBackupTarget.app) {
15644            // If possible we want to avoid killing apps while they're being backed up
15645            if (adj > ProcessList.BACKUP_APP_ADJ) {
15646                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15647                adj = ProcessList.BACKUP_APP_ADJ;
15648                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15649                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15650                }
15651                app.adjType = "backup";
15652                app.cached = false;
15653            }
15654            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15655                procState = ActivityManager.PROCESS_STATE_BACKUP;
15656            }
15657        }
15658
15659        boolean mayBeTop = false;
15660
15661        for (int is = app.services.size()-1;
15662                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15663                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15664                        || procState > ActivityManager.PROCESS_STATE_TOP);
15665                is--) {
15666            ServiceRecord s = app.services.valueAt(is);
15667            if (s.startRequested) {
15668                app.hasStartedServices = true;
15669                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15670                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15671                }
15672                if (app.hasShownUi && app != mHomeProcess) {
15673                    // If this process has shown some UI, let it immediately
15674                    // go to the LRU list because it may be pretty heavy with
15675                    // UI stuff.  We'll tag it with a label just to help
15676                    // debug and understand what is going on.
15677                    if (adj > ProcessList.SERVICE_ADJ) {
15678                        app.adjType = "cch-started-ui-services";
15679                    }
15680                } else {
15681                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15682                        // This service has seen some activity within
15683                        // recent memory, so we will keep its process ahead
15684                        // of the background processes.
15685                        if (adj > ProcessList.SERVICE_ADJ) {
15686                            adj = ProcessList.SERVICE_ADJ;
15687                            app.adjType = "started-services";
15688                            app.cached = false;
15689                        }
15690                    }
15691                    // If we have let the service slide into the background
15692                    // state, still have some text describing what it is doing
15693                    // even though the service no longer has an impact.
15694                    if (adj > ProcessList.SERVICE_ADJ) {
15695                        app.adjType = "cch-started-services";
15696                    }
15697                }
15698            }
15699            for (int conni = s.connections.size()-1;
15700                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15701                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15702                            || procState > ActivityManager.PROCESS_STATE_TOP);
15703                    conni--) {
15704                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15705                for (int i = 0;
15706                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15707                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15708                                || procState > ActivityManager.PROCESS_STATE_TOP);
15709                        i++) {
15710                    // XXX should compute this based on the max of
15711                    // all connected clients.
15712                    ConnectionRecord cr = clist.get(i);
15713                    if (cr.binding.client == app) {
15714                        // Binding to ourself is not interesting.
15715                        continue;
15716                    }
15717                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15718                        ProcessRecord client = cr.binding.client;
15719                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15720                                TOP_APP, doingAll, now);
15721                        int clientProcState = client.curProcState;
15722                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15723                            // If the other app is cached for any reason, for purposes here
15724                            // we are going to consider it empty.  The specific cached state
15725                            // doesn't propagate except under certain conditions.
15726                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15727                        }
15728                        String adjType = null;
15729                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15730                            // Not doing bind OOM management, so treat
15731                            // this guy more like a started service.
15732                            if (app.hasShownUi && app != mHomeProcess) {
15733                                // If this process has shown some UI, let it immediately
15734                                // go to the LRU list because it may be pretty heavy with
15735                                // UI stuff.  We'll tag it with a label just to help
15736                                // debug and understand what is going on.
15737                                if (adj > clientAdj) {
15738                                    adjType = "cch-bound-ui-services";
15739                                }
15740                                app.cached = false;
15741                                clientAdj = adj;
15742                                clientProcState = procState;
15743                            } else {
15744                                if (now >= (s.lastActivity
15745                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15746                                    // This service has not seen activity within
15747                                    // recent memory, so allow it to drop to the
15748                                    // LRU list if there is no other reason to keep
15749                                    // it around.  We'll also tag it with a label just
15750                                    // to help debug and undertand what is going on.
15751                                    if (adj > clientAdj) {
15752                                        adjType = "cch-bound-services";
15753                                    }
15754                                    clientAdj = adj;
15755                                }
15756                            }
15757                        }
15758                        if (adj > clientAdj) {
15759                            // If this process has recently shown UI, and
15760                            // the process that is binding to it is less
15761                            // important than being visible, then we don't
15762                            // care about the binding as much as we care
15763                            // about letting this process get into the LRU
15764                            // list to be killed and restarted if needed for
15765                            // memory.
15766                            if (app.hasShownUi && app != mHomeProcess
15767                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15768                                adjType = "cch-bound-ui-services";
15769                            } else {
15770                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15771                                        |Context.BIND_IMPORTANT)) != 0) {
15772                                    adj = clientAdj;
15773                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15774                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15775                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15776                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15777                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15778                                    adj = clientAdj;
15779                                } else {
15780                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15781                                        adj = ProcessList.VISIBLE_APP_ADJ;
15782                                    }
15783                                }
15784                                if (!client.cached) {
15785                                    app.cached = false;
15786                                }
15787                                adjType = "service";
15788                            }
15789                        }
15790                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15791                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15792                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15793                            }
15794                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15795                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15796                                    // Special handling of clients who are in the top state.
15797                                    // We *may* want to consider this process to be in the
15798                                    // top state as well, but only if there is not another
15799                                    // reason for it to be running.  Being on the top is a
15800                                    // special state, meaning you are specifically running
15801                                    // for the current top app.  If the process is already
15802                                    // running in the background for some other reason, it
15803                                    // is more important to continue considering it to be
15804                                    // in the background state.
15805                                    mayBeTop = true;
15806                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15807                                } else {
15808                                    // Special handling for above-top states (persistent
15809                                    // processes).  These should not bring the current process
15810                                    // into the top state, since they are not on top.  Instead
15811                                    // give them the best state after that.
15812                                    clientProcState =
15813                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15814                                }
15815                            }
15816                        } else {
15817                            if (clientProcState <
15818                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15819                                clientProcState =
15820                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15821                            }
15822                        }
15823                        if (procState > clientProcState) {
15824                            procState = clientProcState;
15825                        }
15826                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15827                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15828                            app.pendingUiClean = true;
15829                        }
15830                        if (adjType != null) {
15831                            app.adjType = adjType;
15832                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15833                                    .REASON_SERVICE_IN_USE;
15834                            app.adjSource = cr.binding.client;
15835                            app.adjSourceProcState = clientProcState;
15836                            app.adjTarget = s.name;
15837                        }
15838                    }
15839                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15840                        app.treatLikeActivity = true;
15841                    }
15842                    final ActivityRecord a = cr.activity;
15843                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15844                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15845                                (a.visible || a.state == ActivityState.RESUMED
15846                                 || a.state == ActivityState.PAUSING)) {
15847                            adj = ProcessList.FOREGROUND_APP_ADJ;
15848                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15849                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15850                            }
15851                            app.cached = false;
15852                            app.adjType = "service";
15853                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15854                                    .REASON_SERVICE_IN_USE;
15855                            app.adjSource = a;
15856                            app.adjSourceProcState = procState;
15857                            app.adjTarget = s.name;
15858                        }
15859                    }
15860                }
15861            }
15862        }
15863
15864        for (int provi = app.pubProviders.size()-1;
15865                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15866                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15867                        || procState > ActivityManager.PROCESS_STATE_TOP);
15868                provi--) {
15869            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15870            for (int i = cpr.connections.size()-1;
15871                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15872                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15873                            || procState > ActivityManager.PROCESS_STATE_TOP);
15874                    i--) {
15875                ContentProviderConnection conn = cpr.connections.get(i);
15876                ProcessRecord client = conn.client;
15877                if (client == app) {
15878                    // Being our own client is not interesting.
15879                    continue;
15880                }
15881                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15882                int clientProcState = client.curProcState;
15883                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15884                    // If the other app is cached for any reason, for purposes here
15885                    // we are going to consider it empty.
15886                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15887                }
15888                if (adj > clientAdj) {
15889                    if (app.hasShownUi && app != mHomeProcess
15890                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15891                        app.adjType = "cch-ui-provider";
15892                    } else {
15893                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15894                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15895                        app.adjType = "provider";
15896                    }
15897                    app.cached &= client.cached;
15898                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15899                            .REASON_PROVIDER_IN_USE;
15900                    app.adjSource = client;
15901                    app.adjSourceProcState = clientProcState;
15902                    app.adjTarget = cpr.name;
15903                }
15904                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15905                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15906                        // Special handling of clients who are in the top state.
15907                        // We *may* want to consider this process to be in the
15908                        // top state as well, but only if there is not another
15909                        // reason for it to be running.  Being on the top is a
15910                        // special state, meaning you are specifically running
15911                        // for the current top app.  If the process is already
15912                        // running in the background for some other reason, it
15913                        // is more important to continue considering it to be
15914                        // in the background state.
15915                        mayBeTop = true;
15916                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15917                    } else {
15918                        // Special handling for above-top states (persistent
15919                        // processes).  These should not bring the current process
15920                        // into the top state, since they are not on top.  Instead
15921                        // give them the best state after that.
15922                        clientProcState =
15923                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15924                    }
15925                }
15926                if (procState > clientProcState) {
15927                    procState = clientProcState;
15928                }
15929                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15930                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15931                }
15932            }
15933            // If the provider has external (non-framework) process
15934            // dependencies, ensure that its adjustment is at least
15935            // FOREGROUND_APP_ADJ.
15936            if (cpr.hasExternalProcessHandles()) {
15937                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15938                    adj = ProcessList.FOREGROUND_APP_ADJ;
15939                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15940                    app.cached = false;
15941                    app.adjType = "provider";
15942                    app.adjTarget = cpr.name;
15943                }
15944                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15945                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15946                }
15947            }
15948        }
15949
15950        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15951            // A client of one of our services or providers is in the top state.  We
15952            // *may* want to be in the top state, but not if we are already running in
15953            // the background for some other reason.  For the decision here, we are going
15954            // to pick out a few specific states that we want to remain in when a client
15955            // is top (states that tend to be longer-term) and otherwise allow it to go
15956            // to the top state.
15957            switch (procState) {
15958                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15959                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15960                case ActivityManager.PROCESS_STATE_SERVICE:
15961                    // These all are longer-term states, so pull them up to the top
15962                    // of the background states, but not all the way to the top state.
15963                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15964                    break;
15965                default:
15966                    // Otherwise, top is a better choice, so take it.
15967                    procState = ActivityManager.PROCESS_STATE_TOP;
15968                    break;
15969            }
15970        }
15971
15972        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15973            if (app.hasClientActivities) {
15974                // This is a cached process, but with client activities.  Mark it so.
15975                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15976                app.adjType = "cch-client-act";
15977            } else if (app.treatLikeActivity) {
15978                // This is a cached process, but somebody wants us to treat it like it has
15979                // an activity, okay!
15980                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15981                app.adjType = "cch-as-act";
15982            }
15983        }
15984
15985        if (adj == ProcessList.SERVICE_ADJ) {
15986            if (doingAll) {
15987                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15988                mNewNumServiceProcs++;
15989                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15990                if (!app.serviceb) {
15991                    // This service isn't far enough down on the LRU list to
15992                    // normally be a B service, but if we are low on RAM and it
15993                    // is large we want to force it down since we would prefer to
15994                    // keep launcher over it.
15995                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15996                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15997                        app.serviceHighRam = true;
15998                        app.serviceb = true;
15999                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16000                    } else {
16001                        mNewNumAServiceProcs++;
16002                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16003                    }
16004                } else {
16005                    app.serviceHighRam = false;
16006                }
16007            }
16008            if (app.serviceb) {
16009                adj = ProcessList.SERVICE_B_ADJ;
16010            }
16011        }
16012
16013        app.curRawAdj = adj;
16014
16015        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16016        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16017        if (adj > app.maxAdj) {
16018            adj = app.maxAdj;
16019            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16020                schedGroup = Process.THREAD_GROUP_DEFAULT;
16021            }
16022        }
16023
16024        // Do final modification to adj.  Everything we do between here and applying
16025        // the final setAdj must be done in this function, because we will also use
16026        // it when computing the final cached adj later.  Note that we don't need to
16027        // worry about this for max adj above, since max adj will always be used to
16028        // keep it out of the cached vaues.
16029        app.curAdj = app.modifyRawOomAdj(adj);
16030        app.curSchedGroup = schedGroup;
16031        app.curProcState = procState;
16032        app.foregroundActivities = foregroundActivities;
16033
16034        return app.curRawAdj;
16035    }
16036
16037    /**
16038     * Schedule PSS collection of a process.
16039     */
16040    void requestPssLocked(ProcessRecord proc, int procState) {
16041        if (mPendingPssProcesses.contains(proc)) {
16042            return;
16043        }
16044        if (mPendingPssProcesses.size() == 0) {
16045            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16046        }
16047        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16048        proc.pssProcState = procState;
16049        mPendingPssProcesses.add(proc);
16050    }
16051
16052    /**
16053     * Schedule PSS collection of all processes.
16054     */
16055    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16056        if (!always) {
16057            if (now < (mLastFullPssTime +
16058                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16059                return;
16060            }
16061        }
16062        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16063        mLastFullPssTime = now;
16064        mFullPssPending = true;
16065        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16066        mPendingPssProcesses.clear();
16067        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16068            ProcessRecord app = mLruProcesses.get(i);
16069            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16070                app.pssProcState = app.setProcState;
16071                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16072                        isSleeping(), now);
16073                mPendingPssProcesses.add(app);
16074            }
16075        }
16076        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16077    }
16078
16079    /**
16080     * Ask a given process to GC right now.
16081     */
16082    final void performAppGcLocked(ProcessRecord app) {
16083        try {
16084            app.lastRequestedGc = SystemClock.uptimeMillis();
16085            if (app.thread != null) {
16086                if (app.reportLowMemory) {
16087                    app.reportLowMemory = false;
16088                    app.thread.scheduleLowMemory();
16089                } else {
16090                    app.thread.processInBackground();
16091                }
16092            }
16093        } catch (Exception e) {
16094            // whatever.
16095        }
16096    }
16097
16098    /**
16099     * Returns true if things are idle enough to perform GCs.
16100     */
16101    private final boolean canGcNowLocked() {
16102        boolean processingBroadcasts = false;
16103        for (BroadcastQueue q : mBroadcastQueues) {
16104            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16105                processingBroadcasts = true;
16106            }
16107        }
16108        return !processingBroadcasts
16109                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16110    }
16111
16112    /**
16113     * Perform GCs on all processes that are waiting for it, but only
16114     * if things are idle.
16115     */
16116    final void performAppGcsLocked() {
16117        final int N = mProcessesToGc.size();
16118        if (N <= 0) {
16119            return;
16120        }
16121        if (canGcNowLocked()) {
16122            while (mProcessesToGc.size() > 0) {
16123                ProcessRecord proc = mProcessesToGc.remove(0);
16124                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16125                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16126                            <= SystemClock.uptimeMillis()) {
16127                        // To avoid spamming the system, we will GC processes one
16128                        // at a time, waiting a few seconds between each.
16129                        performAppGcLocked(proc);
16130                        scheduleAppGcsLocked();
16131                        return;
16132                    } else {
16133                        // It hasn't been long enough since we last GCed this
16134                        // process...  put it in the list to wait for its time.
16135                        addProcessToGcListLocked(proc);
16136                        break;
16137                    }
16138                }
16139            }
16140
16141            scheduleAppGcsLocked();
16142        }
16143    }
16144
16145    /**
16146     * If all looks good, perform GCs on all processes waiting for them.
16147     */
16148    final void performAppGcsIfAppropriateLocked() {
16149        if (canGcNowLocked()) {
16150            performAppGcsLocked();
16151            return;
16152        }
16153        // Still not idle, wait some more.
16154        scheduleAppGcsLocked();
16155    }
16156
16157    /**
16158     * Schedule the execution of all pending app GCs.
16159     */
16160    final void scheduleAppGcsLocked() {
16161        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16162
16163        if (mProcessesToGc.size() > 0) {
16164            // Schedule a GC for the time to the next process.
16165            ProcessRecord proc = mProcessesToGc.get(0);
16166            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16167
16168            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16169            long now = SystemClock.uptimeMillis();
16170            if (when < (now+GC_TIMEOUT)) {
16171                when = now + GC_TIMEOUT;
16172            }
16173            mHandler.sendMessageAtTime(msg, when);
16174        }
16175    }
16176
16177    /**
16178     * Add a process to the array of processes waiting to be GCed.  Keeps the
16179     * list in sorted order by the last GC time.  The process can't already be
16180     * on the list.
16181     */
16182    final void addProcessToGcListLocked(ProcessRecord proc) {
16183        boolean added = false;
16184        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16185            if (mProcessesToGc.get(i).lastRequestedGc <
16186                    proc.lastRequestedGc) {
16187                added = true;
16188                mProcessesToGc.add(i+1, proc);
16189                break;
16190            }
16191        }
16192        if (!added) {
16193            mProcessesToGc.add(0, proc);
16194        }
16195    }
16196
16197    /**
16198     * Set up to ask a process to GC itself.  This will either do it
16199     * immediately, or put it on the list of processes to gc the next
16200     * time things are idle.
16201     */
16202    final void scheduleAppGcLocked(ProcessRecord app) {
16203        long now = SystemClock.uptimeMillis();
16204        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16205            return;
16206        }
16207        if (!mProcessesToGc.contains(app)) {
16208            addProcessToGcListLocked(app);
16209            scheduleAppGcsLocked();
16210        }
16211    }
16212
16213    final void checkExcessivePowerUsageLocked(boolean doKills) {
16214        updateCpuStatsNow();
16215
16216        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16217        boolean doWakeKills = doKills;
16218        boolean doCpuKills = doKills;
16219        if (mLastPowerCheckRealtime == 0) {
16220            doWakeKills = false;
16221        }
16222        if (mLastPowerCheckUptime == 0) {
16223            doCpuKills = false;
16224        }
16225        if (stats.isScreenOn()) {
16226            doWakeKills = false;
16227        }
16228        final long curRealtime = SystemClock.elapsedRealtime();
16229        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16230        final long curUptime = SystemClock.uptimeMillis();
16231        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16232        mLastPowerCheckRealtime = curRealtime;
16233        mLastPowerCheckUptime = curUptime;
16234        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16235            doWakeKills = false;
16236        }
16237        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16238            doCpuKills = false;
16239        }
16240        int i = mLruProcesses.size();
16241        while (i > 0) {
16242            i--;
16243            ProcessRecord app = mLruProcesses.get(i);
16244            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16245                long wtime;
16246                synchronized (stats) {
16247                    wtime = stats.getProcessWakeTime(app.info.uid,
16248                            app.pid, curRealtime);
16249                }
16250                long wtimeUsed = wtime - app.lastWakeTime;
16251                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16252                if (DEBUG_POWER) {
16253                    StringBuilder sb = new StringBuilder(128);
16254                    sb.append("Wake for ");
16255                    app.toShortString(sb);
16256                    sb.append(": over ");
16257                    TimeUtils.formatDuration(realtimeSince, sb);
16258                    sb.append(" used ");
16259                    TimeUtils.formatDuration(wtimeUsed, sb);
16260                    sb.append(" (");
16261                    sb.append((wtimeUsed*100)/realtimeSince);
16262                    sb.append("%)");
16263                    Slog.i(TAG, sb.toString());
16264                    sb.setLength(0);
16265                    sb.append("CPU for ");
16266                    app.toShortString(sb);
16267                    sb.append(": over ");
16268                    TimeUtils.formatDuration(uptimeSince, sb);
16269                    sb.append(" used ");
16270                    TimeUtils.formatDuration(cputimeUsed, sb);
16271                    sb.append(" (");
16272                    sb.append((cputimeUsed*100)/uptimeSince);
16273                    sb.append("%)");
16274                    Slog.i(TAG, sb.toString());
16275                }
16276                // If a process has held a wake lock for more
16277                // than 50% of the time during this period,
16278                // that sounds bad.  Kill!
16279                if (doWakeKills && realtimeSince > 0
16280                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16281                    synchronized (stats) {
16282                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16283                                realtimeSince, wtimeUsed);
16284                    }
16285                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16286                            + " during " + realtimeSince);
16287                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16288                } else if (doCpuKills && uptimeSince > 0
16289                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16290                    synchronized (stats) {
16291                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16292                                uptimeSince, cputimeUsed);
16293                    }
16294                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16295                            + " during " + uptimeSince);
16296                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16297                } else {
16298                    app.lastWakeTime = wtime;
16299                    app.lastCpuTime = app.curCpuTime;
16300                }
16301            }
16302        }
16303    }
16304
16305    private final boolean applyOomAdjLocked(ProcessRecord app,
16306            ProcessRecord TOP_APP, boolean doingAll, long now) {
16307        boolean success = true;
16308
16309        if (app.curRawAdj != app.setRawAdj) {
16310            app.setRawAdj = app.curRawAdj;
16311        }
16312
16313        int changes = 0;
16314
16315        if (app.curAdj != app.setAdj) {
16316            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16317            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16318                TAG, "Set " + app.pid + " " + app.processName +
16319                " adj " + app.curAdj + ": " + app.adjType);
16320            app.setAdj = app.curAdj;
16321        }
16322
16323        if (app.setSchedGroup != app.curSchedGroup) {
16324            app.setSchedGroup = app.curSchedGroup;
16325            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16326                    "Setting process group of " + app.processName
16327                    + " to " + app.curSchedGroup);
16328            if (app.waitingToKill != null &&
16329                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16330                killUnneededProcessLocked(app, app.waitingToKill);
16331                success = false;
16332            } else {
16333                if (true) {
16334                    long oldId = Binder.clearCallingIdentity();
16335                    try {
16336                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16337                    } catch (Exception e) {
16338                        Slog.w(TAG, "Failed setting process group of " + app.pid
16339                                + " to " + app.curSchedGroup);
16340                        e.printStackTrace();
16341                    } finally {
16342                        Binder.restoreCallingIdentity(oldId);
16343                    }
16344                } else {
16345                    if (app.thread != null) {
16346                        try {
16347                            app.thread.setSchedulingGroup(app.curSchedGroup);
16348                        } catch (RemoteException e) {
16349                        }
16350                    }
16351                }
16352                Process.setSwappiness(app.pid,
16353                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16354            }
16355        }
16356        if (app.repForegroundActivities != app.foregroundActivities) {
16357            app.repForegroundActivities = app.foregroundActivities;
16358            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16359        }
16360        if (app.repProcState != app.curProcState) {
16361            app.repProcState = app.curProcState;
16362            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16363            if (app.thread != null) {
16364                try {
16365                    if (false) {
16366                        //RuntimeException h = new RuntimeException("here");
16367                        Slog.i(TAG, "Sending new process state " + app.repProcState
16368                                + " to " + app /*, h*/);
16369                    }
16370                    app.thread.setProcessState(app.repProcState);
16371                } catch (RemoteException e) {
16372                }
16373            }
16374        }
16375        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16376                app.setProcState)) {
16377            app.lastStateTime = now;
16378            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16379                    isSleeping(), now);
16380            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16381                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16382                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16383                    + (app.nextPssTime-now) + ": " + app);
16384        } else {
16385            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16386                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16387                requestPssLocked(app, app.setProcState);
16388                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16389                        isSleeping(), now);
16390            } else if (false && DEBUG_PSS) {
16391                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16392            }
16393        }
16394        if (app.setProcState != app.curProcState) {
16395            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16396                    "Proc state change of " + app.processName
16397                    + " to " + app.curProcState);
16398            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16399            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16400            if (setImportant && !curImportant) {
16401                // This app is no longer something we consider important enough to allow to
16402                // use arbitrary amounts of battery power.  Note
16403                // its current wake lock time to later know to kill it if
16404                // it is not behaving well.
16405                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16406                synchronized (stats) {
16407                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16408                            app.pid, SystemClock.elapsedRealtime());
16409                }
16410                app.lastCpuTime = app.curCpuTime;
16411
16412            }
16413            app.setProcState = app.curProcState;
16414            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16415                app.notCachedSinceIdle = false;
16416            }
16417            if (!doingAll) {
16418                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16419            } else {
16420                app.procStateChanged = true;
16421            }
16422        }
16423
16424        if (changes != 0) {
16425            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16426            int i = mPendingProcessChanges.size()-1;
16427            ProcessChangeItem item = null;
16428            while (i >= 0) {
16429                item = mPendingProcessChanges.get(i);
16430                if (item.pid == app.pid) {
16431                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16432                    break;
16433                }
16434                i--;
16435            }
16436            if (i < 0) {
16437                // No existing item in pending changes; need a new one.
16438                final int NA = mAvailProcessChanges.size();
16439                if (NA > 0) {
16440                    item = mAvailProcessChanges.remove(NA-1);
16441                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16442                } else {
16443                    item = new ProcessChangeItem();
16444                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16445                }
16446                item.changes = 0;
16447                item.pid = app.pid;
16448                item.uid = app.info.uid;
16449                if (mPendingProcessChanges.size() == 0) {
16450                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16451                            "*** Enqueueing dispatch processes changed!");
16452                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16453                }
16454                mPendingProcessChanges.add(item);
16455            }
16456            item.changes |= changes;
16457            item.processState = app.repProcState;
16458            item.foregroundActivities = app.repForegroundActivities;
16459            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16460                    + Integer.toHexString(System.identityHashCode(item))
16461                    + " " + app.toShortString() + ": changes=" + item.changes
16462                    + " procState=" + item.processState
16463                    + " foreground=" + item.foregroundActivities
16464                    + " type=" + app.adjType + " source=" + app.adjSource
16465                    + " target=" + app.adjTarget);
16466        }
16467
16468        return success;
16469    }
16470
16471    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16472        if (proc.thread != null) {
16473            if (proc.baseProcessTracker != null) {
16474                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16475            }
16476            if (proc.repProcState >= 0) {
16477                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16478                        proc.repProcState);
16479            }
16480        }
16481    }
16482
16483    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16484            ProcessRecord TOP_APP, boolean doingAll, long now) {
16485        if (app.thread == null) {
16486            return false;
16487        }
16488
16489        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16490
16491        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16492    }
16493
16494    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16495            boolean oomAdj) {
16496        if (isForeground != proc.foregroundServices) {
16497            proc.foregroundServices = isForeground;
16498            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16499                    proc.info.uid);
16500            if (isForeground) {
16501                if (curProcs == null) {
16502                    curProcs = new ArrayList<ProcessRecord>();
16503                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16504                }
16505                if (!curProcs.contains(proc)) {
16506                    curProcs.add(proc);
16507                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16508                            proc.info.packageName, proc.info.uid);
16509                }
16510            } else {
16511                if (curProcs != null) {
16512                    if (curProcs.remove(proc)) {
16513                        mBatteryStatsService.noteEvent(
16514                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16515                                proc.info.packageName, proc.info.uid);
16516                        if (curProcs.size() <= 0) {
16517                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16518                        }
16519                    }
16520                }
16521            }
16522            if (oomAdj) {
16523                updateOomAdjLocked();
16524            }
16525        }
16526    }
16527
16528    private final ActivityRecord resumedAppLocked() {
16529        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16530        String pkg;
16531        int uid;
16532        if (act != null) {
16533            pkg = act.packageName;
16534            uid = act.info.applicationInfo.uid;
16535        } else {
16536            pkg = null;
16537            uid = -1;
16538        }
16539        // Has the UID or resumed package name changed?
16540        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16541                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16542            if (mCurResumedPackage != null) {
16543                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16544                        mCurResumedPackage, mCurResumedUid);
16545            }
16546            mCurResumedPackage = pkg;
16547            mCurResumedUid = uid;
16548            if (mCurResumedPackage != null) {
16549                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16550                        mCurResumedPackage, mCurResumedUid);
16551            }
16552        }
16553        return act;
16554    }
16555
16556    final boolean updateOomAdjLocked(ProcessRecord app) {
16557        final ActivityRecord TOP_ACT = resumedAppLocked();
16558        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16559        final boolean wasCached = app.cached;
16560
16561        mAdjSeq++;
16562
16563        // This is the desired cached adjusment we want to tell it to use.
16564        // If our app is currently cached, we know it, and that is it.  Otherwise,
16565        // we don't know it yet, and it needs to now be cached we will then
16566        // need to do a complete oom adj.
16567        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16568                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16569        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16570                SystemClock.uptimeMillis());
16571        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16572            // Changed to/from cached state, so apps after it in the LRU
16573            // list may also be changed.
16574            updateOomAdjLocked();
16575        }
16576        return success;
16577    }
16578
16579    final void updateOomAdjLocked() {
16580        final ActivityRecord TOP_ACT = resumedAppLocked();
16581        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16582        final long now = SystemClock.uptimeMillis();
16583        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16584        final int N = mLruProcesses.size();
16585
16586        if (false) {
16587            RuntimeException e = new RuntimeException();
16588            e.fillInStackTrace();
16589            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16590        }
16591
16592        mAdjSeq++;
16593        mNewNumServiceProcs = 0;
16594        mNewNumAServiceProcs = 0;
16595
16596        final int emptyProcessLimit;
16597        final int cachedProcessLimit;
16598        if (mProcessLimit <= 0) {
16599            emptyProcessLimit = cachedProcessLimit = 0;
16600        } else if (mProcessLimit == 1) {
16601            emptyProcessLimit = 1;
16602            cachedProcessLimit = 0;
16603        } else {
16604            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16605            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16606        }
16607
16608        // Let's determine how many processes we have running vs.
16609        // how many slots we have for background processes; we may want
16610        // to put multiple processes in a slot of there are enough of
16611        // them.
16612        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16613                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16614        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16615        if (numEmptyProcs > cachedProcessLimit) {
16616            // If there are more empty processes than our limit on cached
16617            // processes, then use the cached process limit for the factor.
16618            // This ensures that the really old empty processes get pushed
16619            // down to the bottom, so if we are running low on memory we will
16620            // have a better chance at keeping around more cached processes
16621            // instead of a gazillion empty processes.
16622            numEmptyProcs = cachedProcessLimit;
16623        }
16624        int emptyFactor = numEmptyProcs/numSlots;
16625        if (emptyFactor < 1) emptyFactor = 1;
16626        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16627        if (cachedFactor < 1) cachedFactor = 1;
16628        int stepCached = 0;
16629        int stepEmpty = 0;
16630        int numCached = 0;
16631        int numEmpty = 0;
16632        int numTrimming = 0;
16633
16634        mNumNonCachedProcs = 0;
16635        mNumCachedHiddenProcs = 0;
16636
16637        // First update the OOM adjustment for each of the
16638        // application processes based on their current state.
16639        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16640        int nextCachedAdj = curCachedAdj+1;
16641        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16642        int nextEmptyAdj = curEmptyAdj+2;
16643        for (int i=N-1; i>=0; i--) {
16644            ProcessRecord app = mLruProcesses.get(i);
16645            if (!app.killedByAm && app.thread != null) {
16646                app.procStateChanged = false;
16647                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16648
16649                // If we haven't yet assigned the final cached adj
16650                // to the process, do that now.
16651                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16652                    switch (app.curProcState) {
16653                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16654                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16655                            // This process is a cached process holding activities...
16656                            // assign it the next cached value for that type, and then
16657                            // step that cached level.
16658                            app.curRawAdj = curCachedAdj;
16659                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16660                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16661                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16662                                    + ")");
16663                            if (curCachedAdj != nextCachedAdj) {
16664                                stepCached++;
16665                                if (stepCached >= cachedFactor) {
16666                                    stepCached = 0;
16667                                    curCachedAdj = nextCachedAdj;
16668                                    nextCachedAdj += 2;
16669                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16670                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16671                                    }
16672                                }
16673                            }
16674                            break;
16675                        default:
16676                            // For everything else, assign next empty cached process
16677                            // level and bump that up.  Note that this means that
16678                            // long-running services that have dropped down to the
16679                            // cached level will be treated as empty (since their process
16680                            // state is still as a service), which is what we want.
16681                            app.curRawAdj = curEmptyAdj;
16682                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16683                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16684                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16685                                    + ")");
16686                            if (curEmptyAdj != nextEmptyAdj) {
16687                                stepEmpty++;
16688                                if (stepEmpty >= emptyFactor) {
16689                                    stepEmpty = 0;
16690                                    curEmptyAdj = nextEmptyAdj;
16691                                    nextEmptyAdj += 2;
16692                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16693                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16694                                    }
16695                                }
16696                            }
16697                            break;
16698                    }
16699                }
16700
16701                applyOomAdjLocked(app, TOP_APP, true, now);
16702
16703                // Count the number of process types.
16704                switch (app.curProcState) {
16705                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16706                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16707                        mNumCachedHiddenProcs++;
16708                        numCached++;
16709                        if (numCached > cachedProcessLimit) {
16710                            killUnneededProcessLocked(app, "cached #" + numCached);
16711                        }
16712                        break;
16713                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16714                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16715                                && app.lastActivityTime < oldTime) {
16716                            killUnneededProcessLocked(app, "empty for "
16717                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16718                                    / 1000) + "s");
16719                        } else {
16720                            numEmpty++;
16721                            if (numEmpty > emptyProcessLimit) {
16722                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16723                            }
16724                        }
16725                        break;
16726                    default:
16727                        mNumNonCachedProcs++;
16728                        break;
16729                }
16730
16731                if (app.isolated && app.services.size() <= 0) {
16732                    // If this is an isolated process, and there are no
16733                    // services running in it, then the process is no longer
16734                    // needed.  We agressively kill these because we can by
16735                    // definition not re-use the same process again, and it is
16736                    // good to avoid having whatever code was running in them
16737                    // left sitting around after no longer needed.
16738                    killUnneededProcessLocked(app, "isolated not needed");
16739                }
16740
16741                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16742                        && !app.killedByAm) {
16743                    numTrimming++;
16744                }
16745            }
16746        }
16747
16748        mNumServiceProcs = mNewNumServiceProcs;
16749
16750        // Now determine the memory trimming level of background processes.
16751        // Unfortunately we need to start at the back of the list to do this
16752        // properly.  We only do this if the number of background apps we
16753        // are managing to keep around is less than half the maximum we desire;
16754        // if we are keeping a good number around, we'll let them use whatever
16755        // memory they want.
16756        final int numCachedAndEmpty = numCached + numEmpty;
16757        int memFactor;
16758        if (numCached <= ProcessList.TRIM_CACHED_APPS
16759                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16760            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16761                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16762            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16763                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16764            } else {
16765                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16766            }
16767        } else {
16768            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16769        }
16770        // We always allow the memory level to go up (better).  We only allow it to go
16771        // down if we are in a state where that is allowed, *and* the total number of processes
16772        // has gone down since last time.
16773        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16774                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16775                + " last=" + mLastNumProcesses);
16776        if (memFactor > mLastMemoryLevel) {
16777            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16778                memFactor = mLastMemoryLevel;
16779                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16780            }
16781        }
16782        mLastMemoryLevel = memFactor;
16783        mLastNumProcesses = mLruProcesses.size();
16784        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16785        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16786        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16787            if (mLowRamStartTime == 0) {
16788                mLowRamStartTime = now;
16789            }
16790            int step = 0;
16791            int fgTrimLevel;
16792            switch (memFactor) {
16793                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16794                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16795                    break;
16796                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16797                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16798                    break;
16799                default:
16800                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16801                    break;
16802            }
16803            int factor = numTrimming/3;
16804            int minFactor = 2;
16805            if (mHomeProcess != null) minFactor++;
16806            if (mPreviousProcess != null) minFactor++;
16807            if (factor < minFactor) factor = minFactor;
16808            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16809            for (int i=N-1; i>=0; i--) {
16810                ProcessRecord app = mLruProcesses.get(i);
16811                if (allChanged || app.procStateChanged) {
16812                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16813                    app.procStateChanged = false;
16814                }
16815                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16816                        && !app.killedByAm) {
16817                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16818                        try {
16819                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16820                                    "Trimming memory of " + app.processName
16821                                    + " to " + curLevel);
16822                            app.thread.scheduleTrimMemory(curLevel);
16823                        } catch (RemoteException e) {
16824                        }
16825                        if (false) {
16826                            // For now we won't do this; our memory trimming seems
16827                            // to be good enough at this point that destroying
16828                            // activities causes more harm than good.
16829                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16830                                    && app != mHomeProcess && app != mPreviousProcess) {
16831                                // Need to do this on its own message because the stack may not
16832                                // be in a consistent state at this point.
16833                                // For these apps we will also finish their activities
16834                                // to help them free memory.
16835                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16836                            }
16837                        }
16838                    }
16839                    app.trimMemoryLevel = curLevel;
16840                    step++;
16841                    if (step >= factor) {
16842                        step = 0;
16843                        switch (curLevel) {
16844                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16845                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16846                                break;
16847                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16848                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16849                                break;
16850                        }
16851                    }
16852                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16853                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16854                            && app.thread != null) {
16855                        try {
16856                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16857                                    "Trimming memory of heavy-weight " + app.processName
16858                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16859                            app.thread.scheduleTrimMemory(
16860                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16861                        } catch (RemoteException e) {
16862                        }
16863                    }
16864                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16865                } else {
16866                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16867                            || app.systemNoUi) && app.pendingUiClean) {
16868                        // If this application is now in the background and it
16869                        // had done UI, then give it the special trim level to
16870                        // have it free UI resources.
16871                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16872                        if (app.trimMemoryLevel < level && app.thread != null) {
16873                            try {
16874                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16875                                        "Trimming memory of bg-ui " + app.processName
16876                                        + " to " + level);
16877                                app.thread.scheduleTrimMemory(level);
16878                            } catch (RemoteException e) {
16879                            }
16880                        }
16881                        app.pendingUiClean = false;
16882                    }
16883                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16884                        try {
16885                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16886                                    "Trimming memory of fg " + app.processName
16887                                    + " to " + fgTrimLevel);
16888                            app.thread.scheduleTrimMemory(fgTrimLevel);
16889                        } catch (RemoteException e) {
16890                        }
16891                    }
16892                    app.trimMemoryLevel = fgTrimLevel;
16893                }
16894            }
16895        } else {
16896            if (mLowRamStartTime != 0) {
16897                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16898                mLowRamStartTime = 0;
16899            }
16900            for (int i=N-1; i>=0; i--) {
16901                ProcessRecord app = mLruProcesses.get(i);
16902                if (allChanged || app.procStateChanged) {
16903                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16904                    app.procStateChanged = false;
16905                }
16906                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16907                        || app.systemNoUi) && app.pendingUiClean) {
16908                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16909                            && app.thread != null) {
16910                        try {
16911                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16912                                    "Trimming memory of ui hidden " + app.processName
16913                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16914                            app.thread.scheduleTrimMemory(
16915                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16916                        } catch (RemoteException e) {
16917                        }
16918                    }
16919                    app.pendingUiClean = false;
16920                }
16921                app.trimMemoryLevel = 0;
16922            }
16923        }
16924
16925        if (mAlwaysFinishActivities) {
16926            // Need to do this on its own message because the stack may not
16927            // be in a consistent state at this point.
16928            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16929        }
16930
16931        if (allChanged) {
16932            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16933        }
16934
16935        if (mProcessStats.shouldWriteNowLocked(now)) {
16936            mHandler.post(new Runnable() {
16937                @Override public void run() {
16938                    synchronized (ActivityManagerService.this) {
16939                        mProcessStats.writeStateAsyncLocked();
16940                    }
16941                }
16942            });
16943        }
16944
16945        if (DEBUG_OOM_ADJ) {
16946            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16947        }
16948    }
16949
16950    final void trimApplications() {
16951        synchronized (this) {
16952            int i;
16953
16954            // First remove any unused application processes whose package
16955            // has been removed.
16956            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16957                final ProcessRecord app = mRemovedProcesses.get(i);
16958                if (app.activities.size() == 0
16959                        && app.curReceiver == null && app.services.size() == 0) {
16960                    Slog.i(
16961                        TAG, "Exiting empty application process "
16962                        + app.processName + " ("
16963                        + (app.thread != null ? app.thread.asBinder() : null)
16964                        + ")\n");
16965                    if (app.pid > 0 && app.pid != MY_PID) {
16966                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16967                                app.processName, app.setAdj, "empty");
16968                        app.killedByAm = true;
16969                        Process.killProcessQuiet(app.pid);
16970                        Process.killProcessGroup(app.info.uid, app.pid);
16971                    } else {
16972                        try {
16973                            app.thread.scheduleExit();
16974                        } catch (Exception e) {
16975                            // Ignore exceptions.
16976                        }
16977                    }
16978                    cleanUpApplicationRecordLocked(app, false, true, -1);
16979                    mRemovedProcesses.remove(i);
16980
16981                    if (app.persistent) {
16982                        addAppLocked(app.info, false, null /* ABI override */);
16983                    }
16984                }
16985            }
16986
16987            // Now update the oom adj for all processes.
16988            updateOomAdjLocked();
16989        }
16990    }
16991
16992    /** This method sends the specified signal to each of the persistent apps */
16993    public void signalPersistentProcesses(int sig) throws RemoteException {
16994        if (sig != Process.SIGNAL_USR1) {
16995            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16996        }
16997
16998        synchronized (this) {
16999            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17000                    != PackageManager.PERMISSION_GRANTED) {
17001                throw new SecurityException("Requires permission "
17002                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17003            }
17004
17005            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17006                ProcessRecord r = mLruProcesses.get(i);
17007                if (r.thread != null && r.persistent) {
17008                    Process.sendSignal(r.pid, sig);
17009                }
17010            }
17011        }
17012    }
17013
17014    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
17015        if (proc == null || proc == mProfileProc) {
17016            proc = mProfileProc;
17017            path = mProfileFile;
17018            profileType = mProfileType;
17019            clearProfilerLocked();
17020        }
17021        if (proc == null) {
17022            return;
17023        }
17024        try {
17025            proc.thread.profilerControl(false, path, null, profileType);
17026        } catch (RemoteException e) {
17027            throw new IllegalStateException("Process disappeared");
17028        }
17029    }
17030
17031    private void clearProfilerLocked() {
17032        if (mProfileFd != null) {
17033            try {
17034                mProfileFd.close();
17035            } catch (IOException e) {
17036            }
17037        }
17038        mProfileApp = null;
17039        mProfileProc = null;
17040        mProfileFile = null;
17041        mProfileType = 0;
17042        mAutoStopProfiler = false;
17043    }
17044
17045    public boolean profileControl(String process, int userId, boolean start,
17046            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
17047
17048        try {
17049            synchronized (this) {
17050                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17051                // its own permission.
17052                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17053                        != PackageManager.PERMISSION_GRANTED) {
17054                    throw new SecurityException("Requires permission "
17055                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17056                }
17057
17058                if (start && fd == null) {
17059                    throw new IllegalArgumentException("null fd");
17060                }
17061
17062                ProcessRecord proc = null;
17063                if (process != null) {
17064                    proc = findProcessLocked(process, userId, "profileControl");
17065                }
17066
17067                if (start && (proc == null || proc.thread == null)) {
17068                    throw new IllegalArgumentException("Unknown process: " + process);
17069                }
17070
17071                if (start) {
17072                    stopProfilerLocked(null, null, 0);
17073                    setProfileApp(proc.info, proc.processName, path, fd, false);
17074                    mProfileProc = proc;
17075                    mProfileType = profileType;
17076                    try {
17077                        fd = fd.dup();
17078                    } catch (IOException e) {
17079                        fd = null;
17080                    }
17081                    proc.thread.profilerControl(start, path, fd, profileType);
17082                    fd = null;
17083                    mProfileFd = null;
17084                } else {
17085                    stopProfilerLocked(proc, path, profileType);
17086                    if (fd != null) {
17087                        try {
17088                            fd.close();
17089                        } catch (IOException e) {
17090                        }
17091                    }
17092                }
17093
17094                return true;
17095            }
17096        } catch (RemoteException e) {
17097            throw new IllegalStateException("Process disappeared");
17098        } finally {
17099            if (fd != null) {
17100                try {
17101                    fd.close();
17102                } catch (IOException e) {
17103                }
17104            }
17105        }
17106    }
17107
17108    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17109        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17110                userId, true, ALLOW_FULL_ONLY, callName, null);
17111        ProcessRecord proc = null;
17112        try {
17113            int pid = Integer.parseInt(process);
17114            synchronized (mPidsSelfLocked) {
17115                proc = mPidsSelfLocked.get(pid);
17116            }
17117        } catch (NumberFormatException e) {
17118        }
17119
17120        if (proc == null) {
17121            ArrayMap<String, SparseArray<ProcessRecord>> all
17122                    = mProcessNames.getMap();
17123            SparseArray<ProcessRecord> procs = all.get(process);
17124            if (procs != null && procs.size() > 0) {
17125                proc = procs.valueAt(0);
17126                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17127                    for (int i=1; i<procs.size(); i++) {
17128                        ProcessRecord thisProc = procs.valueAt(i);
17129                        if (thisProc.userId == userId) {
17130                            proc = thisProc;
17131                            break;
17132                        }
17133                    }
17134                }
17135            }
17136        }
17137
17138        return proc;
17139    }
17140
17141    public boolean dumpHeap(String process, int userId, boolean managed,
17142            String path, ParcelFileDescriptor fd) throws RemoteException {
17143
17144        try {
17145            synchronized (this) {
17146                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17147                // its own permission (same as profileControl).
17148                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17149                        != PackageManager.PERMISSION_GRANTED) {
17150                    throw new SecurityException("Requires permission "
17151                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17152                }
17153
17154                if (fd == null) {
17155                    throw new IllegalArgumentException("null fd");
17156                }
17157
17158                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17159                if (proc == null || proc.thread == null) {
17160                    throw new IllegalArgumentException("Unknown process: " + process);
17161                }
17162
17163                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17164                if (!isDebuggable) {
17165                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17166                        throw new SecurityException("Process not debuggable: " + proc);
17167                    }
17168                }
17169
17170                proc.thread.dumpHeap(managed, path, fd);
17171                fd = null;
17172                return true;
17173            }
17174        } catch (RemoteException e) {
17175            throw new IllegalStateException("Process disappeared");
17176        } finally {
17177            if (fd != null) {
17178                try {
17179                    fd.close();
17180                } catch (IOException e) {
17181                }
17182            }
17183        }
17184    }
17185
17186    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17187    public void monitor() {
17188        synchronized (this) { }
17189    }
17190
17191    void onCoreSettingsChange(Bundle settings) {
17192        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17193            ProcessRecord processRecord = mLruProcesses.get(i);
17194            try {
17195                if (processRecord.thread != null) {
17196                    processRecord.thread.setCoreSettings(settings);
17197                }
17198            } catch (RemoteException re) {
17199                /* ignore */
17200            }
17201        }
17202    }
17203
17204    // Multi-user methods
17205
17206    /**
17207     * Start user, if its not already running, but don't bring it to foreground.
17208     */
17209    @Override
17210    public boolean startUserInBackground(final int userId) {
17211        return startUser(userId, /* foreground */ false);
17212    }
17213
17214    /**
17215     * Refreshes the list of users related to the current user when either a
17216     * user switch happens or when a new related user is started in the
17217     * background.
17218     */
17219    private void updateCurrentProfileIdsLocked() {
17220        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17221                mCurrentUserId, false /* enabledOnly */);
17222        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17223        for (int i = 0; i < currentProfileIds.length; i++) {
17224            currentProfileIds[i] = profiles.get(i).id;
17225        }
17226        mCurrentProfileIds = currentProfileIds;
17227
17228        synchronized (mUserProfileGroupIdsSelfLocked) {
17229            mUserProfileGroupIdsSelfLocked.clear();
17230            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17231            for (int i = 0; i < users.size(); i++) {
17232                UserInfo user = users.get(i);
17233                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17234                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17235                }
17236            }
17237        }
17238    }
17239
17240    private Set getProfileIdsLocked(int userId) {
17241        Set userIds = new HashSet<Integer>();
17242        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17243                userId, false /* enabledOnly */);
17244        for (UserInfo user : profiles) {
17245            userIds.add(Integer.valueOf(user.id));
17246        }
17247        return userIds;
17248    }
17249
17250    @Override
17251    public boolean switchUser(final int userId) {
17252        return startUser(userId, /* foregound */ true);
17253    }
17254
17255    private boolean startUser(final int userId, boolean foreground) {
17256        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17257                != PackageManager.PERMISSION_GRANTED) {
17258            String msg = "Permission Denial: switchUser() from pid="
17259                    + Binder.getCallingPid()
17260                    + ", uid=" + Binder.getCallingUid()
17261                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17262            Slog.w(TAG, msg);
17263            throw new SecurityException(msg);
17264        }
17265
17266        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17267
17268        final long ident = Binder.clearCallingIdentity();
17269        try {
17270            synchronized (this) {
17271                final int oldUserId = mCurrentUserId;
17272                if (oldUserId == userId) {
17273                    return true;
17274                }
17275
17276                mStackSupervisor.setLockTaskModeLocked(null, false);
17277
17278                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17279                if (userInfo == null) {
17280                    Slog.w(TAG, "No user info for user #" + userId);
17281                    return false;
17282                }
17283                if (foreground && userInfo.isManagedProfile()) {
17284                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17285                    return false;
17286                }
17287
17288                if (foreground) {
17289                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17290                            R.anim.screen_user_enter);
17291                }
17292
17293                boolean needStart = false;
17294
17295                // If the user we are switching to is not currently started, then
17296                // we need to start it now.
17297                if (mStartedUsers.get(userId) == null) {
17298                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17299                    updateStartedUserArrayLocked();
17300                    needStart = true;
17301                }
17302
17303                final Integer userIdInt = Integer.valueOf(userId);
17304                mUserLru.remove(userIdInt);
17305                mUserLru.add(userIdInt);
17306
17307                if (foreground) {
17308                    mCurrentUserId = userId;
17309                    updateCurrentProfileIdsLocked();
17310                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17311                    // Once the internal notion of the active user has switched, we lock the device
17312                    // with the option to show the user switcher on the keyguard.
17313                    mWindowManager.lockNow(null);
17314                } else {
17315                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17316                    updateCurrentProfileIdsLocked();
17317                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17318                    mUserLru.remove(currentUserIdInt);
17319                    mUserLru.add(currentUserIdInt);
17320                }
17321
17322                final UserStartedState uss = mStartedUsers.get(userId);
17323
17324                // Make sure user is in the started state.  If it is currently
17325                // stopping, we need to knock that off.
17326                if (uss.mState == UserStartedState.STATE_STOPPING) {
17327                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17328                    // so we can just fairly silently bring the user back from
17329                    // the almost-dead.
17330                    uss.mState = UserStartedState.STATE_RUNNING;
17331                    updateStartedUserArrayLocked();
17332                    needStart = true;
17333                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17334                    // This means ACTION_SHUTDOWN has been sent, so we will
17335                    // need to treat this as a new boot of the user.
17336                    uss.mState = UserStartedState.STATE_BOOTING;
17337                    updateStartedUserArrayLocked();
17338                    needStart = true;
17339                }
17340
17341                if (uss.mState == UserStartedState.STATE_BOOTING) {
17342                    // Booting up a new user, need to tell system services about it.
17343                    // Note that this is on the same handler as scheduling of broadcasts,
17344                    // which is important because it needs to go first.
17345                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
17346                }
17347
17348                if (foreground) {
17349                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17350                            oldUserId));
17351                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17352                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17353                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17354                            oldUserId, userId, uss));
17355                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17356                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17357                }
17358
17359                if (needStart) {
17360                    // Send USER_STARTED broadcast
17361                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17362                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17363                            | Intent.FLAG_RECEIVER_FOREGROUND);
17364                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17365                    broadcastIntentLocked(null, null, intent,
17366                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17367                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17368                }
17369
17370                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17371                    if (userId != UserHandle.USER_OWNER) {
17372                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17373                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17374                        broadcastIntentLocked(null, null, intent, null,
17375                                new IIntentReceiver.Stub() {
17376                                    public void performReceive(Intent intent, int resultCode,
17377                                            String data, Bundle extras, boolean ordered,
17378                                            boolean sticky, int sendingUser) {
17379                                        userInitialized(uss, userId);
17380                                    }
17381                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17382                                true, false, MY_PID, Process.SYSTEM_UID,
17383                                userId);
17384                        uss.initializing = true;
17385                    } else {
17386                        getUserManagerLocked().makeInitialized(userInfo.id);
17387                    }
17388                }
17389
17390                if (foreground) {
17391                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17392                    if (homeInFront) {
17393                        startHomeActivityLocked(userId);
17394                    } else {
17395                        mStackSupervisor.resumeTopActivitiesLocked();
17396                    }
17397                    EventLogTags.writeAmSwitchUser(userId);
17398                    getUserManagerLocked().userForeground(userId);
17399                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17400                } else {
17401                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17402                }
17403
17404                if (needStart) {
17405                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17406                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17407                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17408                    broadcastIntentLocked(null, null, intent,
17409                            null, new IIntentReceiver.Stub() {
17410                                @Override
17411                                public void performReceive(Intent intent, int resultCode, String data,
17412                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17413                                        throws RemoteException {
17414                                }
17415                            }, 0, null, null,
17416                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17417                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17418                }
17419            }
17420        } finally {
17421            Binder.restoreCallingIdentity(ident);
17422        }
17423
17424        return true;
17425    }
17426
17427    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17428        long ident = Binder.clearCallingIdentity();
17429        try {
17430            Intent intent;
17431            if (oldUserId >= 0) {
17432                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17433                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17434                int count = profiles.size();
17435                for (int i = 0; i < count; i++) {
17436                    int profileUserId = profiles.get(i).id;
17437                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17438                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17439                            | Intent.FLAG_RECEIVER_FOREGROUND);
17440                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17441                    broadcastIntentLocked(null, null, intent,
17442                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17443                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17444                }
17445            }
17446            if (newUserId >= 0) {
17447                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17448                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17449                int count = profiles.size();
17450                for (int i = 0; i < count; i++) {
17451                    int profileUserId = profiles.get(i).id;
17452                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17453                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17454                            | Intent.FLAG_RECEIVER_FOREGROUND);
17455                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17456                    broadcastIntentLocked(null, null, intent,
17457                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17458                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17459                }
17460                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17461                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17462                        | Intent.FLAG_RECEIVER_FOREGROUND);
17463                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17464                broadcastIntentLocked(null, null, intent,
17465                        null, null, 0, null, null,
17466                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17467                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17468            }
17469        } finally {
17470            Binder.restoreCallingIdentity(ident);
17471        }
17472    }
17473
17474    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17475            final int newUserId) {
17476        final int N = mUserSwitchObservers.beginBroadcast();
17477        if (N > 0) {
17478            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17479                int mCount = 0;
17480                @Override
17481                public void sendResult(Bundle data) throws RemoteException {
17482                    synchronized (ActivityManagerService.this) {
17483                        if (mCurUserSwitchCallback == this) {
17484                            mCount++;
17485                            if (mCount == N) {
17486                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17487                            }
17488                        }
17489                    }
17490                }
17491            };
17492            synchronized (this) {
17493                uss.switching = true;
17494                mCurUserSwitchCallback = callback;
17495            }
17496            for (int i=0; i<N; i++) {
17497                try {
17498                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17499                            newUserId, callback);
17500                } catch (RemoteException e) {
17501                }
17502            }
17503        } else {
17504            synchronized (this) {
17505                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17506            }
17507        }
17508        mUserSwitchObservers.finishBroadcast();
17509    }
17510
17511    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17512        synchronized (this) {
17513            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17514            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17515        }
17516    }
17517
17518    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17519        mCurUserSwitchCallback = null;
17520        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17521        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17522                oldUserId, newUserId, uss));
17523    }
17524
17525    void userInitialized(UserStartedState uss, int newUserId) {
17526        completeSwitchAndInitalize(uss, newUserId, true, false);
17527    }
17528
17529    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17530        completeSwitchAndInitalize(uss, newUserId, false, true);
17531    }
17532
17533    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17534            boolean clearInitializing, boolean clearSwitching) {
17535        boolean unfrozen = false;
17536        synchronized (this) {
17537            if (clearInitializing) {
17538                uss.initializing = false;
17539                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17540            }
17541            if (clearSwitching) {
17542                uss.switching = false;
17543            }
17544            if (!uss.switching && !uss.initializing) {
17545                mWindowManager.stopFreezingScreen();
17546                unfrozen = true;
17547            }
17548        }
17549        if (unfrozen) {
17550            final int N = mUserSwitchObservers.beginBroadcast();
17551            for (int i=0; i<N; i++) {
17552                try {
17553                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17554                } catch (RemoteException e) {
17555                }
17556            }
17557            mUserSwitchObservers.finishBroadcast();
17558        }
17559    }
17560
17561    void scheduleStartProfilesLocked() {
17562        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17563            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17564                    DateUtils.SECOND_IN_MILLIS);
17565        }
17566    }
17567
17568    void startProfilesLocked() {
17569        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17570        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17571                mCurrentUserId, false /* enabledOnly */);
17572        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17573        for (UserInfo user : profiles) {
17574            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17575                    && user.id != mCurrentUserId) {
17576                toStart.add(user);
17577            }
17578        }
17579        final int n = toStart.size();
17580        int i = 0;
17581        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17582            startUserInBackground(toStart.get(i).id);
17583        }
17584        if (i < n) {
17585            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17586        }
17587    }
17588
17589    void finishUserBoot(UserStartedState uss) {
17590        synchronized (this) {
17591            if (uss.mState == UserStartedState.STATE_BOOTING
17592                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17593                uss.mState = UserStartedState.STATE_RUNNING;
17594                final int userId = uss.mHandle.getIdentifier();
17595                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17596                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17597                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17598                broadcastIntentLocked(null, null, intent,
17599                        null, null, 0, null, null,
17600                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17601                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17602            }
17603        }
17604    }
17605
17606    void finishUserSwitch(UserStartedState uss) {
17607        synchronized (this) {
17608            finishUserBoot(uss);
17609
17610            startProfilesLocked();
17611
17612            int num = mUserLru.size();
17613            int i = 0;
17614            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17615                Integer oldUserId = mUserLru.get(i);
17616                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17617                if (oldUss == null) {
17618                    // Shouldn't happen, but be sane if it does.
17619                    mUserLru.remove(i);
17620                    num--;
17621                    continue;
17622                }
17623                if (oldUss.mState == UserStartedState.STATE_STOPPING
17624                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17625                    // This user is already stopping, doesn't count.
17626                    num--;
17627                    i++;
17628                    continue;
17629                }
17630                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17631                    // Owner and current can't be stopped, but count as running.
17632                    i++;
17633                    continue;
17634                }
17635                // This is a user to be stopped.
17636                stopUserLocked(oldUserId, null);
17637                num--;
17638                i++;
17639            }
17640        }
17641    }
17642
17643    @Override
17644    public int stopUser(final int userId, final IStopUserCallback callback) {
17645        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17646                != PackageManager.PERMISSION_GRANTED) {
17647            String msg = "Permission Denial: switchUser() from pid="
17648                    + Binder.getCallingPid()
17649                    + ", uid=" + Binder.getCallingUid()
17650                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17651            Slog.w(TAG, msg);
17652            throw new SecurityException(msg);
17653        }
17654        if (userId <= 0) {
17655            throw new IllegalArgumentException("Can't stop primary user " + userId);
17656        }
17657        synchronized (this) {
17658            return stopUserLocked(userId, callback);
17659        }
17660    }
17661
17662    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17663        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17664        if (mCurrentUserId == userId) {
17665            return ActivityManager.USER_OP_IS_CURRENT;
17666        }
17667
17668        final UserStartedState uss = mStartedUsers.get(userId);
17669        if (uss == null) {
17670            // User is not started, nothing to do...  but we do need to
17671            // callback if requested.
17672            if (callback != null) {
17673                mHandler.post(new Runnable() {
17674                    @Override
17675                    public void run() {
17676                        try {
17677                            callback.userStopped(userId);
17678                        } catch (RemoteException e) {
17679                        }
17680                    }
17681                });
17682            }
17683            return ActivityManager.USER_OP_SUCCESS;
17684        }
17685
17686        if (callback != null) {
17687            uss.mStopCallbacks.add(callback);
17688        }
17689
17690        if (uss.mState != UserStartedState.STATE_STOPPING
17691                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17692            uss.mState = UserStartedState.STATE_STOPPING;
17693            updateStartedUserArrayLocked();
17694
17695            long ident = Binder.clearCallingIdentity();
17696            try {
17697                // We are going to broadcast ACTION_USER_STOPPING and then
17698                // once that is done send a final ACTION_SHUTDOWN and then
17699                // stop the user.
17700                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17701                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17702                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17703                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17704                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17705                // This is the result receiver for the final shutdown broadcast.
17706                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17707                    @Override
17708                    public void performReceive(Intent intent, int resultCode, String data,
17709                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17710                        finishUserStop(uss);
17711                    }
17712                };
17713                // This is the result receiver for the initial stopping broadcast.
17714                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17715                    @Override
17716                    public void performReceive(Intent intent, int resultCode, String data,
17717                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17718                        // On to the next.
17719                        synchronized (ActivityManagerService.this) {
17720                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17721                                // Whoops, we are being started back up.  Abort, abort!
17722                                return;
17723                            }
17724                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17725                        }
17726                        mBatteryStatsService.noteEvent(
17727                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17728                                Integer.toString(userId), userId);
17729                        mSystemServiceManager.stopUser(userId);
17730                        broadcastIntentLocked(null, null, shutdownIntent,
17731                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17732                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17733                    }
17734                };
17735                // Kick things off.
17736                broadcastIntentLocked(null, null, stoppingIntent,
17737                        null, stoppingReceiver, 0, null, null,
17738                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17739                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17740            } finally {
17741                Binder.restoreCallingIdentity(ident);
17742            }
17743        }
17744
17745        return ActivityManager.USER_OP_SUCCESS;
17746    }
17747
17748    void finishUserStop(UserStartedState uss) {
17749        final int userId = uss.mHandle.getIdentifier();
17750        boolean stopped;
17751        ArrayList<IStopUserCallback> callbacks;
17752        synchronized (this) {
17753            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17754            if (mStartedUsers.get(userId) != uss) {
17755                stopped = false;
17756            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17757                stopped = false;
17758            } else {
17759                stopped = true;
17760                // User can no longer run.
17761                mStartedUsers.remove(userId);
17762                mUserLru.remove(Integer.valueOf(userId));
17763                updateStartedUserArrayLocked();
17764
17765                // Clean up all state and processes associated with the user.
17766                // Kill all the processes for the user.
17767                forceStopUserLocked(userId, "finish user");
17768            }
17769
17770            // Explicitly remove the old information in mRecentTasks.
17771            removeRecentTasksForUserLocked(userId);
17772        }
17773
17774        for (int i=0; i<callbacks.size(); i++) {
17775            try {
17776                if (stopped) callbacks.get(i).userStopped(userId);
17777                else callbacks.get(i).userStopAborted(userId);
17778            } catch (RemoteException e) {
17779            }
17780        }
17781
17782        if (stopped) {
17783            mSystemServiceManager.cleanupUser(userId);
17784            synchronized (this) {
17785                mStackSupervisor.removeUserLocked(userId);
17786            }
17787        }
17788    }
17789
17790    @Override
17791    public UserInfo getCurrentUser() {
17792        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17793                != PackageManager.PERMISSION_GRANTED) && (
17794                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17795                != PackageManager.PERMISSION_GRANTED)) {
17796            String msg = "Permission Denial: getCurrentUser() from pid="
17797                    + Binder.getCallingPid()
17798                    + ", uid=" + Binder.getCallingUid()
17799                    + " requires " + INTERACT_ACROSS_USERS;
17800            Slog.w(TAG, msg);
17801            throw new SecurityException(msg);
17802        }
17803        synchronized (this) {
17804            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17805        }
17806    }
17807
17808    int getCurrentUserIdLocked() {
17809        return mCurrentUserId;
17810    }
17811
17812    @Override
17813    public boolean isUserRunning(int userId, boolean orStopped) {
17814        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17815                != PackageManager.PERMISSION_GRANTED) {
17816            String msg = "Permission Denial: isUserRunning() from pid="
17817                    + Binder.getCallingPid()
17818                    + ", uid=" + Binder.getCallingUid()
17819                    + " requires " + INTERACT_ACROSS_USERS;
17820            Slog.w(TAG, msg);
17821            throw new SecurityException(msg);
17822        }
17823        synchronized (this) {
17824            return isUserRunningLocked(userId, orStopped);
17825        }
17826    }
17827
17828    boolean isUserRunningLocked(int userId, boolean orStopped) {
17829        UserStartedState state = mStartedUsers.get(userId);
17830        if (state == null) {
17831            return false;
17832        }
17833        if (orStopped) {
17834            return true;
17835        }
17836        return state.mState != UserStartedState.STATE_STOPPING
17837                && state.mState != UserStartedState.STATE_SHUTDOWN;
17838    }
17839
17840    @Override
17841    public int[] getRunningUserIds() {
17842        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17843                != PackageManager.PERMISSION_GRANTED) {
17844            String msg = "Permission Denial: isUserRunning() from pid="
17845                    + Binder.getCallingPid()
17846                    + ", uid=" + Binder.getCallingUid()
17847                    + " requires " + INTERACT_ACROSS_USERS;
17848            Slog.w(TAG, msg);
17849            throw new SecurityException(msg);
17850        }
17851        synchronized (this) {
17852            return mStartedUserArray;
17853        }
17854    }
17855
17856    private void updateStartedUserArrayLocked() {
17857        int num = 0;
17858        for (int i=0; i<mStartedUsers.size();  i++) {
17859            UserStartedState uss = mStartedUsers.valueAt(i);
17860            // This list does not include stopping users.
17861            if (uss.mState != UserStartedState.STATE_STOPPING
17862                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17863                num++;
17864            }
17865        }
17866        mStartedUserArray = new int[num];
17867        num = 0;
17868        for (int i=0; i<mStartedUsers.size();  i++) {
17869            UserStartedState uss = mStartedUsers.valueAt(i);
17870            if (uss.mState != UserStartedState.STATE_STOPPING
17871                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17872                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17873                num++;
17874            }
17875        }
17876    }
17877
17878    @Override
17879    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17880        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17881                != PackageManager.PERMISSION_GRANTED) {
17882            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17883                    + Binder.getCallingPid()
17884                    + ", uid=" + Binder.getCallingUid()
17885                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17886            Slog.w(TAG, msg);
17887            throw new SecurityException(msg);
17888        }
17889
17890        mUserSwitchObservers.register(observer);
17891    }
17892
17893    @Override
17894    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17895        mUserSwitchObservers.unregister(observer);
17896    }
17897
17898    private boolean userExists(int userId) {
17899        if (userId == 0) {
17900            return true;
17901        }
17902        UserManagerService ums = getUserManagerLocked();
17903        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17904    }
17905
17906    int[] getUsersLocked() {
17907        UserManagerService ums = getUserManagerLocked();
17908        return ums != null ? ums.getUserIds() : new int[] { 0 };
17909    }
17910
17911    UserManagerService getUserManagerLocked() {
17912        if (mUserManager == null) {
17913            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17914            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17915        }
17916        return mUserManager;
17917    }
17918
17919    private int applyUserId(int uid, int userId) {
17920        return UserHandle.getUid(userId, uid);
17921    }
17922
17923    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17924        if (info == null) return null;
17925        ApplicationInfo newInfo = new ApplicationInfo(info);
17926        newInfo.uid = applyUserId(info.uid, userId);
17927        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17928                + info.packageName;
17929        return newInfo;
17930    }
17931
17932    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17933        if (aInfo == null
17934                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17935            return aInfo;
17936        }
17937
17938        ActivityInfo info = new ActivityInfo(aInfo);
17939        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17940        return info;
17941    }
17942
17943    private final class LocalService extends ActivityManagerInternal {
17944        @Override
17945        public void goingToSleep() {
17946            ActivityManagerService.this.goingToSleep();
17947        }
17948
17949        @Override
17950        public void wakingUp() {
17951            ActivityManagerService.this.wakingUp();
17952        }
17953
17954        @Override
17955        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
17956                String processName, String abiOverride, int uid, Runnable crashHandler) {
17957            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
17958                    processName, abiOverride, uid, crashHandler);
17959        }
17960    }
17961
17962    /**
17963     * An implementation of IAppTask, that allows an app to manage its own tasks via
17964     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17965     * only the process that calls getAppTasks() can call the AppTask methods.
17966     */
17967    class AppTaskImpl extends IAppTask.Stub {
17968        private int mTaskId;
17969        private int mCallingUid;
17970
17971        public AppTaskImpl(int taskId, int callingUid) {
17972            mTaskId = taskId;
17973            mCallingUid = callingUid;
17974        }
17975
17976        @Override
17977        public void finishAndRemoveTask() {
17978            // Ensure that we are called from the same process that created this AppTask
17979            if (mCallingUid != Binder.getCallingUid()) {
17980                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17981                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17982                return;
17983            }
17984
17985            synchronized (ActivityManagerService.this) {
17986                long origId = Binder.clearCallingIdentity();
17987                try {
17988                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17989                    if (tr != null) {
17990                        // Only kill the process if we are not a new document
17991                        int flags = tr.getBaseIntent().getFlags();
17992                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17993                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17994                        removeTaskByIdLocked(mTaskId,
17995                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17996                    }
17997                } finally {
17998                    Binder.restoreCallingIdentity(origId);
17999                }
18000            }
18001        }
18002
18003        @Override
18004        public ActivityManager.RecentTaskInfo getTaskInfo() {
18005            // Ensure that we are called from the same process that created this AppTask
18006            if (mCallingUid != Binder.getCallingUid()) {
18007                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
18008                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18009                return null;
18010            }
18011
18012            synchronized (ActivityManagerService.this) {
18013                long origId = Binder.clearCallingIdentity();
18014                try {
18015                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18016                    if (tr != null) {
18017                        return createRecentTaskInfoFromTaskRecord(tr);
18018                    }
18019                } finally {
18020                    Binder.restoreCallingIdentity(origId);
18021                }
18022                return null;
18023            }
18024        }
18025    }
18026}
18027