ActivityManagerService.java revision 4a8dddbf18fedb33bb2c725db489669a141e1d73
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) {
4205       appDiedLocked(app, app.pid, app.thread);
4206    }
4207
4208    final void appDiedLocked(ProcessRecord app, int pid,
4209            IApplicationThread thread) {
4210
4211        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4212        synchronized (stats) {
4213            stats.noteProcessDiedLocked(app.info.uid, pid);
4214        }
4215
4216        Process.killProcessGroup(app.info.uid, pid);
4217
4218        // Clean up already done if the process has been re-started.
4219        if (app.pid == pid && app.thread != null &&
4220                app.thread.asBinder() == thread.asBinder()) {
4221            boolean doLowMem = app.instrumentationClass == null;
4222            boolean doOomAdj = doLowMem;
4223            if (!app.killedByAm) {
4224                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4225                        + ") has died.");
4226                mAllowLowerMemLevel = true;
4227            } else {
4228                // Note that we always want to do oom adj to update our state with the
4229                // new number of procs.
4230                mAllowLowerMemLevel = false;
4231                doLowMem = false;
4232            }
4233            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4234            if (DEBUG_CLEANUP) Slog.v(
4235                TAG, "Dying app: " + app + ", pid: " + pid
4236                + ", thread: " + thread.asBinder());
4237            handleAppDiedLocked(app, false, true);
4238
4239            if (doOomAdj) {
4240                updateOomAdjLocked();
4241            }
4242            if (doLowMem) {
4243                doLowMemReportIfNeededLocked(app);
4244            }
4245        } else if (app.pid != pid) {
4246            // A new process has already been started.
4247            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4248                    + ") has died and restarted (pid " + app.pid + ").");
4249            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4250        } else if (DEBUG_PROCESSES) {
4251            Slog.d(TAG, "Received spurious death notification for thread "
4252                    + thread.asBinder());
4253        }
4254    }
4255
4256    /**
4257     * If a stack trace dump file is configured, dump process stack traces.
4258     * @param clearTraces causes the dump file to be erased prior to the new
4259     *    traces being written, if true; when false, the new traces will be
4260     *    appended to any existing file content.
4261     * @param firstPids of dalvik VM processes to dump stack traces for first
4262     * @param lastPids of dalvik VM processes to dump stack traces for last
4263     * @param nativeProcs optional list of native process names to dump stack crawls
4264     * @return file containing stack traces, or null if no dump file is configured
4265     */
4266    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4267            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4268        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4269        if (tracesPath == null || tracesPath.length() == 0) {
4270            return null;
4271        }
4272
4273        File tracesFile = new File(tracesPath);
4274        try {
4275            File tracesDir = tracesFile.getParentFile();
4276            if (!tracesDir.exists()) {
4277                tracesFile.mkdirs();
4278                if (!SELinux.restorecon(tracesDir)) {
4279                    return null;
4280                }
4281            }
4282            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4283
4284            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4285            tracesFile.createNewFile();
4286            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4287        } catch (IOException e) {
4288            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4289            return null;
4290        }
4291
4292        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4293        return tracesFile;
4294    }
4295
4296    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4297            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4298        // Use a FileObserver to detect when traces finish writing.
4299        // The order of traces is considered important to maintain for legibility.
4300        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4301            @Override
4302            public synchronized void onEvent(int event, String path) { notify(); }
4303        };
4304
4305        try {
4306            observer.startWatching();
4307
4308            // First collect all of the stacks of the most important pids.
4309            if (firstPids != null) {
4310                try {
4311                    int num = firstPids.size();
4312                    for (int i = 0; i < num; i++) {
4313                        synchronized (observer) {
4314                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4315                            observer.wait(200);  // Wait for write-close, give up after 200msec
4316                        }
4317                    }
4318                } catch (InterruptedException e) {
4319                    Log.wtf(TAG, e);
4320                }
4321            }
4322
4323            // Next collect the stacks of the native pids
4324            if (nativeProcs != null) {
4325                int[] pids = Process.getPidsForCommands(nativeProcs);
4326                if (pids != null) {
4327                    for (int pid : pids) {
4328                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4329                    }
4330                }
4331            }
4332
4333            // Lastly, measure CPU usage.
4334            if (processCpuTracker != null) {
4335                processCpuTracker.init();
4336                System.gc();
4337                processCpuTracker.update();
4338                try {
4339                    synchronized (processCpuTracker) {
4340                        processCpuTracker.wait(500); // measure over 1/2 second.
4341                    }
4342                } catch (InterruptedException e) {
4343                }
4344                processCpuTracker.update();
4345
4346                // We'll take the stack crawls of just the top apps using CPU.
4347                final int N = processCpuTracker.countWorkingStats();
4348                int numProcs = 0;
4349                for (int i=0; i<N && numProcs<5; i++) {
4350                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4351                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4352                        numProcs++;
4353                        try {
4354                            synchronized (observer) {
4355                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4356                                observer.wait(200);  // Wait for write-close, give up after 200msec
4357                            }
4358                        } catch (InterruptedException e) {
4359                            Log.wtf(TAG, e);
4360                        }
4361
4362                    }
4363                }
4364            }
4365        } finally {
4366            observer.stopWatching();
4367        }
4368    }
4369
4370    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4371        if (true || IS_USER_BUILD) {
4372            return;
4373        }
4374        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4375        if (tracesPath == null || tracesPath.length() == 0) {
4376            return;
4377        }
4378
4379        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4380        StrictMode.allowThreadDiskWrites();
4381        try {
4382            final File tracesFile = new File(tracesPath);
4383            final File tracesDir = tracesFile.getParentFile();
4384            final File tracesTmp = new File(tracesDir, "__tmp__");
4385            try {
4386                if (!tracesDir.exists()) {
4387                    tracesFile.mkdirs();
4388                    if (!SELinux.restorecon(tracesDir.getPath())) {
4389                        return;
4390                    }
4391                }
4392                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4393
4394                if (tracesFile.exists()) {
4395                    tracesTmp.delete();
4396                    tracesFile.renameTo(tracesTmp);
4397                }
4398                StringBuilder sb = new StringBuilder();
4399                Time tobj = new Time();
4400                tobj.set(System.currentTimeMillis());
4401                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4402                sb.append(": ");
4403                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4404                sb.append(" since ");
4405                sb.append(msg);
4406                FileOutputStream fos = new FileOutputStream(tracesFile);
4407                fos.write(sb.toString().getBytes());
4408                if (app == null) {
4409                    fos.write("\n*** No application process!".getBytes());
4410                }
4411                fos.close();
4412                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4413            } catch (IOException e) {
4414                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4415                return;
4416            }
4417
4418            if (app != null) {
4419                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4420                firstPids.add(app.pid);
4421                dumpStackTraces(tracesPath, firstPids, null, null, null);
4422            }
4423
4424            File lastTracesFile = null;
4425            File curTracesFile = null;
4426            for (int i=9; i>=0; i--) {
4427                String name = String.format(Locale.US, "slow%02d.txt", i);
4428                curTracesFile = new File(tracesDir, name);
4429                if (curTracesFile.exists()) {
4430                    if (lastTracesFile != null) {
4431                        curTracesFile.renameTo(lastTracesFile);
4432                    } else {
4433                        curTracesFile.delete();
4434                    }
4435                }
4436                lastTracesFile = curTracesFile;
4437            }
4438            tracesFile.renameTo(curTracesFile);
4439            if (tracesTmp.exists()) {
4440                tracesTmp.renameTo(tracesFile);
4441            }
4442        } finally {
4443            StrictMode.setThreadPolicy(oldPolicy);
4444        }
4445    }
4446
4447    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4448            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4449        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4450        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4451
4452        if (mController != null) {
4453            try {
4454                // 0 == continue, -1 = kill process immediately
4455                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4456                if (res < 0 && app.pid != MY_PID) {
4457                    Process.killProcess(app.pid);
4458                    Process.killProcessGroup(app.info.uid, app.pid);
4459                }
4460            } catch (RemoteException e) {
4461                mController = null;
4462                Watchdog.getInstance().setActivityController(null);
4463            }
4464        }
4465
4466        long anrTime = SystemClock.uptimeMillis();
4467        if (MONITOR_CPU_USAGE) {
4468            updateCpuStatsNow();
4469        }
4470
4471        synchronized (this) {
4472            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4473            if (mShuttingDown) {
4474                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4475                return;
4476            } else if (app.notResponding) {
4477                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4478                return;
4479            } else if (app.crashing) {
4480                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4481                return;
4482            }
4483
4484            // In case we come through here for the same app before completing
4485            // this one, mark as anring now so we will bail out.
4486            app.notResponding = true;
4487
4488            // Log the ANR to the event log.
4489            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4490                    app.processName, app.info.flags, annotation);
4491
4492            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4493            firstPids.add(app.pid);
4494
4495            int parentPid = app.pid;
4496            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4497            if (parentPid != app.pid) firstPids.add(parentPid);
4498
4499            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4500
4501            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4502                ProcessRecord r = mLruProcesses.get(i);
4503                if (r != null && r.thread != null) {
4504                    int pid = r.pid;
4505                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4506                        if (r.persistent) {
4507                            firstPids.add(pid);
4508                        } else {
4509                            lastPids.put(pid, Boolean.TRUE);
4510                        }
4511                    }
4512                }
4513            }
4514        }
4515
4516        // Log the ANR to the main log.
4517        StringBuilder info = new StringBuilder();
4518        info.setLength(0);
4519        info.append("ANR in ").append(app.processName);
4520        if (activity != null && activity.shortComponentName != null) {
4521            info.append(" (").append(activity.shortComponentName).append(")");
4522        }
4523        info.append("\n");
4524        info.append("PID: ").append(app.pid).append("\n");
4525        if (annotation != null) {
4526            info.append("Reason: ").append(annotation).append("\n");
4527        }
4528        if (parent != null && parent != activity) {
4529            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4530        }
4531
4532        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4533
4534        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4535                NATIVE_STACKS_OF_INTEREST);
4536
4537        String cpuInfo = null;
4538        if (MONITOR_CPU_USAGE) {
4539            updateCpuStatsNow();
4540            synchronized (mProcessCpuThread) {
4541                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4542            }
4543            info.append(processCpuTracker.printCurrentLoad());
4544            info.append(cpuInfo);
4545        }
4546
4547        info.append(processCpuTracker.printCurrentState(anrTime));
4548
4549        Slog.e(TAG, info.toString());
4550        if (tracesFile == null) {
4551            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4552            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4553        }
4554
4555        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4556                cpuInfo, tracesFile, null);
4557
4558        if (mController != null) {
4559            try {
4560                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4561                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4562                if (res != 0) {
4563                    if (res < 0 && app.pid != MY_PID) {
4564                        Process.killProcess(app.pid);
4565                        Process.killProcessGroup(app.info.uid, app.pid);
4566                    } else {
4567                        synchronized (this) {
4568                            mServices.scheduleServiceTimeoutLocked(app);
4569                        }
4570                    }
4571                    return;
4572                }
4573            } catch (RemoteException e) {
4574                mController = null;
4575                Watchdog.getInstance().setActivityController(null);
4576            }
4577        }
4578
4579        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4580        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4581                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4582
4583        synchronized (this) {
4584            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4585                killUnneededProcessLocked(app, "background ANR");
4586                return;
4587            }
4588
4589            // Set the app's notResponding state, and look up the errorReportReceiver
4590            makeAppNotRespondingLocked(app,
4591                    activity != null ? activity.shortComponentName : null,
4592                    annotation != null ? "ANR " + annotation : "ANR",
4593                    info.toString());
4594
4595            // Bring up the infamous App Not Responding dialog
4596            Message msg = Message.obtain();
4597            HashMap<String, Object> map = new HashMap<String, Object>();
4598            msg.what = SHOW_NOT_RESPONDING_MSG;
4599            msg.obj = map;
4600            msg.arg1 = aboveSystem ? 1 : 0;
4601            map.put("app", app);
4602            if (activity != null) {
4603                map.put("activity", activity);
4604            }
4605
4606            mHandler.sendMessage(msg);
4607        }
4608    }
4609
4610    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4611        if (!mLaunchWarningShown) {
4612            mLaunchWarningShown = true;
4613            mHandler.post(new Runnable() {
4614                @Override
4615                public void run() {
4616                    synchronized (ActivityManagerService.this) {
4617                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4618                        d.show();
4619                        mHandler.postDelayed(new Runnable() {
4620                            @Override
4621                            public void run() {
4622                                synchronized (ActivityManagerService.this) {
4623                                    d.dismiss();
4624                                    mLaunchWarningShown = false;
4625                                }
4626                            }
4627                        }, 4000);
4628                    }
4629                }
4630            });
4631        }
4632    }
4633
4634    @Override
4635    public boolean clearApplicationUserData(final String packageName,
4636            final IPackageDataObserver observer, int userId) {
4637        enforceNotIsolatedCaller("clearApplicationUserData");
4638        int uid = Binder.getCallingUid();
4639        int pid = Binder.getCallingPid();
4640        userId = handleIncomingUser(pid, uid,
4641                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4642        long callingId = Binder.clearCallingIdentity();
4643        try {
4644            IPackageManager pm = AppGlobals.getPackageManager();
4645            int pkgUid = -1;
4646            synchronized(this) {
4647                try {
4648                    pkgUid = pm.getPackageUid(packageName, userId);
4649                } catch (RemoteException e) {
4650                }
4651                if (pkgUid == -1) {
4652                    Slog.w(TAG, "Invalid packageName: " + packageName);
4653                    if (observer != null) {
4654                        try {
4655                            observer.onRemoveCompleted(packageName, false);
4656                        } catch (RemoteException e) {
4657                            Slog.i(TAG, "Observer no longer exists.");
4658                        }
4659                    }
4660                    return false;
4661                }
4662                if (uid == pkgUid || checkComponentPermission(
4663                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4664                        pid, uid, -1, true)
4665                        == PackageManager.PERMISSION_GRANTED) {
4666                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4667                } else {
4668                    throw new SecurityException("PID " + pid + " does not have permission "
4669                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4670                                    + " of package " + packageName);
4671                }
4672
4673                // Remove all tasks match the cleared application package and user
4674                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
4675                    final TaskRecord tr = mRecentTasks.get(i);
4676                    final String taskPackageName =
4677                            tr.getBaseIntent().getComponent().getPackageName();
4678                    if (tr.userId != userId) continue;
4679                    if (!taskPackageName.equals(packageName)) continue;
4680                    removeTaskByIdLocked(tr.taskId, 0);
4681                }
4682            }
4683
4684            try {
4685                // Clear application user data
4686                pm.clearApplicationUserData(packageName, observer, userId);
4687
4688                synchronized(this) {
4689                    // Remove all permissions granted from/to this package
4690                    removeUriPermissionsForPackageLocked(packageName, userId, true);
4691                }
4692
4693                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4694                        Uri.fromParts("package", packageName, null));
4695                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4696                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4697                        null, null, 0, null, null, null, false, false, userId);
4698            } catch (RemoteException e) {
4699            }
4700        } finally {
4701            Binder.restoreCallingIdentity(callingId);
4702        }
4703        return true;
4704    }
4705
4706    @Override
4707    public void killBackgroundProcesses(final String packageName, int userId) {
4708        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4709                != PackageManager.PERMISSION_GRANTED &&
4710                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4711                        != PackageManager.PERMISSION_GRANTED) {
4712            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4713                    + Binder.getCallingPid()
4714                    + ", uid=" + Binder.getCallingUid()
4715                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4716            Slog.w(TAG, msg);
4717            throw new SecurityException(msg);
4718        }
4719
4720        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4721                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4722        long callingId = Binder.clearCallingIdentity();
4723        try {
4724            IPackageManager pm = AppGlobals.getPackageManager();
4725            synchronized(this) {
4726                int appId = -1;
4727                try {
4728                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4729                } catch (RemoteException e) {
4730                }
4731                if (appId == -1) {
4732                    Slog.w(TAG, "Invalid packageName: " + packageName);
4733                    return;
4734                }
4735                killPackageProcessesLocked(packageName, appId, userId,
4736                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4737            }
4738        } finally {
4739            Binder.restoreCallingIdentity(callingId);
4740        }
4741    }
4742
4743    @Override
4744    public void killAllBackgroundProcesses() {
4745        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4746                != PackageManager.PERMISSION_GRANTED) {
4747            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4748                    + Binder.getCallingPid()
4749                    + ", uid=" + Binder.getCallingUid()
4750                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4751            Slog.w(TAG, msg);
4752            throw new SecurityException(msg);
4753        }
4754
4755        long callingId = Binder.clearCallingIdentity();
4756        try {
4757            synchronized(this) {
4758                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4759                final int NP = mProcessNames.getMap().size();
4760                for (int ip=0; ip<NP; ip++) {
4761                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4762                    final int NA = apps.size();
4763                    for (int ia=0; ia<NA; ia++) {
4764                        ProcessRecord app = apps.valueAt(ia);
4765                        if (app.persistent) {
4766                            // we don't kill persistent processes
4767                            continue;
4768                        }
4769                        if (app.removed) {
4770                            procs.add(app);
4771                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4772                            app.removed = true;
4773                            procs.add(app);
4774                        }
4775                    }
4776                }
4777
4778                int N = procs.size();
4779                for (int i=0; i<N; i++) {
4780                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4781                }
4782                mAllowLowerMemLevel = true;
4783                updateOomAdjLocked();
4784                doLowMemReportIfNeededLocked(null);
4785            }
4786        } finally {
4787            Binder.restoreCallingIdentity(callingId);
4788        }
4789    }
4790
4791    @Override
4792    public void forceStopPackage(final String packageName, int userId) {
4793        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4794                != PackageManager.PERMISSION_GRANTED) {
4795            String msg = "Permission Denial: forceStopPackage() from pid="
4796                    + Binder.getCallingPid()
4797                    + ", uid=" + Binder.getCallingUid()
4798                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4799            Slog.w(TAG, msg);
4800            throw new SecurityException(msg);
4801        }
4802        final int callingPid = Binder.getCallingPid();
4803        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4804                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4805        long callingId = Binder.clearCallingIdentity();
4806        try {
4807            IPackageManager pm = AppGlobals.getPackageManager();
4808            synchronized(this) {
4809                int[] users = userId == UserHandle.USER_ALL
4810                        ? getUsersLocked() : new int[] { userId };
4811                for (int user : users) {
4812                    int pkgUid = -1;
4813                    try {
4814                        pkgUid = pm.getPackageUid(packageName, user);
4815                    } catch (RemoteException e) {
4816                    }
4817                    if (pkgUid == -1) {
4818                        Slog.w(TAG, "Invalid packageName: " + packageName);
4819                        continue;
4820                    }
4821                    try {
4822                        pm.setPackageStoppedState(packageName, true, user);
4823                    } catch (RemoteException e) {
4824                    } catch (IllegalArgumentException e) {
4825                        Slog.w(TAG, "Failed trying to unstop package "
4826                                + packageName + ": " + e);
4827                    }
4828                    if (isUserRunningLocked(user, false)) {
4829                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4830                    }
4831                }
4832            }
4833        } finally {
4834            Binder.restoreCallingIdentity(callingId);
4835        }
4836    }
4837
4838    @Override
4839    public void addPackageDependency(String packageName) {
4840        synchronized (this) {
4841            int callingPid = Binder.getCallingPid();
4842            if (callingPid == Process.myPid()) {
4843                //  Yeah, um, no.
4844                Slog.w(TAG, "Can't addPackageDependency on system process");
4845                return;
4846            }
4847            ProcessRecord proc;
4848            synchronized (mPidsSelfLocked) {
4849                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4850            }
4851            if (proc != null) {
4852                if (proc.pkgDeps == null) {
4853                    proc.pkgDeps = new ArraySet<String>(1);
4854                }
4855                proc.pkgDeps.add(packageName);
4856            }
4857        }
4858    }
4859
4860    /*
4861     * The pkg name and app id have to be specified.
4862     */
4863    @Override
4864    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4865        if (pkg == null) {
4866            return;
4867        }
4868        // Make sure the uid is valid.
4869        if (appid < 0) {
4870            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4871            return;
4872        }
4873        int callerUid = Binder.getCallingUid();
4874        // Only the system server can kill an application
4875        if (callerUid == Process.SYSTEM_UID) {
4876            // Post an aysnc message to kill the application
4877            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4878            msg.arg1 = appid;
4879            msg.arg2 = 0;
4880            Bundle bundle = new Bundle();
4881            bundle.putString("pkg", pkg);
4882            bundle.putString("reason", reason);
4883            msg.obj = bundle;
4884            mHandler.sendMessage(msg);
4885        } else {
4886            throw new SecurityException(callerUid + " cannot kill pkg: " +
4887                    pkg);
4888        }
4889    }
4890
4891    @Override
4892    public void closeSystemDialogs(String reason) {
4893        enforceNotIsolatedCaller("closeSystemDialogs");
4894
4895        final int pid = Binder.getCallingPid();
4896        final int uid = Binder.getCallingUid();
4897        final long origId = Binder.clearCallingIdentity();
4898        try {
4899            synchronized (this) {
4900                // Only allow this from foreground processes, so that background
4901                // applications can't abuse it to prevent system UI from being shown.
4902                if (uid >= Process.FIRST_APPLICATION_UID) {
4903                    ProcessRecord proc;
4904                    synchronized (mPidsSelfLocked) {
4905                        proc = mPidsSelfLocked.get(pid);
4906                    }
4907                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4908                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4909                                + " from background process " + proc);
4910                        return;
4911                    }
4912                }
4913                closeSystemDialogsLocked(reason);
4914            }
4915        } finally {
4916            Binder.restoreCallingIdentity(origId);
4917        }
4918    }
4919
4920    void closeSystemDialogsLocked(String reason) {
4921        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4922        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4923                | Intent.FLAG_RECEIVER_FOREGROUND);
4924        if (reason != null) {
4925            intent.putExtra("reason", reason);
4926        }
4927        mWindowManager.closeSystemDialogs(reason);
4928
4929        mStackSupervisor.closeSystemDialogsLocked();
4930
4931        broadcastIntentLocked(null, null, intent, null,
4932                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4933                Process.SYSTEM_UID, UserHandle.USER_ALL);
4934    }
4935
4936    @Override
4937    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4938        enforceNotIsolatedCaller("getProcessMemoryInfo");
4939        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4940        for (int i=pids.length-1; i>=0; i--) {
4941            ProcessRecord proc;
4942            int oomAdj;
4943            synchronized (this) {
4944                synchronized (mPidsSelfLocked) {
4945                    proc = mPidsSelfLocked.get(pids[i]);
4946                    oomAdj = proc != null ? proc.setAdj : 0;
4947                }
4948            }
4949            infos[i] = new Debug.MemoryInfo();
4950            Debug.getMemoryInfo(pids[i], infos[i]);
4951            if (proc != null) {
4952                synchronized (this) {
4953                    if (proc.thread != null && proc.setAdj == oomAdj) {
4954                        // Record this for posterity if the process has been stable.
4955                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4956                                infos[i].getTotalUss(), false, proc.pkgList);
4957                    }
4958                }
4959            }
4960        }
4961        return infos;
4962    }
4963
4964    @Override
4965    public long[] getProcessPss(int[] pids) {
4966        enforceNotIsolatedCaller("getProcessPss");
4967        long[] pss = new long[pids.length];
4968        for (int i=pids.length-1; i>=0; i--) {
4969            ProcessRecord proc;
4970            int oomAdj;
4971            synchronized (this) {
4972                synchronized (mPidsSelfLocked) {
4973                    proc = mPidsSelfLocked.get(pids[i]);
4974                    oomAdj = proc != null ? proc.setAdj : 0;
4975                }
4976            }
4977            long[] tmpUss = new long[1];
4978            pss[i] = Debug.getPss(pids[i], tmpUss);
4979            if (proc != null) {
4980                synchronized (this) {
4981                    if (proc.thread != null && proc.setAdj == oomAdj) {
4982                        // Record this for posterity if the process has been stable.
4983                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4984                    }
4985                }
4986            }
4987        }
4988        return pss;
4989    }
4990
4991    @Override
4992    public void killApplicationProcess(String processName, int uid) {
4993        if (processName == null) {
4994            return;
4995        }
4996
4997        int callerUid = Binder.getCallingUid();
4998        // Only the system server can kill an application
4999        if (callerUid == Process.SYSTEM_UID) {
5000            synchronized (this) {
5001                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5002                if (app != null && app.thread != null) {
5003                    try {
5004                        app.thread.scheduleSuicide();
5005                    } catch (RemoteException e) {
5006                        // If the other end already died, then our work here is done.
5007                    }
5008                } else {
5009                    Slog.w(TAG, "Process/uid not found attempting kill of "
5010                            + processName + " / " + uid);
5011                }
5012            }
5013        } else {
5014            throw new SecurityException(callerUid + " cannot kill app process: " +
5015                    processName);
5016        }
5017    }
5018
5019    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5020        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5021                false, true, false, false, UserHandle.getUserId(uid), reason);
5022        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5023                Uri.fromParts("package", packageName, null));
5024        if (!mProcessesReady) {
5025            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5026                    | Intent.FLAG_RECEIVER_FOREGROUND);
5027        }
5028        intent.putExtra(Intent.EXTRA_UID, uid);
5029        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5030        broadcastIntentLocked(null, null, intent,
5031                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5032                false, false,
5033                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5034    }
5035
5036    private void forceStopUserLocked(int userId, String reason) {
5037        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5038        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5039        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5040                | Intent.FLAG_RECEIVER_FOREGROUND);
5041        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5042        broadcastIntentLocked(null, null, intent,
5043                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5044                false, false,
5045                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5046    }
5047
5048    private final boolean killPackageProcessesLocked(String packageName, int appId,
5049            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5050            boolean doit, boolean evenPersistent, String reason) {
5051        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5052
5053        // Remove all processes this package may have touched: all with the
5054        // same UID (except for the system or root user), and all whose name
5055        // matches the package name.
5056        final int NP = mProcessNames.getMap().size();
5057        for (int ip=0; ip<NP; ip++) {
5058            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5059            final int NA = apps.size();
5060            for (int ia=0; ia<NA; ia++) {
5061                ProcessRecord app = apps.valueAt(ia);
5062                if (app.persistent && !evenPersistent) {
5063                    // we don't kill persistent processes
5064                    continue;
5065                }
5066                if (app.removed) {
5067                    if (doit) {
5068                        procs.add(app);
5069                    }
5070                    continue;
5071                }
5072
5073                // Skip process if it doesn't meet our oom adj requirement.
5074                if (app.setAdj < minOomAdj) {
5075                    continue;
5076                }
5077
5078                // If no package is specified, we call all processes under the
5079                // give user id.
5080                if (packageName == null) {
5081                    if (app.userId != userId) {
5082                        continue;
5083                    }
5084                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5085                        continue;
5086                    }
5087                // Package has been specified, we want to hit all processes
5088                // that match it.  We need to qualify this by the processes
5089                // that are running under the specified app and user ID.
5090                } else {
5091                    final boolean isDep = app.pkgDeps != null
5092                            && app.pkgDeps.contains(packageName);
5093                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5094                        continue;
5095                    }
5096                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5097                        continue;
5098                    }
5099                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5100                        continue;
5101                    }
5102                }
5103
5104                // Process has passed all conditions, kill it!
5105                if (!doit) {
5106                    return true;
5107                }
5108                app.removed = true;
5109                procs.add(app);
5110            }
5111        }
5112
5113        int N = procs.size();
5114        for (int i=0; i<N; i++) {
5115            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5116        }
5117        updateOomAdjLocked();
5118        return N > 0;
5119    }
5120
5121    private final boolean forceStopPackageLocked(String name, int appId,
5122            boolean callerWillRestart, boolean purgeCache, boolean doit,
5123            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5124        int i;
5125        int N;
5126
5127        if (userId == UserHandle.USER_ALL && name == null) {
5128            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5129        }
5130
5131        if (appId < 0 && name != null) {
5132            try {
5133                appId = UserHandle.getAppId(
5134                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5135            } catch (RemoteException e) {
5136            }
5137        }
5138
5139        if (doit) {
5140            if (name != null) {
5141                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5142                        + " user=" + userId + ": " + reason);
5143            } else {
5144                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5145            }
5146
5147            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5148            for (int ip=pmap.size()-1; ip>=0; ip--) {
5149                SparseArray<Long> ba = pmap.valueAt(ip);
5150                for (i=ba.size()-1; i>=0; i--) {
5151                    boolean remove = false;
5152                    final int entUid = ba.keyAt(i);
5153                    if (name != null) {
5154                        if (userId == UserHandle.USER_ALL) {
5155                            if (UserHandle.getAppId(entUid) == appId) {
5156                                remove = true;
5157                            }
5158                        } else {
5159                            if (entUid == UserHandle.getUid(userId, appId)) {
5160                                remove = true;
5161                            }
5162                        }
5163                    } else if (UserHandle.getUserId(entUid) == userId) {
5164                        remove = true;
5165                    }
5166                    if (remove) {
5167                        ba.removeAt(i);
5168                    }
5169                }
5170                if (ba.size() == 0) {
5171                    pmap.removeAt(ip);
5172                }
5173            }
5174        }
5175
5176        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5177                -100, callerWillRestart, true, doit, evenPersistent,
5178                name == null ? ("stop user " + userId) : ("stop " + name));
5179
5180        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5181            if (!doit) {
5182                return true;
5183            }
5184            didSomething = true;
5185        }
5186
5187        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5188            if (!doit) {
5189                return true;
5190            }
5191            didSomething = true;
5192        }
5193
5194        if (name == null) {
5195            // Remove all sticky broadcasts from this user.
5196            mStickyBroadcasts.remove(userId);
5197        }
5198
5199        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5200        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5201                userId, providers)) {
5202            if (!doit) {
5203                return true;
5204            }
5205            didSomething = true;
5206        }
5207        N = providers.size();
5208        for (i=0; i<N; i++) {
5209            removeDyingProviderLocked(null, providers.get(i), true);
5210        }
5211
5212        // Remove transient permissions granted from/to this package/user
5213        removeUriPermissionsForPackageLocked(name, userId, false);
5214
5215        if (name == null || uninstalling) {
5216            // Remove pending intents.  For now we only do this when force
5217            // stopping users, because we have some problems when doing this
5218            // for packages -- app widgets are not currently cleaned up for
5219            // such packages, so they can be left with bad pending intents.
5220            if (mIntentSenderRecords.size() > 0) {
5221                Iterator<WeakReference<PendingIntentRecord>> it
5222                        = mIntentSenderRecords.values().iterator();
5223                while (it.hasNext()) {
5224                    WeakReference<PendingIntentRecord> wpir = it.next();
5225                    if (wpir == null) {
5226                        it.remove();
5227                        continue;
5228                    }
5229                    PendingIntentRecord pir = wpir.get();
5230                    if (pir == null) {
5231                        it.remove();
5232                        continue;
5233                    }
5234                    if (name == null) {
5235                        // Stopping user, remove all objects for the user.
5236                        if (pir.key.userId != userId) {
5237                            // Not the same user, skip it.
5238                            continue;
5239                        }
5240                    } else {
5241                        if (UserHandle.getAppId(pir.uid) != appId) {
5242                            // Different app id, skip it.
5243                            continue;
5244                        }
5245                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5246                            // Different user, skip it.
5247                            continue;
5248                        }
5249                        if (!pir.key.packageName.equals(name)) {
5250                            // Different package, skip it.
5251                            continue;
5252                        }
5253                    }
5254                    if (!doit) {
5255                        return true;
5256                    }
5257                    didSomething = true;
5258                    it.remove();
5259                    pir.canceled = true;
5260                    if (pir.key.activity != null) {
5261                        pir.key.activity.pendingResults.remove(pir.ref);
5262                    }
5263                }
5264            }
5265        }
5266
5267        if (doit) {
5268            if (purgeCache && name != null) {
5269                AttributeCache ac = AttributeCache.instance();
5270                if (ac != null) {
5271                    ac.removePackage(name);
5272                }
5273            }
5274            if (mBooted) {
5275                mStackSupervisor.resumeTopActivitiesLocked();
5276                mStackSupervisor.scheduleIdleLocked();
5277            }
5278        }
5279
5280        return didSomething;
5281    }
5282
5283    private final boolean removeProcessLocked(ProcessRecord app,
5284            boolean callerWillRestart, boolean allowRestart, String reason) {
5285        final String name = app.processName;
5286        final int uid = app.uid;
5287        if (DEBUG_PROCESSES) Slog.d(
5288            TAG, "Force removing proc " + app.toShortString() + " (" + name
5289            + "/" + uid + ")");
5290
5291        mProcessNames.remove(name, uid);
5292        mIsolatedProcesses.remove(app.uid);
5293        if (mHeavyWeightProcess == app) {
5294            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5295                    mHeavyWeightProcess.userId, 0));
5296            mHeavyWeightProcess = null;
5297        }
5298        boolean needRestart = false;
5299        if (app.pid > 0 && app.pid != MY_PID) {
5300            int pid = app.pid;
5301            synchronized (mPidsSelfLocked) {
5302                mPidsSelfLocked.remove(pid);
5303                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5304            }
5305            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5306            if (app.isolated) {
5307                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5308            }
5309            killUnneededProcessLocked(app, reason);
5310            Process.killProcessGroup(app.info.uid, app.pid);
5311            handleAppDiedLocked(app, true, allowRestart);
5312            removeLruProcessLocked(app);
5313
5314            if (app.persistent && !app.isolated) {
5315                if (!callerWillRestart) {
5316                    addAppLocked(app.info, false, null /* ABI override */);
5317                } else {
5318                    needRestart = true;
5319                }
5320            }
5321        } else {
5322            mRemovedProcesses.add(app);
5323        }
5324
5325        return needRestart;
5326    }
5327
5328    private final void processStartTimedOutLocked(ProcessRecord app) {
5329        final int pid = app.pid;
5330        boolean gone = false;
5331        synchronized (mPidsSelfLocked) {
5332            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5333            if (knownApp != null && knownApp.thread == null) {
5334                mPidsSelfLocked.remove(pid);
5335                gone = true;
5336            }
5337        }
5338
5339        if (gone) {
5340            Slog.w(TAG, "Process " + app + " failed to attach");
5341            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5342                    pid, app.uid, app.processName);
5343            mProcessNames.remove(app.processName, app.uid);
5344            mIsolatedProcesses.remove(app.uid);
5345            if (mHeavyWeightProcess == app) {
5346                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5347                        mHeavyWeightProcess.userId, 0));
5348                mHeavyWeightProcess = null;
5349            }
5350            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5351            if (app.isolated) {
5352                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5353            }
5354            // Take care of any launching providers waiting for this process.
5355            checkAppInLaunchingProvidersLocked(app, true);
5356            // Take care of any services that are waiting for the process.
5357            mServices.processStartTimedOutLocked(app);
5358            killUnneededProcessLocked(app, "start timeout");
5359            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5360                Slog.w(TAG, "Unattached app died before backup, skipping");
5361                try {
5362                    IBackupManager bm = IBackupManager.Stub.asInterface(
5363                            ServiceManager.getService(Context.BACKUP_SERVICE));
5364                    bm.agentDisconnected(app.info.packageName);
5365                } catch (RemoteException e) {
5366                    // Can't happen; the backup manager is local
5367                }
5368            }
5369            if (isPendingBroadcastProcessLocked(pid)) {
5370                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5371                skipPendingBroadcastLocked(pid);
5372            }
5373        } else {
5374            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5375        }
5376    }
5377
5378    private final boolean attachApplicationLocked(IApplicationThread thread,
5379            int pid) {
5380
5381        // Find the application record that is being attached...  either via
5382        // the pid if we are running in multiple processes, or just pull the
5383        // next app record if we are emulating process with anonymous threads.
5384        ProcessRecord app;
5385        if (pid != MY_PID && pid >= 0) {
5386            synchronized (mPidsSelfLocked) {
5387                app = mPidsSelfLocked.get(pid);
5388            }
5389        } else {
5390            app = null;
5391        }
5392
5393        if (app == null) {
5394            Slog.w(TAG, "No pending application record for pid " + pid
5395                    + " (IApplicationThread " + thread + "); dropping process");
5396            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5397            if (pid > 0 && pid != MY_PID) {
5398                Process.killProcessQuiet(pid);
5399                //TODO: Process.killProcessGroup(app.info.uid, pid);
5400            } else {
5401                try {
5402                    thread.scheduleExit();
5403                } catch (Exception e) {
5404                    // Ignore exceptions.
5405                }
5406            }
5407            return false;
5408        }
5409
5410        // If this application record is still attached to a previous
5411        // process, clean it up now.
5412        if (app.thread != null) {
5413            handleAppDiedLocked(app, true, true);
5414        }
5415
5416        // Tell the process all about itself.
5417
5418        if (localLOGV) Slog.v(
5419                TAG, "Binding process pid " + pid + " to record " + app);
5420
5421        final String processName = app.processName;
5422        try {
5423            AppDeathRecipient adr = new AppDeathRecipient(
5424                    app, pid, thread);
5425            thread.asBinder().linkToDeath(adr, 0);
5426            app.deathRecipient = adr;
5427        } catch (RemoteException e) {
5428            app.resetPackageList(mProcessStats);
5429            startProcessLocked(app, "link fail", processName);
5430            return false;
5431        }
5432
5433        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5434
5435        app.makeActive(thread, mProcessStats);
5436        app.curAdj = app.setAdj = -100;
5437        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5438        app.forcingToForeground = null;
5439        updateProcessForegroundLocked(app, false, false);
5440        app.hasShownUi = false;
5441        app.debugging = false;
5442        app.cached = false;
5443
5444        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5445
5446        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5447        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5448
5449        if (!normalMode) {
5450            Slog.i(TAG, "Launching preboot mode app: " + app);
5451        }
5452
5453        if (localLOGV) Slog.v(
5454            TAG, "New app record " + app
5455            + " thread=" + thread.asBinder() + " pid=" + pid);
5456        try {
5457            int testMode = IApplicationThread.DEBUG_OFF;
5458            if (mDebugApp != null && mDebugApp.equals(processName)) {
5459                testMode = mWaitForDebugger
5460                    ? IApplicationThread.DEBUG_WAIT
5461                    : IApplicationThread.DEBUG_ON;
5462                app.debugging = true;
5463                if (mDebugTransient) {
5464                    mDebugApp = mOrigDebugApp;
5465                    mWaitForDebugger = mOrigWaitForDebugger;
5466                }
5467            }
5468            String profileFile = app.instrumentationProfileFile;
5469            ParcelFileDescriptor profileFd = null;
5470            boolean profileAutoStop = false;
5471            if (mProfileApp != null && mProfileApp.equals(processName)) {
5472                mProfileProc = app;
5473                profileFile = mProfileFile;
5474                profileFd = mProfileFd;
5475                profileAutoStop = mAutoStopProfiler;
5476            }
5477            boolean enableOpenGlTrace = false;
5478            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5479                enableOpenGlTrace = true;
5480                mOpenGlTraceApp = null;
5481            }
5482
5483            // If the app is being launched for restore or full backup, set it up specially
5484            boolean isRestrictedBackupMode = false;
5485            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5486                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5487                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5488                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5489            }
5490
5491            ensurePackageDexOpt(app.instrumentationInfo != null
5492                    ? app.instrumentationInfo.packageName
5493                    : app.info.packageName);
5494            if (app.instrumentationClass != null) {
5495                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5496            }
5497            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5498                    + processName + " with config " + mConfiguration);
5499            ApplicationInfo appInfo = app.instrumentationInfo != null
5500                    ? app.instrumentationInfo : app.info;
5501            app.compat = compatibilityInfoForPackageLocked(appInfo);
5502            if (profileFd != null) {
5503                profileFd = profileFd.dup();
5504            }
5505            thread.bindApplication(processName, appInfo, providers,
5506                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5507                    app.instrumentationArguments, app.instrumentationWatcher,
5508                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5509                    isRestrictedBackupMode || !normalMode, app.persistent,
5510                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5511                    mCoreSettingsObserver.getCoreSettingsLocked());
5512            updateLruProcessLocked(app, false, null);
5513            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5514        } catch (Exception e) {
5515            // todo: Yikes!  What should we do?  For now we will try to
5516            // start another process, but that could easily get us in
5517            // an infinite loop of restarting processes...
5518            Slog.w(TAG, "Exception thrown during bind!", e);
5519
5520            app.resetPackageList(mProcessStats);
5521            app.unlinkDeathRecipient();
5522            startProcessLocked(app, "bind fail", processName);
5523            return false;
5524        }
5525
5526        // Remove this record from the list of starting applications.
5527        mPersistentStartingProcesses.remove(app);
5528        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5529                "Attach application locked removing on hold: " + app);
5530        mProcessesOnHold.remove(app);
5531
5532        boolean badApp = false;
5533        boolean didSomething = false;
5534
5535        // See if the top visible activity is waiting to run in this process...
5536        if (normalMode) {
5537            try {
5538                if (mStackSupervisor.attachApplicationLocked(app)) {
5539                    didSomething = true;
5540                }
5541            } catch (Exception e) {
5542                badApp = true;
5543            }
5544        }
5545
5546        // Find any services that should be running in this process...
5547        if (!badApp) {
5548            try {
5549                didSomething |= mServices.attachApplicationLocked(app, processName);
5550            } catch (Exception e) {
5551                badApp = true;
5552            }
5553        }
5554
5555        // Check if a next-broadcast receiver is in this process...
5556        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5557            try {
5558                didSomething |= sendPendingBroadcastsLocked(app);
5559            } catch (Exception e) {
5560                // If the app died trying to launch the receiver we declare it 'bad'
5561                badApp = true;
5562            }
5563        }
5564
5565        // Check whether the next backup agent is in this process...
5566        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5567            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5568            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5569            try {
5570                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5571                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5572                        mBackupTarget.backupMode);
5573            } catch (Exception e) {
5574                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5575                e.printStackTrace();
5576            }
5577        }
5578
5579        if (badApp) {
5580            // todo: Also need to kill application to deal with all
5581            // kinds of exceptions.
5582            handleAppDiedLocked(app, false, true);
5583            return false;
5584        }
5585
5586        if (!didSomething) {
5587            updateOomAdjLocked();
5588        }
5589
5590        return true;
5591    }
5592
5593    @Override
5594    public final void attachApplication(IApplicationThread thread) {
5595        synchronized (this) {
5596            int callingPid = Binder.getCallingPid();
5597            final long origId = Binder.clearCallingIdentity();
5598            attachApplicationLocked(thread, callingPid);
5599            Binder.restoreCallingIdentity(origId);
5600        }
5601    }
5602
5603    @Override
5604    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5605        final long origId = Binder.clearCallingIdentity();
5606        synchronized (this) {
5607            ActivityStack stack = ActivityRecord.getStackLocked(token);
5608            if (stack != null) {
5609                ActivityRecord r =
5610                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5611                if (stopProfiling) {
5612                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5613                        try {
5614                            mProfileFd.close();
5615                        } catch (IOException e) {
5616                        }
5617                        clearProfilerLocked();
5618                    }
5619                }
5620            }
5621        }
5622        Binder.restoreCallingIdentity(origId);
5623    }
5624
5625    void postEnableScreenAfterBootLocked() {
5626        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
5627    }
5628
5629    void enableScreenAfterBoot() {
5630        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5631                SystemClock.uptimeMillis());
5632        mWindowManager.enableScreenAfterBoot();
5633
5634        synchronized (this) {
5635            updateEventDispatchingLocked();
5636        }
5637    }
5638
5639    @Override
5640    public void showBootMessage(final CharSequence msg, final boolean always) {
5641        enforceNotIsolatedCaller("showBootMessage");
5642        mWindowManager.showBootMessage(msg, always);
5643    }
5644
5645    @Override
5646    public void keyguardWaitingForActivityDrawn() {
5647        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
5648        final long token = Binder.clearCallingIdentity();
5649        try {
5650            synchronized (this) {
5651                if (DEBUG_LOCKSCREEN) logLockScreen("");
5652                mWindowManager.keyguardWaitingForActivityDrawn();
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);
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);
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);
9267    }
9268
9269    private void comeOutOfSleepIfNeededLocked() {
9270        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9271            if (mSleeping) {
9272                mSleeping = false;
9273                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9274            }
9275        }
9276    }
9277
9278    void wakingUp() {
9279        synchronized(this) {
9280            mWentToSleep = false;
9281            updateEventDispatchingLocked();
9282            comeOutOfSleepIfNeededLocked();
9283        }
9284    }
9285
9286    void startRunningVoiceLocked() {
9287        if (!mRunningVoice) {
9288            mRunningVoice = true;
9289            comeOutOfSleepIfNeededLocked();
9290        }
9291    }
9292
9293    private void updateEventDispatchingLocked() {
9294        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9295    }
9296
9297    public void setLockScreenShown(boolean shown) {
9298        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9299                != PackageManager.PERMISSION_GRANTED) {
9300            throw new SecurityException("Requires permission "
9301                    + android.Manifest.permission.DEVICE_POWER);
9302        }
9303
9304        synchronized(this) {
9305            long ident = Binder.clearCallingIdentity();
9306            try {
9307                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9308                mLockScreenShown = shown;
9309                comeOutOfSleepIfNeededLocked();
9310            } finally {
9311                Binder.restoreCallingIdentity(ident);
9312            }
9313        }
9314    }
9315
9316    @Override
9317    public void stopAppSwitches() {
9318        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9319                != PackageManager.PERMISSION_GRANTED) {
9320            throw new SecurityException("Requires permission "
9321                    + android.Manifest.permission.STOP_APP_SWITCHES);
9322        }
9323
9324        synchronized(this) {
9325            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9326                    + APP_SWITCH_DELAY_TIME;
9327            mDidAppSwitch = false;
9328            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9329            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9330            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9331        }
9332    }
9333
9334    public void resumeAppSwitches() {
9335        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9336                != PackageManager.PERMISSION_GRANTED) {
9337            throw new SecurityException("Requires permission "
9338                    + android.Manifest.permission.STOP_APP_SWITCHES);
9339        }
9340
9341        synchronized(this) {
9342            // Note that we don't execute any pending app switches... we will
9343            // let those wait until either the timeout, or the next start
9344            // activity request.
9345            mAppSwitchesAllowedTime = 0;
9346        }
9347    }
9348
9349    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9350            String name) {
9351        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9352            return true;
9353        }
9354
9355        final int perm = checkComponentPermission(
9356                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9357                callingUid, -1, true);
9358        if (perm == PackageManager.PERMISSION_GRANTED) {
9359            return true;
9360        }
9361
9362        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9363        return false;
9364    }
9365
9366    public void setDebugApp(String packageName, boolean waitForDebugger,
9367            boolean persistent) {
9368        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9369                "setDebugApp()");
9370
9371        long ident = Binder.clearCallingIdentity();
9372        try {
9373            // Note that this is not really thread safe if there are multiple
9374            // callers into it at the same time, but that's not a situation we
9375            // care about.
9376            if (persistent) {
9377                final ContentResolver resolver = mContext.getContentResolver();
9378                Settings.Global.putString(
9379                    resolver, Settings.Global.DEBUG_APP,
9380                    packageName);
9381                Settings.Global.putInt(
9382                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9383                    waitForDebugger ? 1 : 0);
9384            }
9385
9386            synchronized (this) {
9387                if (!persistent) {
9388                    mOrigDebugApp = mDebugApp;
9389                    mOrigWaitForDebugger = mWaitForDebugger;
9390                }
9391                mDebugApp = packageName;
9392                mWaitForDebugger = waitForDebugger;
9393                mDebugTransient = !persistent;
9394                if (packageName != null) {
9395                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9396                            false, UserHandle.USER_ALL, "set debug app");
9397                }
9398            }
9399        } finally {
9400            Binder.restoreCallingIdentity(ident);
9401        }
9402    }
9403
9404    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9405        synchronized (this) {
9406            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9407            if (!isDebuggable) {
9408                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9409                    throw new SecurityException("Process not debuggable: " + app.packageName);
9410                }
9411            }
9412
9413            mOpenGlTraceApp = processName;
9414        }
9415    }
9416
9417    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9418            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9419        synchronized (this) {
9420            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9421            if (!isDebuggable) {
9422                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9423                    throw new SecurityException("Process not debuggable: " + app.packageName);
9424                }
9425            }
9426            mProfileApp = processName;
9427            mProfileFile = profileFile;
9428            if (mProfileFd != null) {
9429                try {
9430                    mProfileFd.close();
9431                } catch (IOException e) {
9432                }
9433                mProfileFd = null;
9434            }
9435            mProfileFd = profileFd;
9436            mProfileType = 0;
9437            mAutoStopProfiler = autoStopProfiler;
9438        }
9439    }
9440
9441    @Override
9442    public void setAlwaysFinish(boolean enabled) {
9443        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9444                "setAlwaysFinish()");
9445
9446        Settings.Global.putInt(
9447                mContext.getContentResolver(),
9448                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9449
9450        synchronized (this) {
9451            mAlwaysFinishActivities = enabled;
9452        }
9453    }
9454
9455    @Override
9456    public void setActivityController(IActivityController controller) {
9457        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9458                "setActivityController()");
9459        synchronized (this) {
9460            mController = controller;
9461            Watchdog.getInstance().setActivityController(controller);
9462        }
9463    }
9464
9465    @Override
9466    public void setUserIsMonkey(boolean userIsMonkey) {
9467        synchronized (this) {
9468            synchronized (mPidsSelfLocked) {
9469                final int callingPid = Binder.getCallingPid();
9470                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9471                if (precessRecord == null) {
9472                    throw new SecurityException("Unknown process: " + callingPid);
9473                }
9474                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9475                    throw new SecurityException("Only an instrumentation process "
9476                            + "with a UiAutomation can call setUserIsMonkey");
9477                }
9478            }
9479            mUserIsMonkey = userIsMonkey;
9480        }
9481    }
9482
9483    @Override
9484    public boolean isUserAMonkey() {
9485        synchronized (this) {
9486            // If there is a controller also implies the user is a monkey.
9487            return (mUserIsMonkey || mController != null);
9488        }
9489    }
9490
9491    public void requestBugReport() {
9492        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9493        SystemProperties.set("ctl.start", "bugreport");
9494    }
9495
9496    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9497        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9498    }
9499
9500    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9501        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9502            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9503        }
9504        return KEY_DISPATCHING_TIMEOUT;
9505    }
9506
9507    @Override
9508    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9509        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9510                != PackageManager.PERMISSION_GRANTED) {
9511            throw new SecurityException("Requires permission "
9512                    + android.Manifest.permission.FILTER_EVENTS);
9513        }
9514        ProcessRecord proc;
9515        long timeout;
9516        synchronized (this) {
9517            synchronized (mPidsSelfLocked) {
9518                proc = mPidsSelfLocked.get(pid);
9519            }
9520            timeout = getInputDispatchingTimeoutLocked(proc);
9521        }
9522
9523        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9524            return -1;
9525        }
9526
9527        return timeout;
9528    }
9529
9530    /**
9531     * Handle input dispatching timeouts.
9532     * Returns whether input dispatching should be aborted or not.
9533     */
9534    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9535            final ActivityRecord activity, final ActivityRecord parent,
9536            final boolean aboveSystem, String reason) {
9537        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9538                != PackageManager.PERMISSION_GRANTED) {
9539            throw new SecurityException("Requires permission "
9540                    + android.Manifest.permission.FILTER_EVENTS);
9541        }
9542
9543        final String annotation;
9544        if (reason == null) {
9545            annotation = "Input dispatching timed out";
9546        } else {
9547            annotation = "Input dispatching timed out (" + reason + ")";
9548        }
9549
9550        if (proc != null) {
9551            synchronized (this) {
9552                if (proc.debugging) {
9553                    return false;
9554                }
9555
9556                if (mDidDexOpt) {
9557                    // Give more time since we were dexopting.
9558                    mDidDexOpt = false;
9559                    return false;
9560                }
9561
9562                if (proc.instrumentationClass != null) {
9563                    Bundle info = new Bundle();
9564                    info.putString("shortMsg", "keyDispatchingTimedOut");
9565                    info.putString("longMsg", annotation);
9566                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9567                    return true;
9568                }
9569            }
9570            mHandler.post(new Runnable() {
9571                @Override
9572                public void run() {
9573                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9574                }
9575            });
9576        }
9577
9578        return true;
9579    }
9580
9581    public Bundle getAssistContextExtras(int requestType) {
9582        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9583                "getAssistContextExtras()");
9584        PendingAssistExtras pae;
9585        Bundle extras = new Bundle();
9586        synchronized (this) {
9587            ActivityRecord activity = getFocusedStack().mResumedActivity;
9588            if (activity == null) {
9589                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9590                return null;
9591            }
9592            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9593            if (activity.app == null || activity.app.thread == null) {
9594                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9595                return extras;
9596            }
9597            if (activity.app.pid == Binder.getCallingPid()) {
9598                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9599                return extras;
9600            }
9601            pae = new PendingAssistExtras(activity);
9602            try {
9603                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9604                        requestType);
9605                mPendingAssistExtras.add(pae);
9606                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9607            } catch (RemoteException e) {
9608                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9609                return extras;
9610            }
9611        }
9612        synchronized (pae) {
9613            while (!pae.haveResult) {
9614                try {
9615                    pae.wait();
9616                } catch (InterruptedException e) {
9617                }
9618            }
9619            if (pae.result != null) {
9620                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9621            }
9622        }
9623        synchronized (this) {
9624            mPendingAssistExtras.remove(pae);
9625            mHandler.removeCallbacks(pae);
9626        }
9627        return extras;
9628    }
9629
9630    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9631        PendingAssistExtras pae = (PendingAssistExtras)token;
9632        synchronized (pae) {
9633            pae.result = extras;
9634            pae.haveResult = true;
9635            pae.notifyAll();
9636        }
9637    }
9638
9639    public void registerProcessObserver(IProcessObserver observer) {
9640        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9641                "registerProcessObserver()");
9642        synchronized (this) {
9643            mProcessObservers.register(observer);
9644        }
9645    }
9646
9647    @Override
9648    public void unregisterProcessObserver(IProcessObserver observer) {
9649        synchronized (this) {
9650            mProcessObservers.unregister(observer);
9651        }
9652    }
9653
9654    @Override
9655    public boolean convertFromTranslucent(IBinder token) {
9656        final long origId = Binder.clearCallingIdentity();
9657        try {
9658            synchronized (this) {
9659                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9660                if (r == null) {
9661                    return false;
9662                }
9663                if (r.changeWindowTranslucency(true)) {
9664                    mWindowManager.setAppFullscreen(token, true);
9665                    r.task.stack.releaseMediaResources();
9666                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9667                    return true;
9668                }
9669                return false;
9670            }
9671        } finally {
9672            Binder.restoreCallingIdentity(origId);
9673        }
9674    }
9675
9676    @Override
9677    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9678        final long origId = Binder.clearCallingIdentity();
9679        try {
9680            synchronized (this) {
9681                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9682                if (r == null) {
9683                    return false;
9684                }
9685                int index = r.task.mActivities.lastIndexOf(r);
9686                if (index > 0) {
9687                    ActivityRecord under = r.task.mActivities.get(index - 1);
9688                    under.returningOptions = options;
9689                }
9690                if (r.changeWindowTranslucency(false)) {
9691                    r.task.stack.convertToTranslucent(r);
9692                    mWindowManager.setAppFullscreen(token, false);
9693                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9694                    return true;
9695                } else {
9696                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9697                    return false;
9698                }
9699            }
9700        } finally {
9701            Binder.restoreCallingIdentity(origId);
9702        }
9703    }
9704
9705    @Override
9706    public boolean setMediaPlaying(IBinder token, boolean playing) {
9707        final long origId = Binder.clearCallingIdentity();
9708        try {
9709            synchronized (this) {
9710                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9711                if (r != null) {
9712                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9713                }
9714            }
9715            return false;
9716        } finally {
9717            Binder.restoreCallingIdentity(origId);
9718        }
9719    }
9720
9721    @Override
9722    public boolean isBackgroundMediaPlaying(IBinder token) {
9723        final long origId = Binder.clearCallingIdentity();
9724        try {
9725            synchronized (this) {
9726                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9727                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9728                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9729                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9730                return playing;
9731            }
9732        } finally {
9733            Binder.restoreCallingIdentity(origId);
9734        }
9735    }
9736
9737    @Override
9738    public ActivityOptions getActivityOptions(IBinder token) {
9739        final long origId = Binder.clearCallingIdentity();
9740        try {
9741            synchronized (this) {
9742                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9743                if (r != null) {
9744                    final ActivityOptions activityOptions = r.pendingOptions;
9745                    r.pendingOptions = null;
9746                    return activityOptions;
9747                }
9748                return null;
9749            }
9750        } finally {
9751            Binder.restoreCallingIdentity(origId);
9752        }
9753    }
9754
9755    @Override
9756    public void setImmersive(IBinder token, boolean immersive) {
9757        synchronized(this) {
9758            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9759            if (r == null) {
9760                throw new IllegalArgumentException();
9761            }
9762            r.immersive = immersive;
9763
9764            // update associated state if we're frontmost
9765            if (r == mFocusedActivity) {
9766                if (DEBUG_IMMERSIVE) {
9767                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9768                }
9769                applyUpdateLockStateLocked(r);
9770            }
9771        }
9772    }
9773
9774    @Override
9775    public boolean isImmersive(IBinder token) {
9776        synchronized (this) {
9777            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9778            if (r == null) {
9779                throw new IllegalArgumentException();
9780            }
9781            return r.immersive;
9782        }
9783    }
9784
9785    public boolean isTopActivityImmersive() {
9786        enforceNotIsolatedCaller("startActivity");
9787        synchronized (this) {
9788            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9789            return (r != null) ? r.immersive : false;
9790        }
9791    }
9792
9793    @Override
9794    public boolean isTopOfTask(IBinder token) {
9795        synchronized (this) {
9796            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9797            if (r == null) {
9798                throw new IllegalArgumentException();
9799            }
9800            return r.task.getTopActivity() == r;
9801        }
9802    }
9803
9804    public final void enterSafeMode() {
9805        synchronized(this) {
9806            // It only makes sense to do this before the system is ready
9807            // and started launching other packages.
9808            if (!mSystemReady) {
9809                try {
9810                    AppGlobals.getPackageManager().enterSafeMode();
9811                } catch (RemoteException e) {
9812                }
9813            }
9814
9815            mSafeMode = true;
9816        }
9817    }
9818
9819    public final void showSafeModeOverlay() {
9820        View v = LayoutInflater.from(mContext).inflate(
9821                com.android.internal.R.layout.safe_mode, null);
9822        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9823        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9824        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9825        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9826        lp.gravity = Gravity.BOTTOM | Gravity.START;
9827        lp.format = v.getBackground().getOpacity();
9828        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9829                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9830        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9831        ((WindowManager)mContext.getSystemService(
9832                Context.WINDOW_SERVICE)).addView(v, lp);
9833    }
9834
9835    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9836        if (!(sender instanceof PendingIntentRecord)) {
9837            return;
9838        }
9839        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9840        synchronized (stats) {
9841            if (mBatteryStatsService.isOnBattery()) {
9842                mBatteryStatsService.enforceCallingPermission();
9843                PendingIntentRecord rec = (PendingIntentRecord)sender;
9844                int MY_UID = Binder.getCallingUid();
9845                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9846                BatteryStatsImpl.Uid.Pkg pkg =
9847                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9848                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9849                pkg.incWakeupsLocked();
9850            }
9851        }
9852    }
9853
9854    public boolean killPids(int[] pids, String pReason, boolean secure) {
9855        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9856            throw new SecurityException("killPids only available to the system");
9857        }
9858        String reason = (pReason == null) ? "Unknown" : pReason;
9859        // XXX Note: don't acquire main activity lock here, because the window
9860        // manager calls in with its locks held.
9861
9862        boolean killed = false;
9863        synchronized (mPidsSelfLocked) {
9864            int[] types = new int[pids.length];
9865            int worstType = 0;
9866            for (int i=0; i<pids.length; i++) {
9867                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9868                if (proc != null) {
9869                    int type = proc.setAdj;
9870                    types[i] = type;
9871                    if (type > worstType) {
9872                        worstType = type;
9873                    }
9874                }
9875            }
9876
9877            // If the worst oom_adj is somewhere in the cached proc LRU range,
9878            // then constrain it so we will kill all cached procs.
9879            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9880                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9881                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9882            }
9883
9884            // If this is not a secure call, don't let it kill processes that
9885            // are important.
9886            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9887                worstType = ProcessList.SERVICE_ADJ;
9888            }
9889
9890            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9891            for (int i=0; i<pids.length; i++) {
9892                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9893                if (proc == null) {
9894                    continue;
9895                }
9896                int adj = proc.setAdj;
9897                if (adj >= worstType && !proc.killedByAm) {
9898                    killUnneededProcessLocked(proc, reason);
9899                    killed = true;
9900                }
9901            }
9902        }
9903        return killed;
9904    }
9905
9906    @Override
9907    public void killUid(int uid, String reason) {
9908        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9909            throw new SecurityException("killUid only available to the system");
9910        }
9911        synchronized (this) {
9912            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9913                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9914                    reason != null ? reason : "kill uid");
9915        }
9916    }
9917
9918    @Override
9919    public boolean killProcessesBelowForeground(String reason) {
9920        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9921            throw new SecurityException("killProcessesBelowForeground() only available to system");
9922        }
9923
9924        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9925    }
9926
9927    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9928        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9929            throw new SecurityException("killProcessesBelowAdj() only available to system");
9930        }
9931
9932        boolean killed = false;
9933        synchronized (mPidsSelfLocked) {
9934            final int size = mPidsSelfLocked.size();
9935            for (int i = 0; i < size; i++) {
9936                final int pid = mPidsSelfLocked.keyAt(i);
9937                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9938                if (proc == null) continue;
9939
9940                final int adj = proc.setAdj;
9941                if (adj > belowAdj && !proc.killedByAm) {
9942                    killUnneededProcessLocked(proc, reason);
9943                    killed = true;
9944                }
9945            }
9946        }
9947        return killed;
9948    }
9949
9950    @Override
9951    public void hang(final IBinder who, boolean allowRestart) {
9952        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9953                != PackageManager.PERMISSION_GRANTED) {
9954            throw new SecurityException("Requires permission "
9955                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9956        }
9957
9958        final IBinder.DeathRecipient death = new DeathRecipient() {
9959            @Override
9960            public void binderDied() {
9961                synchronized (this) {
9962                    notifyAll();
9963                }
9964            }
9965        };
9966
9967        try {
9968            who.linkToDeath(death, 0);
9969        } catch (RemoteException e) {
9970            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9971            return;
9972        }
9973
9974        synchronized (this) {
9975            Watchdog.getInstance().setAllowRestart(allowRestart);
9976            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9977            synchronized (death) {
9978                while (who.isBinderAlive()) {
9979                    try {
9980                        death.wait();
9981                    } catch (InterruptedException e) {
9982                    }
9983                }
9984            }
9985            Watchdog.getInstance().setAllowRestart(true);
9986        }
9987    }
9988
9989    @Override
9990    public void restart() {
9991        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9992                != PackageManager.PERMISSION_GRANTED) {
9993            throw new SecurityException("Requires permission "
9994                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9995        }
9996
9997        Log.i(TAG, "Sending shutdown broadcast...");
9998
9999        BroadcastReceiver br = new BroadcastReceiver() {
10000            @Override public void onReceive(Context context, Intent intent) {
10001                // Now the broadcast is done, finish up the low-level shutdown.
10002                Log.i(TAG, "Shutting down activity manager...");
10003                shutdown(10000);
10004                Log.i(TAG, "Shutdown complete, restarting!");
10005                Process.killProcess(Process.myPid());
10006                System.exit(10);
10007            }
10008        };
10009
10010        // First send the high-level shut down broadcast.
10011        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10012        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10013        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10014        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10015        mContext.sendOrderedBroadcastAsUser(intent,
10016                UserHandle.ALL, null, br, mHandler, 0, null, null);
10017        */
10018        br.onReceive(mContext, intent);
10019    }
10020
10021    private long getLowRamTimeSinceIdle(long now) {
10022        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10023    }
10024
10025    @Override
10026    public void performIdleMaintenance() {
10027        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10028                != PackageManager.PERMISSION_GRANTED) {
10029            throw new SecurityException("Requires permission "
10030                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10031        }
10032
10033        synchronized (this) {
10034            final long now = SystemClock.uptimeMillis();
10035            final long timeSinceLastIdle = now - mLastIdleTime;
10036            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10037            mLastIdleTime = now;
10038            mLowRamTimeSinceLastIdle = 0;
10039            if (mLowRamStartTime != 0) {
10040                mLowRamStartTime = now;
10041            }
10042
10043            StringBuilder sb = new StringBuilder(128);
10044            sb.append("Idle maintenance over ");
10045            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10046            sb.append(" low RAM for ");
10047            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10048            Slog.i(TAG, sb.toString());
10049
10050            // If at least 1/3 of our time since the last idle period has been spent
10051            // with RAM low, then we want to kill processes.
10052            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10053
10054            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10055                ProcessRecord proc = mLruProcesses.get(i);
10056                if (proc.notCachedSinceIdle) {
10057                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10058                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10059                        if (doKilling && proc.initialIdlePss != 0
10060                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10061                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
10062                                    + " from " + proc.initialIdlePss + ")");
10063                        }
10064                    }
10065                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10066                    proc.notCachedSinceIdle = true;
10067                    proc.initialIdlePss = 0;
10068                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10069                            isSleeping(), now);
10070                }
10071            }
10072
10073            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10074            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10075        }
10076    }
10077
10078    private void retrieveSettings() {
10079        final ContentResolver resolver = mContext.getContentResolver();
10080        String debugApp = Settings.Global.getString(
10081            resolver, Settings.Global.DEBUG_APP);
10082        boolean waitForDebugger = Settings.Global.getInt(
10083            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10084        boolean alwaysFinishActivities = Settings.Global.getInt(
10085            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10086        boolean forceRtl = Settings.Global.getInt(
10087                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10088        // Transfer any global setting for forcing RTL layout, into a System Property
10089        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10090
10091        Configuration configuration = new Configuration();
10092        Settings.System.getConfiguration(resolver, configuration);
10093        if (forceRtl) {
10094            // This will take care of setting the correct layout direction flags
10095            configuration.setLayoutDirection(configuration.locale);
10096        }
10097
10098        synchronized (this) {
10099            mDebugApp = mOrigDebugApp = debugApp;
10100            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10101            mAlwaysFinishActivities = alwaysFinishActivities;
10102            // This happens before any activities are started, so we can
10103            // change mConfiguration in-place.
10104            updateConfigurationLocked(configuration, null, false, true);
10105            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10106        }
10107    }
10108
10109    public boolean testIsSystemReady() {
10110        // no need to synchronize(this) just to read & return the value
10111        return mSystemReady;
10112    }
10113
10114    private static File getCalledPreBootReceiversFile() {
10115        File dataDir = Environment.getDataDirectory();
10116        File systemDir = new File(dataDir, "system");
10117        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10118        return fname;
10119    }
10120
10121    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10122        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10123        File file = getCalledPreBootReceiversFile();
10124        FileInputStream fis = null;
10125        try {
10126            fis = new FileInputStream(file);
10127            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10128            int fvers = dis.readInt();
10129            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10130                String vers = dis.readUTF();
10131                String codename = dis.readUTF();
10132                String build = dis.readUTF();
10133                if (android.os.Build.VERSION.RELEASE.equals(vers)
10134                        && android.os.Build.VERSION.CODENAME.equals(codename)
10135                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10136                    int num = dis.readInt();
10137                    while (num > 0) {
10138                        num--;
10139                        String pkg = dis.readUTF();
10140                        String cls = dis.readUTF();
10141                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10142                    }
10143                }
10144            }
10145        } catch (FileNotFoundException e) {
10146        } catch (IOException e) {
10147            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10148        } finally {
10149            if (fis != null) {
10150                try {
10151                    fis.close();
10152                } catch (IOException e) {
10153                }
10154            }
10155        }
10156        return lastDoneReceivers;
10157    }
10158
10159    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10160        File file = getCalledPreBootReceiversFile();
10161        FileOutputStream fos = null;
10162        DataOutputStream dos = null;
10163        try {
10164            fos = new FileOutputStream(file);
10165            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10166            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10167            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10168            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10169            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10170            dos.writeInt(list.size());
10171            for (int i=0; i<list.size(); i++) {
10172                dos.writeUTF(list.get(i).getPackageName());
10173                dos.writeUTF(list.get(i).getClassName());
10174            }
10175        } catch (IOException e) {
10176            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10177            file.delete();
10178        } finally {
10179            FileUtils.sync(fos);
10180            if (dos != null) {
10181                try {
10182                    dos.close();
10183                } catch (IOException e) {
10184                    // TODO Auto-generated catch block
10185                    e.printStackTrace();
10186                }
10187            }
10188        }
10189    }
10190
10191    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10192            ArrayList<ComponentName> doneReceivers, int userId) {
10193        boolean waitingUpdate = false;
10194        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10195        List<ResolveInfo> ris = null;
10196        try {
10197            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10198                    intent, null, 0, userId);
10199        } catch (RemoteException e) {
10200        }
10201        if (ris != null) {
10202            for (int i=ris.size()-1; i>=0; i--) {
10203                if ((ris.get(i).activityInfo.applicationInfo.flags
10204                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10205                    ris.remove(i);
10206                }
10207            }
10208            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10209
10210            // For User 0, load the version number. When delivering to a new user, deliver
10211            // to all receivers.
10212            if (userId == UserHandle.USER_OWNER) {
10213                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10214                for (int i=0; i<ris.size(); i++) {
10215                    ActivityInfo ai = ris.get(i).activityInfo;
10216                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10217                    if (lastDoneReceivers.contains(comp)) {
10218                        // We already did the pre boot receiver for this app with the current
10219                        // platform version, so don't do it again...
10220                        ris.remove(i);
10221                        i--;
10222                        // ...however, do keep it as one that has been done, so we don't
10223                        // forget about it when rewriting the file of last done receivers.
10224                        doneReceivers.add(comp);
10225                    }
10226                }
10227            }
10228
10229            // If primary user, send broadcast to all available users, else just to userId
10230            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10231                    : new int[] { userId };
10232            for (int i = 0; i < ris.size(); i++) {
10233                ActivityInfo ai = ris.get(i).activityInfo;
10234                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10235                doneReceivers.add(comp);
10236                intent.setComponent(comp);
10237                for (int j=0; j<users.length; j++) {
10238                    IIntentReceiver finisher = null;
10239                    // On last receiver and user, set up a completion callback
10240                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10241                        finisher = new IIntentReceiver.Stub() {
10242                            public void performReceive(Intent intent, int resultCode,
10243                                    String data, Bundle extras, boolean ordered,
10244                                    boolean sticky, int sendingUser) {
10245                                // The raw IIntentReceiver interface is called
10246                                // with the AM lock held, so redispatch to
10247                                // execute our code without the lock.
10248                                mHandler.post(onFinishCallback);
10249                            }
10250                        };
10251                    }
10252                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10253                            + " for user " + users[j]);
10254                    broadcastIntentLocked(null, null, intent, null, finisher,
10255                            0, null, null, null, AppOpsManager.OP_NONE,
10256                            true, false, MY_PID, Process.SYSTEM_UID,
10257                            users[j]);
10258                    if (finisher != null) {
10259                        waitingUpdate = true;
10260                    }
10261                }
10262            }
10263        }
10264
10265        return waitingUpdate;
10266    }
10267
10268    public void systemReady(final Runnable goingCallback) {
10269        synchronized(this) {
10270            if (mSystemReady) {
10271                // If we're done calling all the receivers, run the next "boot phase" passed in
10272                // by the SystemServer
10273                if (goingCallback != null) {
10274                    goingCallback.run();
10275                }
10276                return;
10277            }
10278
10279            // Make sure we have the current profile info, since it is needed for
10280            // security checks.
10281            updateCurrentProfileIdsLocked();
10282
10283            if (mRecentTasks == null) {
10284                mRecentTasks = mTaskPersister.restoreTasksLocked();
10285                if (!mRecentTasks.isEmpty()) {
10286                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10287                }
10288                mTaskPersister.startPersisting();
10289            }
10290
10291            // Check to see if there are any update receivers to run.
10292            if (!mDidUpdate) {
10293                if (mWaitingUpdate) {
10294                    return;
10295                }
10296                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10297                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10298                    public void run() {
10299                        synchronized (ActivityManagerService.this) {
10300                            mDidUpdate = true;
10301                        }
10302                        writeLastDonePreBootReceivers(doneReceivers);
10303                        showBootMessage(mContext.getText(
10304                                R.string.android_upgrading_complete),
10305                                false);
10306                        systemReady(goingCallback);
10307                    }
10308                }, doneReceivers, UserHandle.USER_OWNER);
10309
10310                if (mWaitingUpdate) {
10311                    return;
10312                }
10313                mDidUpdate = true;
10314            }
10315
10316            mAppOpsService.systemReady();
10317            mSystemReady = true;
10318        }
10319
10320        ArrayList<ProcessRecord> procsToKill = null;
10321        synchronized(mPidsSelfLocked) {
10322            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10323                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10324                if (!isAllowedWhileBooting(proc.info)){
10325                    if (procsToKill == null) {
10326                        procsToKill = new ArrayList<ProcessRecord>();
10327                    }
10328                    procsToKill.add(proc);
10329                }
10330            }
10331        }
10332
10333        synchronized(this) {
10334            if (procsToKill != null) {
10335                for (int i=procsToKill.size()-1; i>=0; i--) {
10336                    ProcessRecord proc = procsToKill.get(i);
10337                    Slog.i(TAG, "Removing system update proc: " + proc);
10338                    removeProcessLocked(proc, true, false, "system update done");
10339                }
10340            }
10341
10342            // Now that we have cleaned up any update processes, we
10343            // are ready to start launching real processes and know that
10344            // we won't trample on them any more.
10345            mProcessesReady = true;
10346        }
10347
10348        Slog.i(TAG, "System now ready");
10349        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10350            SystemClock.uptimeMillis());
10351
10352        synchronized(this) {
10353            // Make sure we have no pre-ready processes sitting around.
10354
10355            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10356                ResolveInfo ri = mContext.getPackageManager()
10357                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10358                                STOCK_PM_FLAGS);
10359                CharSequence errorMsg = null;
10360                if (ri != null) {
10361                    ActivityInfo ai = ri.activityInfo;
10362                    ApplicationInfo app = ai.applicationInfo;
10363                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10364                        mTopAction = Intent.ACTION_FACTORY_TEST;
10365                        mTopData = null;
10366                        mTopComponent = new ComponentName(app.packageName,
10367                                ai.name);
10368                    } else {
10369                        errorMsg = mContext.getResources().getText(
10370                                com.android.internal.R.string.factorytest_not_system);
10371                    }
10372                } else {
10373                    errorMsg = mContext.getResources().getText(
10374                            com.android.internal.R.string.factorytest_no_action);
10375                }
10376                if (errorMsg != null) {
10377                    mTopAction = null;
10378                    mTopData = null;
10379                    mTopComponent = null;
10380                    Message msg = Message.obtain();
10381                    msg.what = SHOW_FACTORY_ERROR_MSG;
10382                    msg.getData().putCharSequence("msg", errorMsg);
10383                    mHandler.sendMessage(msg);
10384                }
10385            }
10386        }
10387
10388        retrieveSettings();
10389
10390        synchronized (this) {
10391            readGrantedUriPermissionsLocked();
10392        }
10393
10394        if (goingCallback != null) goingCallback.run();
10395
10396        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10397                Integer.toString(mCurrentUserId), mCurrentUserId);
10398        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10399                Integer.toString(mCurrentUserId), mCurrentUserId);
10400        mSystemServiceManager.startUser(mCurrentUserId);
10401
10402        synchronized (this) {
10403            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10404                try {
10405                    List apps = AppGlobals.getPackageManager().
10406                        getPersistentApplications(STOCK_PM_FLAGS);
10407                    if (apps != null) {
10408                        int N = apps.size();
10409                        int i;
10410                        for (i=0; i<N; i++) {
10411                            ApplicationInfo info
10412                                = (ApplicationInfo)apps.get(i);
10413                            if (info != null &&
10414                                    !info.packageName.equals("android")) {
10415                                addAppLocked(info, false, null /* ABI override */);
10416                            }
10417                        }
10418                    }
10419                } catch (RemoteException ex) {
10420                    // pm is in same process, this will never happen.
10421                }
10422            }
10423
10424            // Start up initial activity.
10425            mBooting = true;
10426
10427            try {
10428                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10429                    Message msg = Message.obtain();
10430                    msg.what = SHOW_UID_ERROR_MSG;
10431                    mHandler.sendMessage(msg);
10432                }
10433            } catch (RemoteException e) {
10434            }
10435
10436            long ident = Binder.clearCallingIdentity();
10437            try {
10438                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10439                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10440                        | Intent.FLAG_RECEIVER_FOREGROUND);
10441                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10442                broadcastIntentLocked(null, null, intent,
10443                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10444                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10445                intent = new Intent(Intent.ACTION_USER_STARTING);
10446                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10447                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10448                broadcastIntentLocked(null, null, intent,
10449                        null, new IIntentReceiver.Stub() {
10450                            @Override
10451                            public void performReceive(Intent intent, int resultCode, String data,
10452                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10453                                    throws RemoteException {
10454                            }
10455                        }, 0, null, null,
10456                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10457                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10458            } catch (Throwable t) {
10459                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10460            } finally {
10461                Binder.restoreCallingIdentity(ident);
10462            }
10463            mStackSupervisor.resumeTopActivitiesLocked();
10464            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10465        }
10466    }
10467
10468    private boolean makeAppCrashingLocked(ProcessRecord app,
10469            String shortMsg, String longMsg, String stackTrace) {
10470        app.crashing = true;
10471        app.crashingReport = generateProcessError(app,
10472                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10473        startAppProblemLocked(app);
10474        app.stopFreezingAllLocked();
10475        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10476    }
10477
10478    private void makeAppNotRespondingLocked(ProcessRecord app,
10479            String activity, String shortMsg, String longMsg) {
10480        app.notResponding = true;
10481        app.notRespondingReport = generateProcessError(app,
10482                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10483                activity, shortMsg, longMsg, null);
10484        startAppProblemLocked(app);
10485        app.stopFreezingAllLocked();
10486    }
10487
10488    /**
10489     * Generate a process error record, suitable for attachment to a ProcessRecord.
10490     *
10491     * @param app The ProcessRecord in which the error occurred.
10492     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10493     *                      ActivityManager.AppErrorStateInfo
10494     * @param activity The activity associated with the crash, if known.
10495     * @param shortMsg Short message describing the crash.
10496     * @param longMsg Long message describing the crash.
10497     * @param stackTrace Full crash stack trace, may be null.
10498     *
10499     * @return Returns a fully-formed AppErrorStateInfo record.
10500     */
10501    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10502            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10503        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10504
10505        report.condition = condition;
10506        report.processName = app.processName;
10507        report.pid = app.pid;
10508        report.uid = app.info.uid;
10509        report.tag = activity;
10510        report.shortMsg = shortMsg;
10511        report.longMsg = longMsg;
10512        report.stackTrace = stackTrace;
10513
10514        return report;
10515    }
10516
10517    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10518        synchronized (this) {
10519            app.crashing = false;
10520            app.crashingReport = null;
10521            app.notResponding = false;
10522            app.notRespondingReport = null;
10523            if (app.anrDialog == fromDialog) {
10524                app.anrDialog = null;
10525            }
10526            if (app.waitDialog == fromDialog) {
10527                app.waitDialog = null;
10528            }
10529            if (app.pid > 0 && app.pid != MY_PID) {
10530                handleAppCrashLocked(app, null, null, null);
10531                killUnneededProcessLocked(app, "user request after error");
10532            }
10533        }
10534    }
10535
10536    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10537            String stackTrace) {
10538        long now = SystemClock.uptimeMillis();
10539
10540        Long crashTime;
10541        if (!app.isolated) {
10542            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10543        } else {
10544            crashTime = null;
10545        }
10546        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10547            // This process loses!
10548            Slog.w(TAG, "Process " + app.info.processName
10549                    + " has crashed too many times: killing!");
10550            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10551                    app.userId, app.info.processName, app.uid);
10552            mStackSupervisor.handleAppCrashLocked(app);
10553            if (!app.persistent) {
10554                // We don't want to start this process again until the user
10555                // explicitly does so...  but for persistent process, we really
10556                // need to keep it running.  If a persistent process is actually
10557                // repeatedly crashing, then badness for everyone.
10558                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10559                        app.info.processName);
10560                if (!app.isolated) {
10561                    // XXX We don't have a way to mark isolated processes
10562                    // as bad, since they don't have a peristent identity.
10563                    mBadProcesses.put(app.info.processName, app.uid,
10564                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10565                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10566                }
10567                app.bad = true;
10568                app.removed = true;
10569                // Don't let services in this process be restarted and potentially
10570                // annoy the user repeatedly.  Unless it is persistent, since those
10571                // processes run critical code.
10572                removeProcessLocked(app, false, false, "crash");
10573                mStackSupervisor.resumeTopActivitiesLocked();
10574                return false;
10575            }
10576            mStackSupervisor.resumeTopActivitiesLocked();
10577        } else {
10578            mStackSupervisor.finishTopRunningActivityLocked(app);
10579        }
10580
10581        // Bump up the crash count of any services currently running in the proc.
10582        for (int i=app.services.size()-1; i>=0; i--) {
10583            // Any services running in the application need to be placed
10584            // back in the pending list.
10585            ServiceRecord sr = app.services.valueAt(i);
10586            sr.crashCount++;
10587        }
10588
10589        // If the crashing process is what we consider to be the "home process" and it has been
10590        // replaced by a third-party app, clear the package preferred activities from packages
10591        // with a home activity running in the process to prevent a repeatedly crashing app
10592        // from blocking the user to manually clear the list.
10593        final ArrayList<ActivityRecord> activities = app.activities;
10594        if (app == mHomeProcess && activities.size() > 0
10595                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10596            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10597                final ActivityRecord r = activities.get(activityNdx);
10598                if (r.isHomeActivity()) {
10599                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10600                    try {
10601                        ActivityThread.getPackageManager()
10602                                .clearPackagePreferredActivities(r.packageName);
10603                    } catch (RemoteException c) {
10604                        // pm is in same process, this will never happen.
10605                    }
10606                }
10607            }
10608        }
10609
10610        if (!app.isolated) {
10611            // XXX Can't keep track of crash times for isolated processes,
10612            // because they don't have a perisistent identity.
10613            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10614        }
10615
10616        if (app.crashHandler != null) mHandler.post(app.crashHandler);
10617        return true;
10618    }
10619
10620    void startAppProblemLocked(ProcessRecord app) {
10621        // If this app is not running under the current user, then we
10622        // can't give it a report button because that would require
10623        // launching the report UI under a different user.
10624        app.errorReportReceiver = null;
10625
10626        for (int userId : mCurrentProfileIds) {
10627            if (app.userId == userId) {
10628                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10629                        mContext, app.info.packageName, app.info.flags);
10630            }
10631        }
10632        skipCurrentReceiverLocked(app);
10633    }
10634
10635    void skipCurrentReceiverLocked(ProcessRecord app) {
10636        for (BroadcastQueue queue : mBroadcastQueues) {
10637            queue.skipCurrentReceiverLocked(app);
10638        }
10639    }
10640
10641    /**
10642     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10643     * The application process will exit immediately after this call returns.
10644     * @param app object of the crashing app, null for the system server
10645     * @param crashInfo describing the exception
10646     */
10647    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10648        ProcessRecord r = findAppProcess(app, "Crash");
10649        final String processName = app == null ? "system_server"
10650                : (r == null ? "unknown" : r.processName);
10651
10652        handleApplicationCrashInner("crash", r, processName, crashInfo);
10653    }
10654
10655    /* Native crash reporting uses this inner version because it needs to be somewhat
10656     * decoupled from the AM-managed cleanup lifecycle
10657     */
10658    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10659            ApplicationErrorReport.CrashInfo crashInfo) {
10660        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10661                UserHandle.getUserId(Binder.getCallingUid()), processName,
10662                r == null ? -1 : r.info.flags,
10663                crashInfo.exceptionClassName,
10664                crashInfo.exceptionMessage,
10665                crashInfo.throwFileName,
10666                crashInfo.throwLineNumber);
10667
10668        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10669
10670        crashApplication(r, crashInfo);
10671    }
10672
10673    public void handleApplicationStrictModeViolation(
10674            IBinder app,
10675            int violationMask,
10676            StrictMode.ViolationInfo info) {
10677        ProcessRecord r = findAppProcess(app, "StrictMode");
10678        if (r == null) {
10679            return;
10680        }
10681
10682        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10683            Integer stackFingerprint = info.hashCode();
10684            boolean logIt = true;
10685            synchronized (mAlreadyLoggedViolatedStacks) {
10686                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10687                    logIt = false;
10688                    // TODO: sub-sample into EventLog for these, with
10689                    // the info.durationMillis?  Then we'd get
10690                    // the relative pain numbers, without logging all
10691                    // the stack traces repeatedly.  We'd want to do
10692                    // likewise in the client code, which also does
10693                    // dup suppression, before the Binder call.
10694                } else {
10695                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10696                        mAlreadyLoggedViolatedStacks.clear();
10697                    }
10698                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10699                }
10700            }
10701            if (logIt) {
10702                logStrictModeViolationToDropBox(r, info);
10703            }
10704        }
10705
10706        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10707            AppErrorResult result = new AppErrorResult();
10708            synchronized (this) {
10709                final long origId = Binder.clearCallingIdentity();
10710
10711                Message msg = Message.obtain();
10712                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10713                HashMap<String, Object> data = new HashMap<String, Object>();
10714                data.put("result", result);
10715                data.put("app", r);
10716                data.put("violationMask", violationMask);
10717                data.put("info", info);
10718                msg.obj = data;
10719                mHandler.sendMessage(msg);
10720
10721                Binder.restoreCallingIdentity(origId);
10722            }
10723            int res = result.get();
10724            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10725        }
10726    }
10727
10728    // Depending on the policy in effect, there could be a bunch of
10729    // these in quick succession so we try to batch these together to
10730    // minimize disk writes, number of dropbox entries, and maximize
10731    // compression, by having more fewer, larger records.
10732    private void logStrictModeViolationToDropBox(
10733            ProcessRecord process,
10734            StrictMode.ViolationInfo info) {
10735        if (info == null) {
10736            return;
10737        }
10738        final boolean isSystemApp = process == null ||
10739                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10740                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10741        final String processName = process == null ? "unknown" : process.processName;
10742        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10743        final DropBoxManager dbox = (DropBoxManager)
10744                mContext.getSystemService(Context.DROPBOX_SERVICE);
10745
10746        // Exit early if the dropbox isn't configured to accept this report type.
10747        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10748
10749        boolean bufferWasEmpty;
10750        boolean needsFlush;
10751        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10752        synchronized (sb) {
10753            bufferWasEmpty = sb.length() == 0;
10754            appendDropBoxProcessHeaders(process, processName, sb);
10755            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10756            sb.append("System-App: ").append(isSystemApp).append("\n");
10757            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10758            if (info.violationNumThisLoop != 0) {
10759                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10760            }
10761            if (info.numAnimationsRunning != 0) {
10762                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10763            }
10764            if (info.broadcastIntentAction != null) {
10765                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10766            }
10767            if (info.durationMillis != -1) {
10768                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10769            }
10770            if (info.numInstances != -1) {
10771                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10772            }
10773            if (info.tags != null) {
10774                for (String tag : info.tags) {
10775                    sb.append("Span-Tag: ").append(tag).append("\n");
10776                }
10777            }
10778            sb.append("\n");
10779            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10780                sb.append(info.crashInfo.stackTrace);
10781            }
10782            sb.append("\n");
10783
10784            // Only buffer up to ~64k.  Various logging bits truncate
10785            // things at 128k.
10786            needsFlush = (sb.length() > 64 * 1024);
10787        }
10788
10789        // Flush immediately if the buffer's grown too large, or this
10790        // is a non-system app.  Non-system apps are isolated with a
10791        // different tag & policy and not batched.
10792        //
10793        // Batching is useful during internal testing with
10794        // StrictMode settings turned up high.  Without batching,
10795        // thousands of separate files could be created on boot.
10796        if (!isSystemApp || needsFlush) {
10797            new Thread("Error dump: " + dropboxTag) {
10798                @Override
10799                public void run() {
10800                    String report;
10801                    synchronized (sb) {
10802                        report = sb.toString();
10803                        sb.delete(0, sb.length());
10804                        sb.trimToSize();
10805                    }
10806                    if (report.length() != 0) {
10807                        dbox.addText(dropboxTag, report);
10808                    }
10809                }
10810            }.start();
10811            return;
10812        }
10813
10814        // System app batching:
10815        if (!bufferWasEmpty) {
10816            // An existing dropbox-writing thread is outstanding, so
10817            // we don't need to start it up.  The existing thread will
10818            // catch the buffer appends we just did.
10819            return;
10820        }
10821
10822        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10823        // (After this point, we shouldn't access AMS internal data structures.)
10824        new Thread("Error dump: " + dropboxTag) {
10825            @Override
10826            public void run() {
10827                // 5 second sleep to let stacks arrive and be batched together
10828                try {
10829                    Thread.sleep(5000);  // 5 seconds
10830                } catch (InterruptedException e) {}
10831
10832                String errorReport;
10833                synchronized (mStrictModeBuffer) {
10834                    errorReport = mStrictModeBuffer.toString();
10835                    if (errorReport.length() == 0) {
10836                        return;
10837                    }
10838                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10839                    mStrictModeBuffer.trimToSize();
10840                }
10841                dbox.addText(dropboxTag, errorReport);
10842            }
10843        }.start();
10844    }
10845
10846    /**
10847     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10848     * @param app object of the crashing app, null for the system server
10849     * @param tag reported by the caller
10850     * @param crashInfo describing the context of the error
10851     * @return true if the process should exit immediately (WTF is fatal)
10852     */
10853    public boolean handleApplicationWtf(IBinder app, String tag,
10854            ApplicationErrorReport.CrashInfo crashInfo) {
10855        ProcessRecord r = findAppProcess(app, "WTF");
10856        final String processName = app == null ? "system_server"
10857                : (r == null ? "unknown" : r.processName);
10858
10859        EventLog.writeEvent(EventLogTags.AM_WTF,
10860                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10861                processName,
10862                r == null ? -1 : r.info.flags,
10863                tag, crashInfo.exceptionMessage);
10864
10865        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10866
10867        if (r != null && r.pid != Process.myPid() &&
10868                Settings.Global.getInt(mContext.getContentResolver(),
10869                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10870            crashApplication(r, crashInfo);
10871            return true;
10872        } else {
10873            return false;
10874        }
10875    }
10876
10877    /**
10878     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10879     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10880     */
10881    private ProcessRecord findAppProcess(IBinder app, String reason) {
10882        if (app == null) {
10883            return null;
10884        }
10885
10886        synchronized (this) {
10887            final int NP = mProcessNames.getMap().size();
10888            for (int ip=0; ip<NP; ip++) {
10889                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10890                final int NA = apps.size();
10891                for (int ia=0; ia<NA; ia++) {
10892                    ProcessRecord p = apps.valueAt(ia);
10893                    if (p.thread != null && p.thread.asBinder() == app) {
10894                        return p;
10895                    }
10896                }
10897            }
10898
10899            Slog.w(TAG, "Can't find mystery application for " + reason
10900                    + " from pid=" + Binder.getCallingPid()
10901                    + " uid=" + Binder.getCallingUid() + ": " + app);
10902            return null;
10903        }
10904    }
10905
10906    /**
10907     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10908     * to append various headers to the dropbox log text.
10909     */
10910    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10911            StringBuilder sb) {
10912        // Watchdog thread ends up invoking this function (with
10913        // a null ProcessRecord) to add the stack file to dropbox.
10914        // Do not acquire a lock on this (am) in such cases, as it
10915        // could cause a potential deadlock, if and when watchdog
10916        // is invoked due to unavailability of lock on am and it
10917        // would prevent watchdog from killing system_server.
10918        if (process == null) {
10919            sb.append("Process: ").append(processName).append("\n");
10920            return;
10921        }
10922        // Note: ProcessRecord 'process' is guarded by the service
10923        // instance.  (notably process.pkgList, which could otherwise change
10924        // concurrently during execution of this method)
10925        synchronized (this) {
10926            sb.append("Process: ").append(processName).append("\n");
10927            int flags = process.info.flags;
10928            IPackageManager pm = AppGlobals.getPackageManager();
10929            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10930            for (int ip=0; ip<process.pkgList.size(); ip++) {
10931                String pkg = process.pkgList.keyAt(ip);
10932                sb.append("Package: ").append(pkg);
10933                try {
10934                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10935                    if (pi != null) {
10936                        sb.append(" v").append(pi.versionCode);
10937                        if (pi.versionName != null) {
10938                            sb.append(" (").append(pi.versionName).append(")");
10939                        }
10940                    }
10941                } catch (RemoteException e) {
10942                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10943                }
10944                sb.append("\n");
10945            }
10946        }
10947    }
10948
10949    private static String processClass(ProcessRecord process) {
10950        if (process == null || process.pid == MY_PID) {
10951            return "system_server";
10952        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10953            return "system_app";
10954        } else {
10955            return "data_app";
10956        }
10957    }
10958
10959    /**
10960     * Write a description of an error (crash, WTF, ANR) to the drop box.
10961     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10962     * @param process which caused the error, null means the system server
10963     * @param activity which triggered the error, null if unknown
10964     * @param parent activity related to the error, null if unknown
10965     * @param subject line related to the error, null if absent
10966     * @param report in long form describing the error, null if absent
10967     * @param logFile to include in the report, null if none
10968     * @param crashInfo giving an application stack trace, null if absent
10969     */
10970    public void addErrorToDropBox(String eventType,
10971            ProcessRecord process, String processName, ActivityRecord activity,
10972            ActivityRecord parent, String subject,
10973            final String report, final File logFile,
10974            final ApplicationErrorReport.CrashInfo crashInfo) {
10975        // NOTE -- this must never acquire the ActivityManagerService lock,
10976        // otherwise the watchdog may be prevented from resetting the system.
10977
10978        final String dropboxTag = processClass(process) + "_" + eventType;
10979        final DropBoxManager dbox = (DropBoxManager)
10980                mContext.getSystemService(Context.DROPBOX_SERVICE);
10981
10982        // Exit early if the dropbox isn't configured to accept this report type.
10983        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10984
10985        final StringBuilder sb = new StringBuilder(1024);
10986        appendDropBoxProcessHeaders(process, processName, sb);
10987        if (activity != null) {
10988            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10989        }
10990        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10991            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10992        }
10993        if (parent != null && parent != activity) {
10994            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10995        }
10996        if (subject != null) {
10997            sb.append("Subject: ").append(subject).append("\n");
10998        }
10999        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11000        if (Debug.isDebuggerConnected()) {
11001            sb.append("Debugger: Connected\n");
11002        }
11003        sb.append("\n");
11004
11005        // Do the rest in a worker thread to avoid blocking the caller on I/O
11006        // (After this point, we shouldn't access AMS internal data structures.)
11007        Thread worker = new Thread("Error dump: " + dropboxTag) {
11008            @Override
11009            public void run() {
11010                if (report != null) {
11011                    sb.append(report);
11012                }
11013                if (logFile != null) {
11014                    try {
11015                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11016                                    "\n\n[[TRUNCATED]]"));
11017                    } catch (IOException e) {
11018                        Slog.e(TAG, "Error reading " + logFile, e);
11019                    }
11020                }
11021                if (crashInfo != null && crashInfo.stackTrace != null) {
11022                    sb.append(crashInfo.stackTrace);
11023                }
11024
11025                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11026                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11027                if (lines > 0) {
11028                    sb.append("\n");
11029
11030                    // Merge several logcat streams, and take the last N lines
11031                    InputStreamReader input = null;
11032                    try {
11033                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11034                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11035                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11036
11037                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11038                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11039                        input = new InputStreamReader(logcat.getInputStream());
11040
11041                        int num;
11042                        char[] buf = new char[8192];
11043                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11044                    } catch (IOException e) {
11045                        Slog.e(TAG, "Error running logcat", e);
11046                    } finally {
11047                        if (input != null) try { input.close(); } catch (IOException e) {}
11048                    }
11049                }
11050
11051                dbox.addText(dropboxTag, sb.toString());
11052            }
11053        };
11054
11055        if (process == null) {
11056            // If process is null, we are being called from some internal code
11057            // and may be about to die -- run this synchronously.
11058            worker.run();
11059        } else {
11060            worker.start();
11061        }
11062    }
11063
11064    /**
11065     * Bring up the "unexpected error" dialog box for a crashing app.
11066     * Deal with edge cases (intercepts from instrumented applications,
11067     * ActivityController, error intent receivers, that sort of thing).
11068     * @param r the application crashing
11069     * @param crashInfo describing the failure
11070     */
11071    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11072        long timeMillis = System.currentTimeMillis();
11073        String shortMsg = crashInfo.exceptionClassName;
11074        String longMsg = crashInfo.exceptionMessage;
11075        String stackTrace = crashInfo.stackTrace;
11076        if (shortMsg != null && longMsg != null) {
11077            longMsg = shortMsg + ": " + longMsg;
11078        } else if (shortMsg != null) {
11079            longMsg = shortMsg;
11080        }
11081
11082        AppErrorResult result = new AppErrorResult();
11083        synchronized (this) {
11084            if (mController != null) {
11085                try {
11086                    String name = r != null ? r.processName : null;
11087                    int pid = r != null ? r.pid : Binder.getCallingPid();
11088                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11089                    if (!mController.appCrashed(name, pid,
11090                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11091                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11092                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11093                            Slog.w(TAG, "Skip killing native crashed app " + name
11094                                    + "(" + pid + ") during testing");
11095                        } else {
11096                            Slog.w(TAG, "Force-killing crashed app " + name
11097                                    + " at watcher's request");
11098                            Process.killProcess(pid);
11099                            if (r != null) {
11100                                Process.killProcessGroup(uid, pid);
11101                            }
11102                        }
11103                        return;
11104                    }
11105                } catch (RemoteException e) {
11106                    mController = null;
11107                    Watchdog.getInstance().setActivityController(null);
11108                }
11109            }
11110
11111            final long origId = Binder.clearCallingIdentity();
11112
11113            // If this process is running instrumentation, finish it.
11114            if (r != null && r.instrumentationClass != null) {
11115                Slog.w(TAG, "Error in app " + r.processName
11116                      + " running instrumentation " + r.instrumentationClass + ":");
11117                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11118                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11119                Bundle info = new Bundle();
11120                info.putString("shortMsg", shortMsg);
11121                info.putString("longMsg", longMsg);
11122                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11123                Binder.restoreCallingIdentity(origId);
11124                return;
11125            }
11126
11127            // If we can't identify the process or it's already exceeded its crash quota,
11128            // quit right away without showing a crash dialog.
11129            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11130                Binder.restoreCallingIdentity(origId);
11131                return;
11132            }
11133
11134            Message msg = Message.obtain();
11135            msg.what = SHOW_ERROR_MSG;
11136            HashMap data = new HashMap();
11137            data.put("result", result);
11138            data.put("app", r);
11139            msg.obj = data;
11140            mHandler.sendMessage(msg);
11141
11142            Binder.restoreCallingIdentity(origId);
11143        }
11144
11145        int res = result.get();
11146
11147        Intent appErrorIntent = null;
11148        synchronized (this) {
11149            if (r != null && !r.isolated) {
11150                // XXX Can't keep track of crash time for isolated processes,
11151                // since they don't have a persistent identity.
11152                mProcessCrashTimes.put(r.info.processName, r.uid,
11153                        SystemClock.uptimeMillis());
11154            }
11155            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11156                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11157            }
11158        }
11159
11160        if (appErrorIntent != null) {
11161            try {
11162                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11163            } catch (ActivityNotFoundException e) {
11164                Slog.w(TAG, "bug report receiver dissappeared", e);
11165            }
11166        }
11167    }
11168
11169    Intent createAppErrorIntentLocked(ProcessRecord r,
11170            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11171        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11172        if (report == null) {
11173            return null;
11174        }
11175        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11176        result.setComponent(r.errorReportReceiver);
11177        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11178        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11179        return result;
11180    }
11181
11182    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11183            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11184        if (r.errorReportReceiver == null) {
11185            return null;
11186        }
11187
11188        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11189            return null;
11190        }
11191
11192        ApplicationErrorReport report = new ApplicationErrorReport();
11193        report.packageName = r.info.packageName;
11194        report.installerPackageName = r.errorReportReceiver.getPackageName();
11195        report.processName = r.processName;
11196        report.time = timeMillis;
11197        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11198
11199        if (r.crashing || r.forceCrashReport) {
11200            report.type = ApplicationErrorReport.TYPE_CRASH;
11201            report.crashInfo = crashInfo;
11202        } else if (r.notResponding) {
11203            report.type = ApplicationErrorReport.TYPE_ANR;
11204            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11205
11206            report.anrInfo.activity = r.notRespondingReport.tag;
11207            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11208            report.anrInfo.info = r.notRespondingReport.longMsg;
11209        }
11210
11211        return report;
11212    }
11213
11214    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11215        enforceNotIsolatedCaller("getProcessesInErrorState");
11216        // assume our apps are happy - lazy create the list
11217        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11218
11219        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11220                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11221        int userId = UserHandle.getUserId(Binder.getCallingUid());
11222
11223        synchronized (this) {
11224
11225            // iterate across all processes
11226            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11227                ProcessRecord app = mLruProcesses.get(i);
11228                if (!allUsers && app.userId != userId) {
11229                    continue;
11230                }
11231                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11232                    // This one's in trouble, so we'll generate a report for it
11233                    // crashes are higher priority (in case there's a crash *and* an anr)
11234                    ActivityManager.ProcessErrorStateInfo report = null;
11235                    if (app.crashing) {
11236                        report = app.crashingReport;
11237                    } else if (app.notResponding) {
11238                        report = app.notRespondingReport;
11239                    }
11240
11241                    if (report != null) {
11242                        if (errList == null) {
11243                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11244                        }
11245                        errList.add(report);
11246                    } else {
11247                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11248                                " crashing = " + app.crashing +
11249                                " notResponding = " + app.notResponding);
11250                    }
11251                }
11252            }
11253        }
11254
11255        return errList;
11256    }
11257
11258    static int procStateToImportance(int procState, int memAdj,
11259            ActivityManager.RunningAppProcessInfo currApp) {
11260        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11261        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11262            currApp.lru = memAdj;
11263        } else {
11264            currApp.lru = 0;
11265        }
11266        return imp;
11267    }
11268
11269    private void fillInProcMemInfo(ProcessRecord app,
11270            ActivityManager.RunningAppProcessInfo outInfo) {
11271        outInfo.pid = app.pid;
11272        outInfo.uid = app.info.uid;
11273        if (mHeavyWeightProcess == app) {
11274            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11275        }
11276        if (app.persistent) {
11277            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11278        }
11279        if (app.activities.size() > 0) {
11280            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11281        }
11282        outInfo.lastTrimLevel = app.trimMemoryLevel;
11283        int adj = app.curAdj;
11284        int procState = app.curProcState;
11285        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11286        outInfo.importanceReasonCode = app.adjTypeCode;
11287        outInfo.processState = app.curProcState;
11288    }
11289
11290    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11291        enforceNotIsolatedCaller("getRunningAppProcesses");
11292        // Lazy instantiation of list
11293        List<ActivityManager.RunningAppProcessInfo> runList = null;
11294        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11295                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11296        int userId = UserHandle.getUserId(Binder.getCallingUid());
11297        synchronized (this) {
11298            // Iterate across all processes
11299            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11300                ProcessRecord app = mLruProcesses.get(i);
11301                if (!allUsers && app.userId != userId) {
11302                    continue;
11303                }
11304                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11305                    // Generate process state info for running application
11306                    ActivityManager.RunningAppProcessInfo currApp =
11307                        new ActivityManager.RunningAppProcessInfo(app.processName,
11308                                app.pid, app.getPackageList());
11309                    fillInProcMemInfo(app, currApp);
11310                    if (app.adjSource instanceof ProcessRecord) {
11311                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11312                        currApp.importanceReasonImportance =
11313                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11314                                        app.adjSourceProcState);
11315                    } else if (app.adjSource instanceof ActivityRecord) {
11316                        ActivityRecord r = (ActivityRecord)app.adjSource;
11317                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11318                    }
11319                    if (app.adjTarget instanceof ComponentName) {
11320                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11321                    }
11322                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11323                    //        + " lru=" + currApp.lru);
11324                    if (runList == null) {
11325                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11326                    }
11327                    runList.add(currApp);
11328                }
11329            }
11330        }
11331        return runList;
11332    }
11333
11334    public List<ApplicationInfo> getRunningExternalApplications() {
11335        enforceNotIsolatedCaller("getRunningExternalApplications");
11336        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11337        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11338        if (runningApps != null && runningApps.size() > 0) {
11339            Set<String> extList = new HashSet<String>();
11340            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11341                if (app.pkgList != null) {
11342                    for (String pkg : app.pkgList) {
11343                        extList.add(pkg);
11344                    }
11345                }
11346            }
11347            IPackageManager pm = AppGlobals.getPackageManager();
11348            for (String pkg : extList) {
11349                try {
11350                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11351                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11352                        retList.add(info);
11353                    }
11354                } catch (RemoteException e) {
11355                }
11356            }
11357        }
11358        return retList;
11359    }
11360
11361    @Override
11362    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11363        enforceNotIsolatedCaller("getMyMemoryState");
11364        synchronized (this) {
11365            ProcessRecord proc;
11366            synchronized (mPidsSelfLocked) {
11367                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11368            }
11369            fillInProcMemInfo(proc, outInfo);
11370        }
11371    }
11372
11373    @Override
11374    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11375        if (checkCallingPermission(android.Manifest.permission.DUMP)
11376                != PackageManager.PERMISSION_GRANTED) {
11377            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11378                    + Binder.getCallingPid()
11379                    + ", uid=" + Binder.getCallingUid()
11380                    + " without permission "
11381                    + android.Manifest.permission.DUMP);
11382            return;
11383        }
11384
11385        boolean dumpAll = false;
11386        boolean dumpClient = false;
11387        String dumpPackage = null;
11388
11389        int opti = 0;
11390        while (opti < args.length) {
11391            String opt = args[opti];
11392            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11393                break;
11394            }
11395            opti++;
11396            if ("-a".equals(opt)) {
11397                dumpAll = true;
11398            } else if ("-c".equals(opt)) {
11399                dumpClient = true;
11400            } else if ("-h".equals(opt)) {
11401                pw.println("Activity manager dump options:");
11402                pw.println("  [-a] [-c] [-h] [cmd] ...");
11403                pw.println("  cmd may be one of:");
11404                pw.println("    a[ctivities]: activity stack state");
11405                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11406                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11407                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11408                pw.println("    o[om]: out of memory management");
11409                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11410                pw.println("    provider [COMP_SPEC]: provider client-side state");
11411                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11412                pw.println("    service [COMP_SPEC]: service client-side state");
11413                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11414                pw.println("    all: dump all activities");
11415                pw.println("    top: dump the top activity");
11416                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11417                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11418                pw.println("    a partial substring in a component name, a");
11419                pw.println("    hex object identifier.");
11420                pw.println("  -a: include all available server state.");
11421                pw.println("  -c: include client state.");
11422                return;
11423            } else {
11424                pw.println("Unknown argument: " + opt + "; use -h for help");
11425            }
11426        }
11427
11428        long origId = Binder.clearCallingIdentity();
11429        boolean more = false;
11430        // Is the caller requesting to dump a particular piece of data?
11431        if (opti < args.length) {
11432            String cmd = args[opti];
11433            opti++;
11434            if ("activities".equals(cmd) || "a".equals(cmd)) {
11435                synchronized (this) {
11436                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11437                }
11438            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11439                String[] newArgs;
11440                String name;
11441                if (opti >= args.length) {
11442                    name = null;
11443                    newArgs = EMPTY_STRING_ARRAY;
11444                } else {
11445                    name = args[opti];
11446                    opti++;
11447                    newArgs = new String[args.length - opti];
11448                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11449                            args.length - opti);
11450                }
11451                synchronized (this) {
11452                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11453                }
11454            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11455                String[] newArgs;
11456                String name;
11457                if (opti >= args.length) {
11458                    name = null;
11459                    newArgs = EMPTY_STRING_ARRAY;
11460                } else {
11461                    name = args[opti];
11462                    opti++;
11463                    newArgs = new String[args.length - opti];
11464                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11465                            args.length - opti);
11466                }
11467                synchronized (this) {
11468                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11469                }
11470            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11471                String[] newArgs;
11472                String name;
11473                if (opti >= args.length) {
11474                    name = null;
11475                    newArgs = EMPTY_STRING_ARRAY;
11476                } else {
11477                    name = args[opti];
11478                    opti++;
11479                    newArgs = new String[args.length - opti];
11480                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11481                            args.length - opti);
11482                }
11483                synchronized (this) {
11484                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11485                }
11486            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11487                synchronized (this) {
11488                    dumpOomLocked(fd, pw, args, opti, true);
11489                }
11490            } else if ("provider".equals(cmd)) {
11491                String[] newArgs;
11492                String name;
11493                if (opti >= args.length) {
11494                    name = null;
11495                    newArgs = EMPTY_STRING_ARRAY;
11496                } else {
11497                    name = args[opti];
11498                    opti++;
11499                    newArgs = new String[args.length - opti];
11500                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11501                }
11502                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11503                    pw.println("No providers match: " + name);
11504                    pw.println("Use -h for help.");
11505                }
11506            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11507                synchronized (this) {
11508                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11509                }
11510            } else if ("service".equals(cmd)) {
11511                String[] newArgs;
11512                String name;
11513                if (opti >= args.length) {
11514                    name = null;
11515                    newArgs = EMPTY_STRING_ARRAY;
11516                } else {
11517                    name = args[opti];
11518                    opti++;
11519                    newArgs = new String[args.length - opti];
11520                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11521                            args.length - opti);
11522                }
11523                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11524                    pw.println("No services match: " + name);
11525                    pw.println("Use -h for help.");
11526                }
11527            } else if ("package".equals(cmd)) {
11528                String[] newArgs;
11529                if (opti >= args.length) {
11530                    pw.println("package: no package name specified");
11531                    pw.println("Use -h for help.");
11532                } else {
11533                    dumpPackage = args[opti];
11534                    opti++;
11535                    newArgs = new String[args.length - opti];
11536                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11537                            args.length - opti);
11538                    args = newArgs;
11539                    opti = 0;
11540                    more = true;
11541                }
11542            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11543                synchronized (this) {
11544                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11545                }
11546            } else {
11547                // Dumping a single activity?
11548                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11549                    pw.println("Bad activity command, or no activities match: " + cmd);
11550                    pw.println("Use -h for help.");
11551                }
11552            }
11553            if (!more) {
11554                Binder.restoreCallingIdentity(origId);
11555                return;
11556            }
11557        }
11558
11559        // No piece of data specified, dump everything.
11560        synchronized (this) {
11561            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11562            pw.println();
11563            if (dumpAll) {
11564                pw.println("-------------------------------------------------------------------------------");
11565            }
11566            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11567            pw.println();
11568            if (dumpAll) {
11569                pw.println("-------------------------------------------------------------------------------");
11570            }
11571            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11572            pw.println();
11573            if (dumpAll) {
11574                pw.println("-------------------------------------------------------------------------------");
11575            }
11576            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11577            pw.println();
11578            if (dumpAll) {
11579                pw.println("-------------------------------------------------------------------------------");
11580            }
11581            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11582            pw.println();
11583            if (dumpAll) {
11584                pw.println("-------------------------------------------------------------------------------");
11585            }
11586            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11587        }
11588        Binder.restoreCallingIdentity(origId);
11589    }
11590
11591    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11592            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11593        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11594
11595        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11596                dumpPackage);
11597        boolean needSep = printedAnything;
11598
11599        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11600                dumpPackage, needSep, "  mFocusedActivity: ");
11601        if (printed) {
11602            printedAnything = true;
11603            needSep = false;
11604        }
11605
11606        if (dumpPackage == null) {
11607            if (needSep) {
11608                pw.println();
11609            }
11610            needSep = true;
11611            printedAnything = true;
11612            mStackSupervisor.dump(pw, "  ");
11613        }
11614
11615        if (mRecentTasks.size() > 0) {
11616            boolean printedHeader = false;
11617
11618            final int N = mRecentTasks.size();
11619            for (int i=0; i<N; i++) {
11620                TaskRecord tr = mRecentTasks.get(i);
11621                if (dumpPackage != null) {
11622                    if (tr.realActivity == null ||
11623                            !dumpPackage.equals(tr.realActivity)) {
11624                        continue;
11625                    }
11626                }
11627                if (!printedHeader) {
11628                    if (needSep) {
11629                        pw.println();
11630                    }
11631                    pw.println("  Recent tasks:");
11632                    printedHeader = true;
11633                    printedAnything = true;
11634                }
11635                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11636                        pw.println(tr);
11637                if (dumpAll) {
11638                    mRecentTasks.get(i).dump(pw, "    ");
11639                }
11640            }
11641        }
11642
11643        if (!printedAnything) {
11644            pw.println("  (nothing)");
11645        }
11646    }
11647
11648    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11649            int opti, boolean dumpAll, String dumpPackage) {
11650        boolean needSep = false;
11651        boolean printedAnything = false;
11652        int numPers = 0;
11653
11654        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11655
11656        if (dumpAll) {
11657            final int NP = mProcessNames.getMap().size();
11658            for (int ip=0; ip<NP; ip++) {
11659                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11660                final int NA = procs.size();
11661                for (int ia=0; ia<NA; ia++) {
11662                    ProcessRecord r = procs.valueAt(ia);
11663                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11664                        continue;
11665                    }
11666                    if (!needSep) {
11667                        pw.println("  All known processes:");
11668                        needSep = true;
11669                        printedAnything = true;
11670                    }
11671                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11672                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11673                        pw.print(" "); pw.println(r);
11674                    r.dump(pw, "    ");
11675                    if (r.persistent) {
11676                        numPers++;
11677                    }
11678                }
11679            }
11680        }
11681
11682        if (mIsolatedProcesses.size() > 0) {
11683            boolean printed = false;
11684            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11685                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11686                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11687                    continue;
11688                }
11689                if (!printed) {
11690                    if (needSep) {
11691                        pw.println();
11692                    }
11693                    pw.println("  Isolated process list (sorted by uid):");
11694                    printedAnything = true;
11695                    printed = true;
11696                    needSep = true;
11697                }
11698                pw.println(String.format("%sIsolated #%2d: %s",
11699                        "    ", i, r.toString()));
11700            }
11701        }
11702
11703        if (mLruProcesses.size() > 0) {
11704            if (needSep) {
11705                pw.println();
11706            }
11707            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11708                    pw.print(" total, non-act at ");
11709                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11710                    pw.print(", non-svc at ");
11711                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11712                    pw.println("):");
11713            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11714            needSep = true;
11715            printedAnything = true;
11716        }
11717
11718        if (dumpAll || dumpPackage != null) {
11719            synchronized (mPidsSelfLocked) {
11720                boolean printed = false;
11721                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11722                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11723                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11724                        continue;
11725                    }
11726                    if (!printed) {
11727                        if (needSep) pw.println();
11728                        needSep = true;
11729                        pw.println("  PID mappings:");
11730                        printed = true;
11731                        printedAnything = true;
11732                    }
11733                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11734                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11735                }
11736            }
11737        }
11738
11739        if (mForegroundProcesses.size() > 0) {
11740            synchronized (mPidsSelfLocked) {
11741                boolean printed = false;
11742                for (int i=0; i<mForegroundProcesses.size(); i++) {
11743                    ProcessRecord r = mPidsSelfLocked.get(
11744                            mForegroundProcesses.valueAt(i).pid);
11745                    if (dumpPackage != null && (r == null
11746                            || !r.pkgList.containsKey(dumpPackage))) {
11747                        continue;
11748                    }
11749                    if (!printed) {
11750                        if (needSep) pw.println();
11751                        needSep = true;
11752                        pw.println("  Foreground Processes:");
11753                        printed = true;
11754                        printedAnything = true;
11755                    }
11756                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11757                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11758                }
11759            }
11760        }
11761
11762        if (mPersistentStartingProcesses.size() > 0) {
11763            if (needSep) pw.println();
11764            needSep = true;
11765            printedAnything = true;
11766            pw.println("  Persisent processes that are starting:");
11767            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11768                    "Starting Norm", "Restarting PERS", dumpPackage);
11769        }
11770
11771        if (mRemovedProcesses.size() > 0) {
11772            if (needSep) pw.println();
11773            needSep = true;
11774            printedAnything = true;
11775            pw.println("  Processes that are being removed:");
11776            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11777                    "Removed Norm", "Removed PERS", dumpPackage);
11778        }
11779
11780        if (mProcessesOnHold.size() > 0) {
11781            if (needSep) pw.println();
11782            needSep = true;
11783            printedAnything = true;
11784            pw.println("  Processes that are on old until the system is ready:");
11785            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11786                    "OnHold Norm", "OnHold PERS", dumpPackage);
11787        }
11788
11789        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11790
11791        if (mProcessCrashTimes.getMap().size() > 0) {
11792            boolean printed = false;
11793            long now = SystemClock.uptimeMillis();
11794            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11795            final int NP = pmap.size();
11796            for (int ip=0; ip<NP; ip++) {
11797                String pname = pmap.keyAt(ip);
11798                SparseArray<Long> uids = pmap.valueAt(ip);
11799                final int N = uids.size();
11800                for (int i=0; i<N; i++) {
11801                    int puid = uids.keyAt(i);
11802                    ProcessRecord r = mProcessNames.get(pname, puid);
11803                    if (dumpPackage != null && (r == null
11804                            || !r.pkgList.containsKey(dumpPackage))) {
11805                        continue;
11806                    }
11807                    if (!printed) {
11808                        if (needSep) pw.println();
11809                        needSep = true;
11810                        pw.println("  Time since processes crashed:");
11811                        printed = true;
11812                        printedAnything = true;
11813                    }
11814                    pw.print("    Process "); pw.print(pname);
11815                            pw.print(" uid "); pw.print(puid);
11816                            pw.print(": last crashed ");
11817                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11818                            pw.println(" ago");
11819                }
11820            }
11821        }
11822
11823        if (mBadProcesses.getMap().size() > 0) {
11824            boolean printed = false;
11825            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11826            final int NP = pmap.size();
11827            for (int ip=0; ip<NP; ip++) {
11828                String pname = pmap.keyAt(ip);
11829                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11830                final int N = uids.size();
11831                for (int i=0; i<N; i++) {
11832                    int puid = uids.keyAt(i);
11833                    ProcessRecord r = mProcessNames.get(pname, puid);
11834                    if (dumpPackage != null && (r == null
11835                            || !r.pkgList.containsKey(dumpPackage))) {
11836                        continue;
11837                    }
11838                    if (!printed) {
11839                        if (needSep) pw.println();
11840                        needSep = true;
11841                        pw.println("  Bad processes:");
11842                        printedAnything = true;
11843                    }
11844                    BadProcessInfo info = uids.valueAt(i);
11845                    pw.print("    Bad process "); pw.print(pname);
11846                            pw.print(" uid "); pw.print(puid);
11847                            pw.print(": crashed at time "); pw.println(info.time);
11848                    if (info.shortMsg != null) {
11849                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11850                    }
11851                    if (info.longMsg != null) {
11852                        pw.print("      Long msg: "); pw.println(info.longMsg);
11853                    }
11854                    if (info.stack != null) {
11855                        pw.println("      Stack:");
11856                        int lastPos = 0;
11857                        for (int pos=0; pos<info.stack.length(); pos++) {
11858                            if (info.stack.charAt(pos) == '\n') {
11859                                pw.print("        ");
11860                                pw.write(info.stack, lastPos, pos-lastPos);
11861                                pw.println();
11862                                lastPos = pos+1;
11863                            }
11864                        }
11865                        if (lastPos < info.stack.length()) {
11866                            pw.print("        ");
11867                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11868                            pw.println();
11869                        }
11870                    }
11871                }
11872            }
11873        }
11874
11875        if (dumpPackage == null) {
11876            pw.println();
11877            needSep = false;
11878            pw.println("  mStartedUsers:");
11879            for (int i=0; i<mStartedUsers.size(); i++) {
11880                UserStartedState uss = mStartedUsers.valueAt(i);
11881                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11882                        pw.print(": "); uss.dump("", pw);
11883            }
11884            pw.print("  mStartedUserArray: [");
11885            for (int i=0; i<mStartedUserArray.length; i++) {
11886                if (i > 0) pw.print(", ");
11887                pw.print(mStartedUserArray[i]);
11888            }
11889            pw.println("]");
11890            pw.print("  mUserLru: [");
11891            for (int i=0; i<mUserLru.size(); i++) {
11892                if (i > 0) pw.print(", ");
11893                pw.print(mUserLru.get(i));
11894            }
11895            pw.println("]");
11896            if (dumpAll) {
11897                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11898            }
11899            synchronized (mUserProfileGroupIdsSelfLocked) {
11900                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11901                    pw.println("  mUserProfileGroupIds:");
11902                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11903                        pw.print("    User #");
11904                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11905                        pw.print(" -> profile #");
11906                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11907                    }
11908                }
11909            }
11910        }
11911        if (mHomeProcess != null && (dumpPackage == null
11912                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11913            if (needSep) {
11914                pw.println();
11915                needSep = false;
11916            }
11917            pw.println("  mHomeProcess: " + mHomeProcess);
11918        }
11919        if (mPreviousProcess != null && (dumpPackage == null
11920                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11921            if (needSep) {
11922                pw.println();
11923                needSep = false;
11924            }
11925            pw.println("  mPreviousProcess: " + mPreviousProcess);
11926        }
11927        if (dumpAll) {
11928            StringBuilder sb = new StringBuilder(128);
11929            sb.append("  mPreviousProcessVisibleTime: ");
11930            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11931            pw.println(sb);
11932        }
11933        if (mHeavyWeightProcess != null && (dumpPackage == null
11934                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11935            if (needSep) {
11936                pw.println();
11937                needSep = false;
11938            }
11939            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11940        }
11941        if (dumpPackage == null) {
11942            pw.println("  mConfiguration: " + mConfiguration);
11943        }
11944        if (dumpAll) {
11945            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11946            if (mCompatModePackages.getPackages().size() > 0) {
11947                boolean printed = false;
11948                for (Map.Entry<String, Integer> entry
11949                        : mCompatModePackages.getPackages().entrySet()) {
11950                    String pkg = entry.getKey();
11951                    int mode = entry.getValue();
11952                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11953                        continue;
11954                    }
11955                    if (!printed) {
11956                        pw.println("  mScreenCompatPackages:");
11957                        printed = true;
11958                    }
11959                    pw.print("    "); pw.print(pkg); pw.print(": ");
11960                            pw.print(mode); pw.println();
11961                }
11962            }
11963        }
11964        if (dumpPackage == null) {
11965            if (mSleeping || mWentToSleep || mLockScreenShown) {
11966                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11967                        + " mLockScreenShown " + mLockScreenShown);
11968            }
11969            if (mShuttingDown || mRunningVoice) {
11970                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11971            }
11972        }
11973        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11974                || mOrigWaitForDebugger) {
11975            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11976                    || dumpPackage.equals(mOrigDebugApp)) {
11977                if (needSep) {
11978                    pw.println();
11979                    needSep = false;
11980                }
11981                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11982                        + " mDebugTransient=" + mDebugTransient
11983                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11984            }
11985        }
11986        if (mOpenGlTraceApp != null) {
11987            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11988                if (needSep) {
11989                    pw.println();
11990                    needSep = false;
11991                }
11992                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11993            }
11994        }
11995        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11996                || mProfileFd != null) {
11997            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11998                if (needSep) {
11999                    pw.println();
12000                    needSep = false;
12001                }
12002                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12003                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12004                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
12005                        + mAutoStopProfiler);
12006            }
12007        }
12008        if (dumpPackage == null) {
12009            if (mAlwaysFinishActivities || mController != null) {
12010                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12011                        + " mController=" + mController);
12012            }
12013            if (dumpAll) {
12014                pw.println("  Total persistent processes: " + numPers);
12015                pw.println("  mProcessesReady=" + mProcessesReady
12016                        + " mSystemReady=" + mSystemReady);
12017                pw.println("  mBooting=" + mBooting
12018                        + " mBooted=" + mBooted
12019                        + " mFactoryTest=" + mFactoryTest);
12020                pw.print("  mLastPowerCheckRealtime=");
12021                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12022                        pw.println("");
12023                pw.print("  mLastPowerCheckUptime=");
12024                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12025                        pw.println("");
12026                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12027                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12028                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12029                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12030                        + " (" + mLruProcesses.size() + " total)"
12031                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12032                        + " mNumServiceProcs=" + mNumServiceProcs
12033                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12034                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12035                        + " mLastMemoryLevel" + mLastMemoryLevel
12036                        + " mLastNumProcesses" + mLastNumProcesses);
12037                long now = SystemClock.uptimeMillis();
12038                pw.print("  mLastIdleTime=");
12039                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12040                        pw.print(" mLowRamSinceLastIdle=");
12041                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12042                        pw.println();
12043            }
12044        }
12045
12046        if (!printedAnything) {
12047            pw.println("  (nothing)");
12048        }
12049    }
12050
12051    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12052            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12053        if (mProcessesToGc.size() > 0) {
12054            boolean printed = false;
12055            long now = SystemClock.uptimeMillis();
12056            for (int i=0; i<mProcessesToGc.size(); i++) {
12057                ProcessRecord proc = mProcessesToGc.get(i);
12058                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12059                    continue;
12060                }
12061                if (!printed) {
12062                    if (needSep) pw.println();
12063                    needSep = true;
12064                    pw.println("  Processes that are waiting to GC:");
12065                    printed = true;
12066                }
12067                pw.print("    Process "); pw.println(proc);
12068                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12069                        pw.print(", last gced=");
12070                        pw.print(now-proc.lastRequestedGc);
12071                        pw.print(" ms ago, last lowMem=");
12072                        pw.print(now-proc.lastLowMemory);
12073                        pw.println(" ms ago");
12074
12075            }
12076        }
12077        return needSep;
12078    }
12079
12080    void printOomLevel(PrintWriter pw, String name, int adj) {
12081        pw.print("    ");
12082        if (adj >= 0) {
12083            pw.print(' ');
12084            if (adj < 10) pw.print(' ');
12085        } else {
12086            if (adj > -10) pw.print(' ');
12087        }
12088        pw.print(adj);
12089        pw.print(": ");
12090        pw.print(name);
12091        pw.print(" (");
12092        pw.print(mProcessList.getMemLevel(adj)/1024);
12093        pw.println(" kB)");
12094    }
12095
12096    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12097            int opti, boolean dumpAll) {
12098        boolean needSep = false;
12099
12100        if (mLruProcesses.size() > 0) {
12101            if (needSep) pw.println();
12102            needSep = true;
12103            pw.println("  OOM levels:");
12104            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12105            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12106            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12107            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12108            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12109            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12110            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12111            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12112            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12113            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12114            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12115            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12116            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12117
12118            if (needSep) pw.println();
12119            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12120                    pw.print(" total, non-act at ");
12121                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12122                    pw.print(", non-svc at ");
12123                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12124                    pw.println("):");
12125            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12126            needSep = true;
12127        }
12128
12129        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12130
12131        pw.println();
12132        pw.println("  mHomeProcess: " + mHomeProcess);
12133        pw.println("  mPreviousProcess: " + mPreviousProcess);
12134        if (mHeavyWeightProcess != null) {
12135            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12136        }
12137
12138        return true;
12139    }
12140
12141    /**
12142     * There are three ways to call this:
12143     *  - no provider specified: dump all the providers
12144     *  - a flattened component name that matched an existing provider was specified as the
12145     *    first arg: dump that one provider
12146     *  - the first arg isn't the flattened component name of an existing provider:
12147     *    dump all providers whose component contains the first arg as a substring
12148     */
12149    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12150            int opti, boolean dumpAll) {
12151        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12152    }
12153
12154    static class ItemMatcher {
12155        ArrayList<ComponentName> components;
12156        ArrayList<String> strings;
12157        ArrayList<Integer> objects;
12158        boolean all;
12159
12160        ItemMatcher() {
12161            all = true;
12162        }
12163
12164        void build(String name) {
12165            ComponentName componentName = ComponentName.unflattenFromString(name);
12166            if (componentName != null) {
12167                if (components == null) {
12168                    components = new ArrayList<ComponentName>();
12169                }
12170                components.add(componentName);
12171                all = false;
12172            } else {
12173                int objectId = 0;
12174                // Not a '/' separated full component name; maybe an object ID?
12175                try {
12176                    objectId = Integer.parseInt(name, 16);
12177                    if (objects == null) {
12178                        objects = new ArrayList<Integer>();
12179                    }
12180                    objects.add(objectId);
12181                    all = false;
12182                } catch (RuntimeException e) {
12183                    // Not an integer; just do string match.
12184                    if (strings == null) {
12185                        strings = new ArrayList<String>();
12186                    }
12187                    strings.add(name);
12188                    all = false;
12189                }
12190            }
12191        }
12192
12193        int build(String[] args, int opti) {
12194            for (; opti<args.length; opti++) {
12195                String name = args[opti];
12196                if ("--".equals(name)) {
12197                    return opti+1;
12198                }
12199                build(name);
12200            }
12201            return opti;
12202        }
12203
12204        boolean match(Object object, ComponentName comp) {
12205            if (all) {
12206                return true;
12207            }
12208            if (components != null) {
12209                for (int i=0; i<components.size(); i++) {
12210                    if (components.get(i).equals(comp)) {
12211                        return true;
12212                    }
12213                }
12214            }
12215            if (objects != null) {
12216                for (int i=0; i<objects.size(); i++) {
12217                    if (System.identityHashCode(object) == objects.get(i)) {
12218                        return true;
12219                    }
12220                }
12221            }
12222            if (strings != null) {
12223                String flat = comp.flattenToString();
12224                for (int i=0; i<strings.size(); i++) {
12225                    if (flat.contains(strings.get(i))) {
12226                        return true;
12227                    }
12228                }
12229            }
12230            return false;
12231        }
12232    }
12233
12234    /**
12235     * There are three things that cmd can be:
12236     *  - a flattened component name that matches an existing activity
12237     *  - the cmd arg isn't the flattened component name of an existing activity:
12238     *    dump all activity whose component contains the cmd as a substring
12239     *  - A hex number of the ActivityRecord object instance.
12240     */
12241    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12242            int opti, boolean dumpAll) {
12243        ArrayList<ActivityRecord> activities;
12244
12245        synchronized (this) {
12246            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12247        }
12248
12249        if (activities.size() <= 0) {
12250            return false;
12251        }
12252
12253        String[] newArgs = new String[args.length - opti];
12254        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12255
12256        TaskRecord lastTask = null;
12257        boolean needSep = false;
12258        for (int i=activities.size()-1; i>=0; i--) {
12259            ActivityRecord r = activities.get(i);
12260            if (needSep) {
12261                pw.println();
12262            }
12263            needSep = true;
12264            synchronized (this) {
12265                if (lastTask != r.task) {
12266                    lastTask = r.task;
12267                    pw.print("TASK "); pw.print(lastTask.affinity);
12268                            pw.print(" id="); pw.println(lastTask.taskId);
12269                    if (dumpAll) {
12270                        lastTask.dump(pw, "  ");
12271                    }
12272                }
12273            }
12274            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12275        }
12276        return true;
12277    }
12278
12279    /**
12280     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12281     * there is a thread associated with the activity.
12282     */
12283    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12284            final ActivityRecord r, String[] args, boolean dumpAll) {
12285        String innerPrefix = prefix + "  ";
12286        synchronized (this) {
12287            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12288                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12289                    pw.print(" pid=");
12290                    if (r.app != null) pw.println(r.app.pid);
12291                    else pw.println("(not running)");
12292            if (dumpAll) {
12293                r.dump(pw, innerPrefix);
12294            }
12295        }
12296        if (r.app != null && r.app.thread != null) {
12297            // flush anything that is already in the PrintWriter since the thread is going
12298            // to write to the file descriptor directly
12299            pw.flush();
12300            try {
12301                TransferPipe tp = new TransferPipe();
12302                try {
12303                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12304                            r.appToken, innerPrefix, args);
12305                    tp.go(fd);
12306                } finally {
12307                    tp.kill();
12308                }
12309            } catch (IOException e) {
12310                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12311            } catch (RemoteException e) {
12312                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12313            }
12314        }
12315    }
12316
12317    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12318            int opti, boolean dumpAll, String dumpPackage) {
12319        boolean needSep = false;
12320        boolean onlyHistory = false;
12321        boolean printedAnything = false;
12322
12323        if ("history".equals(dumpPackage)) {
12324            if (opti < args.length && "-s".equals(args[opti])) {
12325                dumpAll = false;
12326            }
12327            onlyHistory = true;
12328            dumpPackage = null;
12329        }
12330
12331        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12332        if (!onlyHistory && dumpAll) {
12333            if (mRegisteredReceivers.size() > 0) {
12334                boolean printed = false;
12335                Iterator it = mRegisteredReceivers.values().iterator();
12336                while (it.hasNext()) {
12337                    ReceiverList r = (ReceiverList)it.next();
12338                    if (dumpPackage != null && (r.app == null ||
12339                            !dumpPackage.equals(r.app.info.packageName))) {
12340                        continue;
12341                    }
12342                    if (!printed) {
12343                        pw.println("  Registered Receivers:");
12344                        needSep = true;
12345                        printed = true;
12346                        printedAnything = true;
12347                    }
12348                    pw.print("  * "); pw.println(r);
12349                    r.dump(pw, "    ");
12350                }
12351            }
12352
12353            if (mReceiverResolver.dump(pw, needSep ?
12354                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12355                    "    ", dumpPackage, false)) {
12356                needSep = true;
12357                printedAnything = true;
12358            }
12359        }
12360
12361        for (BroadcastQueue q : mBroadcastQueues) {
12362            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12363            printedAnything |= needSep;
12364        }
12365
12366        needSep = true;
12367
12368        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12369            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12370                if (needSep) {
12371                    pw.println();
12372                }
12373                needSep = true;
12374                printedAnything = true;
12375                pw.print("  Sticky broadcasts for user ");
12376                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12377                StringBuilder sb = new StringBuilder(128);
12378                for (Map.Entry<String, ArrayList<Intent>> ent
12379                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12380                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12381                    if (dumpAll) {
12382                        pw.println(":");
12383                        ArrayList<Intent> intents = ent.getValue();
12384                        final int N = intents.size();
12385                        for (int i=0; i<N; i++) {
12386                            sb.setLength(0);
12387                            sb.append("    Intent: ");
12388                            intents.get(i).toShortString(sb, false, true, false, false);
12389                            pw.println(sb.toString());
12390                            Bundle bundle = intents.get(i).getExtras();
12391                            if (bundle != null) {
12392                                pw.print("      ");
12393                                pw.println(bundle.toString());
12394                            }
12395                        }
12396                    } else {
12397                        pw.println("");
12398                    }
12399                }
12400            }
12401        }
12402
12403        if (!onlyHistory && dumpAll) {
12404            pw.println();
12405            for (BroadcastQueue queue : mBroadcastQueues) {
12406                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12407                        + queue.mBroadcastsScheduled);
12408            }
12409            pw.println("  mHandler:");
12410            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12411            needSep = true;
12412            printedAnything = true;
12413        }
12414
12415        if (!printedAnything) {
12416            pw.println("  (nothing)");
12417        }
12418    }
12419
12420    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12421            int opti, boolean dumpAll, String dumpPackage) {
12422        boolean needSep;
12423        boolean printedAnything = false;
12424
12425        ItemMatcher matcher = new ItemMatcher();
12426        matcher.build(args, opti);
12427
12428        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12429
12430        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12431        printedAnything |= needSep;
12432
12433        if (mLaunchingProviders.size() > 0) {
12434            boolean printed = false;
12435            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12436                ContentProviderRecord r = mLaunchingProviders.get(i);
12437                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12438                    continue;
12439                }
12440                if (!printed) {
12441                    if (needSep) pw.println();
12442                    needSep = true;
12443                    pw.println("  Launching content providers:");
12444                    printed = true;
12445                    printedAnything = true;
12446                }
12447                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12448                        pw.println(r);
12449            }
12450        }
12451
12452        if (mGrantedUriPermissions.size() > 0) {
12453            boolean printed = false;
12454            int dumpUid = -2;
12455            if (dumpPackage != null) {
12456                try {
12457                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12458                } catch (NameNotFoundException e) {
12459                    dumpUid = -1;
12460                }
12461            }
12462            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12463                int uid = mGrantedUriPermissions.keyAt(i);
12464                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12465                    continue;
12466                }
12467                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12468                if (!printed) {
12469                    if (needSep) pw.println();
12470                    needSep = true;
12471                    pw.println("  Granted Uri Permissions:");
12472                    printed = true;
12473                    printedAnything = true;
12474                }
12475                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12476                for (UriPermission perm : perms.values()) {
12477                    pw.print("    "); pw.println(perm);
12478                    if (dumpAll) {
12479                        perm.dump(pw, "      ");
12480                    }
12481                }
12482            }
12483        }
12484
12485        if (!printedAnything) {
12486            pw.println("  (nothing)");
12487        }
12488    }
12489
12490    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12491            int opti, boolean dumpAll, String dumpPackage) {
12492        boolean printed = false;
12493
12494        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12495
12496        if (mIntentSenderRecords.size() > 0) {
12497            Iterator<WeakReference<PendingIntentRecord>> it
12498                    = mIntentSenderRecords.values().iterator();
12499            while (it.hasNext()) {
12500                WeakReference<PendingIntentRecord> ref = it.next();
12501                PendingIntentRecord rec = ref != null ? ref.get(): null;
12502                if (dumpPackage != null && (rec == null
12503                        || !dumpPackage.equals(rec.key.packageName))) {
12504                    continue;
12505                }
12506                printed = true;
12507                if (rec != null) {
12508                    pw.print("  * "); pw.println(rec);
12509                    if (dumpAll) {
12510                        rec.dump(pw, "    ");
12511                    }
12512                } else {
12513                    pw.print("  * "); pw.println(ref);
12514                }
12515            }
12516        }
12517
12518        if (!printed) {
12519            pw.println("  (nothing)");
12520        }
12521    }
12522
12523    private static final int dumpProcessList(PrintWriter pw,
12524            ActivityManagerService service, List list,
12525            String prefix, String normalLabel, String persistentLabel,
12526            String dumpPackage) {
12527        int numPers = 0;
12528        final int N = list.size()-1;
12529        for (int i=N; i>=0; i--) {
12530            ProcessRecord r = (ProcessRecord)list.get(i);
12531            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12532                continue;
12533            }
12534            pw.println(String.format("%s%s #%2d: %s",
12535                    prefix, (r.persistent ? persistentLabel : normalLabel),
12536                    i, r.toString()));
12537            if (r.persistent) {
12538                numPers++;
12539            }
12540        }
12541        return numPers;
12542    }
12543
12544    private static final boolean dumpProcessOomList(PrintWriter pw,
12545            ActivityManagerService service, List<ProcessRecord> origList,
12546            String prefix, String normalLabel, String persistentLabel,
12547            boolean inclDetails, String dumpPackage) {
12548
12549        ArrayList<Pair<ProcessRecord, Integer>> list
12550                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12551        for (int i=0; i<origList.size(); i++) {
12552            ProcessRecord r = origList.get(i);
12553            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12554                continue;
12555            }
12556            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12557        }
12558
12559        if (list.size() <= 0) {
12560            return false;
12561        }
12562
12563        Comparator<Pair<ProcessRecord, Integer>> comparator
12564                = new Comparator<Pair<ProcessRecord, Integer>>() {
12565            @Override
12566            public int compare(Pair<ProcessRecord, Integer> object1,
12567                    Pair<ProcessRecord, Integer> object2) {
12568                if (object1.first.setAdj != object2.first.setAdj) {
12569                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12570                }
12571                if (object1.second.intValue() != object2.second.intValue()) {
12572                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12573                }
12574                return 0;
12575            }
12576        };
12577
12578        Collections.sort(list, comparator);
12579
12580        final long curRealtime = SystemClock.elapsedRealtime();
12581        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12582        final long curUptime = SystemClock.uptimeMillis();
12583        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12584
12585        for (int i=list.size()-1; i>=0; i--) {
12586            ProcessRecord r = list.get(i).first;
12587            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12588            char schedGroup;
12589            switch (r.setSchedGroup) {
12590                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12591                    schedGroup = 'B';
12592                    break;
12593                case Process.THREAD_GROUP_DEFAULT:
12594                    schedGroup = 'F';
12595                    break;
12596                default:
12597                    schedGroup = '?';
12598                    break;
12599            }
12600            char foreground;
12601            if (r.foregroundActivities) {
12602                foreground = 'A';
12603            } else if (r.foregroundServices) {
12604                foreground = 'S';
12605            } else {
12606                foreground = ' ';
12607            }
12608            String procState = ProcessList.makeProcStateString(r.curProcState);
12609            pw.print(prefix);
12610            pw.print(r.persistent ? persistentLabel : normalLabel);
12611            pw.print(" #");
12612            int num = (origList.size()-1)-list.get(i).second;
12613            if (num < 10) pw.print(' ');
12614            pw.print(num);
12615            pw.print(": ");
12616            pw.print(oomAdj);
12617            pw.print(' ');
12618            pw.print(schedGroup);
12619            pw.print('/');
12620            pw.print(foreground);
12621            pw.print('/');
12622            pw.print(procState);
12623            pw.print(" trm:");
12624            if (r.trimMemoryLevel < 10) pw.print(' ');
12625            pw.print(r.trimMemoryLevel);
12626            pw.print(' ');
12627            pw.print(r.toShortString());
12628            pw.print(" (");
12629            pw.print(r.adjType);
12630            pw.println(')');
12631            if (r.adjSource != null || r.adjTarget != null) {
12632                pw.print(prefix);
12633                pw.print("    ");
12634                if (r.adjTarget instanceof ComponentName) {
12635                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12636                } else if (r.adjTarget != null) {
12637                    pw.print(r.adjTarget.toString());
12638                } else {
12639                    pw.print("{null}");
12640                }
12641                pw.print("<=");
12642                if (r.adjSource instanceof ProcessRecord) {
12643                    pw.print("Proc{");
12644                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12645                    pw.println("}");
12646                } else if (r.adjSource != null) {
12647                    pw.println(r.adjSource.toString());
12648                } else {
12649                    pw.println("{null}");
12650                }
12651            }
12652            if (inclDetails) {
12653                pw.print(prefix);
12654                pw.print("    ");
12655                pw.print("oom: max="); pw.print(r.maxAdj);
12656                pw.print(" curRaw="); pw.print(r.curRawAdj);
12657                pw.print(" setRaw="); pw.print(r.setRawAdj);
12658                pw.print(" cur="); pw.print(r.curAdj);
12659                pw.print(" set="); pw.println(r.setAdj);
12660                pw.print(prefix);
12661                pw.print("    ");
12662                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12663                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12664                pw.print(" lastPss="); pw.print(r.lastPss);
12665                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12666                pw.print(prefix);
12667                pw.print("    ");
12668                pw.print("cached="); pw.print(r.cached);
12669                pw.print(" empty="); pw.print(r.empty);
12670                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12671
12672                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12673                    if (r.lastWakeTime != 0) {
12674                        long wtime;
12675                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12676                        synchronized (stats) {
12677                            wtime = stats.getProcessWakeTime(r.info.uid,
12678                                    r.pid, curRealtime);
12679                        }
12680                        long timeUsed = wtime - r.lastWakeTime;
12681                        pw.print(prefix);
12682                        pw.print("    ");
12683                        pw.print("keep awake over ");
12684                        TimeUtils.formatDuration(realtimeSince, pw);
12685                        pw.print(" used ");
12686                        TimeUtils.formatDuration(timeUsed, pw);
12687                        pw.print(" (");
12688                        pw.print((timeUsed*100)/realtimeSince);
12689                        pw.println("%)");
12690                    }
12691                    if (r.lastCpuTime != 0) {
12692                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12693                        pw.print(prefix);
12694                        pw.print("    ");
12695                        pw.print("run cpu over ");
12696                        TimeUtils.formatDuration(uptimeSince, pw);
12697                        pw.print(" used ");
12698                        TimeUtils.formatDuration(timeUsed, pw);
12699                        pw.print(" (");
12700                        pw.print((timeUsed*100)/uptimeSince);
12701                        pw.println("%)");
12702                    }
12703                }
12704            }
12705        }
12706        return true;
12707    }
12708
12709    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12710        ArrayList<ProcessRecord> procs;
12711        synchronized (this) {
12712            if (args != null && args.length > start
12713                    && args[start].charAt(0) != '-') {
12714                procs = new ArrayList<ProcessRecord>();
12715                int pid = -1;
12716                try {
12717                    pid = Integer.parseInt(args[start]);
12718                } catch (NumberFormatException e) {
12719                }
12720                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12721                    ProcessRecord proc = mLruProcesses.get(i);
12722                    if (proc.pid == pid) {
12723                        procs.add(proc);
12724                    } else if (proc.processName.equals(args[start])) {
12725                        procs.add(proc);
12726                    }
12727                }
12728                if (procs.size() <= 0) {
12729                    return null;
12730                }
12731            } else {
12732                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12733            }
12734        }
12735        return procs;
12736    }
12737
12738    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12739            PrintWriter pw, String[] args) {
12740        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12741        if (procs == null) {
12742            pw.println("No process found for: " + args[0]);
12743            return;
12744        }
12745
12746        long uptime = SystemClock.uptimeMillis();
12747        long realtime = SystemClock.elapsedRealtime();
12748        pw.println("Applications Graphics Acceleration Info:");
12749        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12750
12751        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12752            ProcessRecord r = procs.get(i);
12753            if (r.thread != null) {
12754                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12755                pw.flush();
12756                try {
12757                    TransferPipe tp = new TransferPipe();
12758                    try {
12759                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12760                        tp.go(fd);
12761                    } finally {
12762                        tp.kill();
12763                    }
12764                } catch (IOException e) {
12765                    pw.println("Failure while dumping the app: " + r);
12766                    pw.flush();
12767                } catch (RemoteException e) {
12768                    pw.println("Got a RemoteException while dumping the app " + r);
12769                    pw.flush();
12770                }
12771            }
12772        }
12773    }
12774
12775    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12776        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12777        if (procs == null) {
12778            pw.println("No process found for: " + args[0]);
12779            return;
12780        }
12781
12782        pw.println("Applications Database Info:");
12783
12784        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12785            ProcessRecord r = procs.get(i);
12786            if (r.thread != null) {
12787                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12788                pw.flush();
12789                try {
12790                    TransferPipe tp = new TransferPipe();
12791                    try {
12792                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12793                        tp.go(fd);
12794                    } finally {
12795                        tp.kill();
12796                    }
12797                } catch (IOException e) {
12798                    pw.println("Failure while dumping the app: " + r);
12799                    pw.flush();
12800                } catch (RemoteException e) {
12801                    pw.println("Got a RemoteException while dumping the app " + r);
12802                    pw.flush();
12803                }
12804            }
12805        }
12806    }
12807
12808    final static class MemItem {
12809        final boolean isProc;
12810        final String label;
12811        final String shortLabel;
12812        final long pss;
12813        final int id;
12814        final boolean hasActivities;
12815        ArrayList<MemItem> subitems;
12816
12817        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12818                boolean _hasActivities) {
12819            isProc = true;
12820            label = _label;
12821            shortLabel = _shortLabel;
12822            pss = _pss;
12823            id = _id;
12824            hasActivities = _hasActivities;
12825        }
12826
12827        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12828            isProc = false;
12829            label = _label;
12830            shortLabel = _shortLabel;
12831            pss = _pss;
12832            id = _id;
12833            hasActivities = false;
12834        }
12835    }
12836
12837    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12838            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12839        if (sort && !isCompact) {
12840            Collections.sort(items, new Comparator<MemItem>() {
12841                @Override
12842                public int compare(MemItem lhs, MemItem rhs) {
12843                    if (lhs.pss < rhs.pss) {
12844                        return 1;
12845                    } else if (lhs.pss > rhs.pss) {
12846                        return -1;
12847                    }
12848                    return 0;
12849                }
12850            });
12851        }
12852
12853        for (int i=0; i<items.size(); i++) {
12854            MemItem mi = items.get(i);
12855            if (!isCompact) {
12856                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12857            } else if (mi.isProc) {
12858                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12859                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12860                pw.println(mi.hasActivities ? ",a" : ",e");
12861            } else {
12862                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12863                pw.println(mi.pss);
12864            }
12865            if (mi.subitems != null) {
12866                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12867                        true, isCompact);
12868            }
12869        }
12870    }
12871
12872    // These are in KB.
12873    static final long[] DUMP_MEM_BUCKETS = new long[] {
12874        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12875        120*1024, 160*1024, 200*1024,
12876        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12877        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12878    };
12879
12880    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12881            boolean stackLike) {
12882        int start = label.lastIndexOf('.');
12883        if (start >= 0) start++;
12884        else start = 0;
12885        int end = label.length();
12886        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12887            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12888                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12889                out.append(bucket);
12890                out.append(stackLike ? "MB." : "MB ");
12891                out.append(label, start, end);
12892                return;
12893            }
12894        }
12895        out.append(memKB/1024);
12896        out.append(stackLike ? "MB." : "MB ");
12897        out.append(label, start, end);
12898    }
12899
12900    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12901            ProcessList.NATIVE_ADJ,
12902            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12903            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12904            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12905            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12906            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12907    };
12908    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12909            "Native",
12910            "System", "Persistent", "Foreground",
12911            "Visible", "Perceptible",
12912            "Heavy Weight", "Backup",
12913            "A Services", "Home",
12914            "Previous", "B Services", "Cached"
12915    };
12916    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12917            "native",
12918            "sys", "pers", "fore",
12919            "vis", "percept",
12920            "heavy", "backup",
12921            "servicea", "home",
12922            "prev", "serviceb", "cached"
12923    };
12924
12925    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12926            long realtime, boolean isCheckinRequest, boolean isCompact) {
12927        if (isCheckinRequest || isCompact) {
12928            // short checkin version
12929            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12930        } else {
12931            pw.println("Applications Memory Usage (kB):");
12932            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12933        }
12934    }
12935
12936    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12937            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12938        boolean dumpDetails = false;
12939        boolean dumpFullDetails = false;
12940        boolean dumpDalvik = false;
12941        boolean oomOnly = false;
12942        boolean isCompact = false;
12943        boolean localOnly = false;
12944
12945        int opti = 0;
12946        while (opti < args.length) {
12947            String opt = args[opti];
12948            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12949                break;
12950            }
12951            opti++;
12952            if ("-a".equals(opt)) {
12953                dumpDetails = true;
12954                dumpFullDetails = true;
12955                dumpDalvik = true;
12956            } else if ("-d".equals(opt)) {
12957                dumpDalvik = true;
12958            } else if ("-c".equals(opt)) {
12959                isCompact = true;
12960            } else if ("--oom".equals(opt)) {
12961                oomOnly = true;
12962            } else if ("--local".equals(opt)) {
12963                localOnly = true;
12964            } else if ("-h".equals(opt)) {
12965                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12966                pw.println("  -a: include all available information for each process.");
12967                pw.println("  -d: include dalvik details when dumping process details.");
12968                pw.println("  -c: dump in a compact machine-parseable representation.");
12969                pw.println("  --oom: only show processes organized by oom adj.");
12970                pw.println("  --local: only collect details locally, don't call process.");
12971                pw.println("If [process] is specified it can be the name or ");
12972                pw.println("pid of a specific process to dump.");
12973                return;
12974            } else {
12975                pw.println("Unknown argument: " + opt + "; use -h for help");
12976            }
12977        }
12978
12979        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12980        long uptime = SystemClock.uptimeMillis();
12981        long realtime = SystemClock.elapsedRealtime();
12982        final long[] tmpLong = new long[1];
12983
12984        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12985        if (procs == null) {
12986            // No Java processes.  Maybe they want to print a native process.
12987            if (args != null && args.length > opti
12988                    && args[opti].charAt(0) != '-') {
12989                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12990                        = new ArrayList<ProcessCpuTracker.Stats>();
12991                updateCpuStatsNow();
12992                int findPid = -1;
12993                try {
12994                    findPid = Integer.parseInt(args[opti]);
12995                } catch (NumberFormatException e) {
12996                }
12997                synchronized (mProcessCpuThread) {
12998                    final int N = mProcessCpuTracker.countStats();
12999                    for (int i=0; i<N; i++) {
13000                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13001                        if (st.pid == findPid || (st.baseName != null
13002                                && st.baseName.equals(args[opti]))) {
13003                            nativeProcs.add(st);
13004                        }
13005                    }
13006                }
13007                if (nativeProcs.size() > 0) {
13008                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13009                            isCompact);
13010                    Debug.MemoryInfo mi = null;
13011                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13012                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13013                        final int pid = r.pid;
13014                        if (!isCheckinRequest && dumpDetails) {
13015                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13016                        }
13017                        if (mi == null) {
13018                            mi = new Debug.MemoryInfo();
13019                        }
13020                        if (dumpDetails || (!brief && !oomOnly)) {
13021                            Debug.getMemoryInfo(pid, mi);
13022                        } else {
13023                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13024                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13025                        }
13026                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13027                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13028                        if (isCheckinRequest) {
13029                            pw.println();
13030                        }
13031                    }
13032                    return;
13033                }
13034            }
13035            pw.println("No process found for: " + args[opti]);
13036            return;
13037        }
13038
13039        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13040            dumpDetails = true;
13041        }
13042
13043        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13044
13045        String[] innerArgs = new String[args.length-opti];
13046        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13047
13048        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13049        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13050        long nativePss=0, dalvikPss=0, otherPss=0;
13051        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13052
13053        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13054        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13055                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13056
13057        long totalPss = 0;
13058        long cachedPss = 0;
13059
13060        Debug.MemoryInfo mi = null;
13061        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13062            final ProcessRecord r = procs.get(i);
13063            final IApplicationThread thread;
13064            final int pid;
13065            final int oomAdj;
13066            final boolean hasActivities;
13067            synchronized (this) {
13068                thread = r.thread;
13069                pid = r.pid;
13070                oomAdj = r.getSetAdjWithServices();
13071                hasActivities = r.activities.size() > 0;
13072            }
13073            if (thread != null) {
13074                if (!isCheckinRequest && dumpDetails) {
13075                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13076                }
13077                if (mi == null) {
13078                    mi = new Debug.MemoryInfo();
13079                }
13080                if (dumpDetails || (!brief && !oomOnly)) {
13081                    Debug.getMemoryInfo(pid, mi);
13082                } else {
13083                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13084                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13085                }
13086                if (dumpDetails) {
13087                    if (localOnly) {
13088                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13089                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13090                        if (isCheckinRequest) {
13091                            pw.println();
13092                        }
13093                    } else {
13094                        try {
13095                            pw.flush();
13096                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13097                                    dumpDalvik, innerArgs);
13098                        } catch (RemoteException e) {
13099                            if (!isCheckinRequest) {
13100                                pw.println("Got RemoteException!");
13101                                pw.flush();
13102                            }
13103                        }
13104                    }
13105                }
13106
13107                final long myTotalPss = mi.getTotalPss();
13108                final long myTotalUss = mi.getTotalUss();
13109
13110                synchronized (this) {
13111                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13112                        // Record this for posterity if the process has been stable.
13113                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13114                    }
13115                }
13116
13117                if (!isCheckinRequest && mi != null) {
13118                    totalPss += myTotalPss;
13119                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13120                            (hasActivities ? " / activities)" : ")"),
13121                            r.processName, myTotalPss, pid, hasActivities);
13122                    procMems.add(pssItem);
13123                    procMemsMap.put(pid, pssItem);
13124
13125                    nativePss += mi.nativePss;
13126                    dalvikPss += mi.dalvikPss;
13127                    otherPss += mi.otherPss;
13128                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13129                        long mem = mi.getOtherPss(j);
13130                        miscPss[j] += mem;
13131                        otherPss -= mem;
13132                    }
13133
13134                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13135                        cachedPss += myTotalPss;
13136                    }
13137
13138                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13139                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13140                                || oomIndex == (oomPss.length-1)) {
13141                            oomPss[oomIndex] += myTotalPss;
13142                            if (oomProcs[oomIndex] == null) {
13143                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13144                            }
13145                            oomProcs[oomIndex].add(pssItem);
13146                            break;
13147                        }
13148                    }
13149                }
13150            }
13151        }
13152
13153        long nativeProcTotalPss = 0;
13154
13155        if (!isCheckinRequest && procs.size() > 1) {
13156            // If we are showing aggregations, also look for native processes to
13157            // include so that our aggregations are more accurate.
13158            updateCpuStatsNow();
13159            synchronized (mProcessCpuThread) {
13160                final int N = mProcessCpuTracker.countStats();
13161                for (int i=0; i<N; i++) {
13162                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13163                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13164                        if (mi == null) {
13165                            mi = new Debug.MemoryInfo();
13166                        }
13167                        if (!brief && !oomOnly) {
13168                            Debug.getMemoryInfo(st.pid, mi);
13169                        } else {
13170                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13171                            mi.nativePrivateDirty = (int)tmpLong[0];
13172                        }
13173
13174                        final long myTotalPss = mi.getTotalPss();
13175                        totalPss += myTotalPss;
13176                        nativeProcTotalPss += myTotalPss;
13177
13178                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13179                                st.name, myTotalPss, st.pid, false);
13180                        procMems.add(pssItem);
13181
13182                        nativePss += mi.nativePss;
13183                        dalvikPss += mi.dalvikPss;
13184                        otherPss += mi.otherPss;
13185                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13186                            long mem = mi.getOtherPss(j);
13187                            miscPss[j] += mem;
13188                            otherPss -= mem;
13189                        }
13190                        oomPss[0] += myTotalPss;
13191                        if (oomProcs[0] == null) {
13192                            oomProcs[0] = new ArrayList<MemItem>();
13193                        }
13194                        oomProcs[0].add(pssItem);
13195                    }
13196                }
13197            }
13198
13199            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13200
13201            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13202            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13203            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13204            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13205                String label = Debug.MemoryInfo.getOtherLabel(j);
13206                catMems.add(new MemItem(label, label, miscPss[j], j));
13207            }
13208
13209            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13210            for (int j=0; j<oomPss.length; j++) {
13211                if (oomPss[j] != 0) {
13212                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13213                            : DUMP_MEM_OOM_LABEL[j];
13214                    MemItem item = new MemItem(label, label, oomPss[j],
13215                            DUMP_MEM_OOM_ADJ[j]);
13216                    item.subitems = oomProcs[j];
13217                    oomMems.add(item);
13218                }
13219            }
13220
13221            if (!brief && !oomOnly && !isCompact) {
13222                pw.println();
13223                pw.println("Total PSS by process:");
13224                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13225                pw.println();
13226            }
13227            if (!isCompact) {
13228                pw.println("Total PSS by OOM adjustment:");
13229            }
13230            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13231            if (!brief && !oomOnly) {
13232                PrintWriter out = categoryPw != null ? categoryPw : pw;
13233                if (!isCompact) {
13234                    out.println();
13235                    out.println("Total PSS by category:");
13236                }
13237                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13238            }
13239            if (!isCompact) {
13240                pw.println();
13241            }
13242            MemInfoReader memInfo = new MemInfoReader();
13243            memInfo.readMemInfo();
13244            if (nativeProcTotalPss > 0) {
13245                synchronized (this) {
13246                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13247                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13248                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13249                            nativeProcTotalPss);
13250                }
13251            }
13252            if (!brief) {
13253                if (!isCompact) {
13254                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13255                    pw.print(" kB (status ");
13256                    switch (mLastMemoryLevel) {
13257                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13258                            pw.println("normal)");
13259                            break;
13260                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13261                            pw.println("moderate)");
13262                            break;
13263                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13264                            pw.println("low)");
13265                            break;
13266                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13267                            pw.println("critical)");
13268                            break;
13269                        default:
13270                            pw.print(mLastMemoryLevel);
13271                            pw.println(")");
13272                            break;
13273                    }
13274                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13275                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13276                            pw.print(cachedPss); pw.print(" cached pss + ");
13277                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13278                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13279                } else {
13280                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13281                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13282                            + memInfo.getFreeSizeKb()); pw.print(",");
13283                    pw.println(totalPss - cachedPss);
13284                }
13285            }
13286            if (!isCompact) {
13287                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13288                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13289                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13290                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13291                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13292                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13293                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13294                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13295                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13296                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13297                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13298            }
13299            if (!brief) {
13300                if (memInfo.getZramTotalSizeKb() != 0) {
13301                    if (!isCompact) {
13302                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13303                                pw.print(" kB physical used for ");
13304                                pw.print(memInfo.getSwapTotalSizeKb()
13305                                        - memInfo.getSwapFreeSizeKb());
13306                                pw.print(" kB in swap (");
13307                                pw.print(memInfo.getSwapTotalSizeKb());
13308                                pw.println(" kB total swap)");
13309                    } else {
13310                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13311                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13312                                pw.println(memInfo.getSwapFreeSizeKb());
13313                    }
13314                }
13315                final int[] SINGLE_LONG_FORMAT = new int[] {
13316                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13317                };
13318                long[] longOut = new long[1];
13319                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13320                        SINGLE_LONG_FORMAT, null, longOut, null);
13321                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13322                longOut[0] = 0;
13323                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13324                        SINGLE_LONG_FORMAT, null, longOut, null);
13325                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13326                longOut[0] = 0;
13327                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13328                        SINGLE_LONG_FORMAT, null, longOut, null);
13329                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13330                longOut[0] = 0;
13331                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13332                        SINGLE_LONG_FORMAT, null, longOut, null);
13333                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13334                if (!isCompact) {
13335                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13336                        pw.print("      KSM: "); pw.print(sharing);
13337                                pw.print(" kB saved from shared ");
13338                                pw.print(shared); pw.println(" kB");
13339                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13340                                pw.print(voltile); pw.println(" kB volatile");
13341                    }
13342                    pw.print("   Tuning: ");
13343                    pw.print(ActivityManager.staticGetMemoryClass());
13344                    pw.print(" (large ");
13345                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13346                    pw.print("), oom ");
13347                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13348                    pw.print(" kB");
13349                    pw.print(", restore limit ");
13350                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13351                    pw.print(" kB");
13352                    if (ActivityManager.isLowRamDeviceStatic()) {
13353                        pw.print(" (low-ram)");
13354                    }
13355                    if (ActivityManager.isHighEndGfx()) {
13356                        pw.print(" (high-end-gfx)");
13357                    }
13358                    pw.println();
13359                } else {
13360                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13361                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13362                    pw.println(voltile);
13363                    pw.print("tuning,");
13364                    pw.print(ActivityManager.staticGetMemoryClass());
13365                    pw.print(',');
13366                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13367                    pw.print(',');
13368                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13369                    if (ActivityManager.isLowRamDeviceStatic()) {
13370                        pw.print(",low-ram");
13371                    }
13372                    if (ActivityManager.isHighEndGfx()) {
13373                        pw.print(",high-end-gfx");
13374                    }
13375                    pw.println();
13376                }
13377            }
13378        }
13379    }
13380
13381    /**
13382     * Searches array of arguments for the specified string
13383     * @param args array of argument strings
13384     * @param value value to search for
13385     * @return true if the value is contained in the array
13386     */
13387    private static boolean scanArgs(String[] args, String value) {
13388        if (args != null) {
13389            for (String arg : args) {
13390                if (value.equals(arg)) {
13391                    return true;
13392                }
13393            }
13394        }
13395        return false;
13396    }
13397
13398    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13399            ContentProviderRecord cpr, boolean always) {
13400        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13401
13402        if (!inLaunching || always) {
13403            synchronized (cpr) {
13404                cpr.launchingApp = null;
13405                cpr.notifyAll();
13406            }
13407            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13408            String names[] = cpr.info.authority.split(";");
13409            for (int j = 0; j < names.length; j++) {
13410                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13411            }
13412        }
13413
13414        for (int i=0; i<cpr.connections.size(); i++) {
13415            ContentProviderConnection conn = cpr.connections.get(i);
13416            if (conn.waiting) {
13417                // If this connection is waiting for the provider, then we don't
13418                // need to mess with its process unless we are always removing
13419                // or for some reason the provider is not currently launching.
13420                if (inLaunching && !always) {
13421                    continue;
13422                }
13423            }
13424            ProcessRecord capp = conn.client;
13425            conn.dead = true;
13426            if (conn.stableCount > 0) {
13427                if (!capp.persistent && capp.thread != null
13428                        && capp.pid != 0
13429                        && capp.pid != MY_PID) {
13430                    killUnneededProcessLocked(capp, "depends on provider "
13431                            + cpr.name.flattenToShortString()
13432                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13433                }
13434            } else if (capp.thread != null && conn.provider.provider != null) {
13435                try {
13436                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13437                } catch (RemoteException e) {
13438                }
13439                // In the protocol here, we don't expect the client to correctly
13440                // clean up this connection, we'll just remove it.
13441                cpr.connections.remove(i);
13442                conn.client.conProviders.remove(conn);
13443            }
13444        }
13445
13446        if (inLaunching && always) {
13447            mLaunchingProviders.remove(cpr);
13448        }
13449        return inLaunching;
13450    }
13451
13452    /**
13453     * Main code for cleaning up a process when it has gone away.  This is
13454     * called both as a result of the process dying, or directly when stopping
13455     * a process when running in single process mode.
13456     */
13457    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13458            boolean restarting, boolean allowRestart, int index) {
13459        if (index >= 0) {
13460            removeLruProcessLocked(app);
13461            ProcessList.remove(app.pid);
13462        }
13463
13464        mProcessesToGc.remove(app);
13465        mPendingPssProcesses.remove(app);
13466
13467        // Dismiss any open dialogs.
13468        if (app.crashDialog != null && !app.forceCrashReport) {
13469            app.crashDialog.dismiss();
13470            app.crashDialog = null;
13471        }
13472        if (app.anrDialog != null) {
13473            app.anrDialog.dismiss();
13474            app.anrDialog = null;
13475        }
13476        if (app.waitDialog != null) {
13477            app.waitDialog.dismiss();
13478            app.waitDialog = null;
13479        }
13480
13481        app.crashing = false;
13482        app.notResponding = false;
13483
13484        app.resetPackageList(mProcessStats);
13485        app.unlinkDeathRecipient();
13486        app.makeInactive(mProcessStats);
13487        app.waitingToKill = null;
13488        app.forcingToForeground = null;
13489        updateProcessForegroundLocked(app, false, false);
13490        app.foregroundActivities = false;
13491        app.hasShownUi = false;
13492        app.treatLikeActivity = false;
13493        app.hasAboveClient = false;
13494        app.hasClientActivities = false;
13495
13496        mServices.killServicesLocked(app, allowRestart);
13497
13498        boolean restart = false;
13499
13500        // Remove published content providers.
13501        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13502            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13503            final boolean always = app.bad || !allowRestart;
13504            if (removeDyingProviderLocked(app, cpr, always) || always) {
13505                // We left the provider in the launching list, need to
13506                // restart it.
13507                restart = true;
13508            }
13509
13510            cpr.provider = null;
13511            cpr.proc = null;
13512        }
13513        app.pubProviders.clear();
13514
13515        // Take care of any launching providers waiting for this process.
13516        if (checkAppInLaunchingProvidersLocked(app, false)) {
13517            restart = true;
13518        }
13519
13520        // Unregister from connected content providers.
13521        if (!app.conProviders.isEmpty()) {
13522            for (int i=0; i<app.conProviders.size(); i++) {
13523                ContentProviderConnection conn = app.conProviders.get(i);
13524                conn.provider.connections.remove(conn);
13525            }
13526            app.conProviders.clear();
13527        }
13528
13529        // At this point there may be remaining entries in mLaunchingProviders
13530        // where we were the only one waiting, so they are no longer of use.
13531        // Look for these and clean up if found.
13532        // XXX Commented out for now.  Trying to figure out a way to reproduce
13533        // the actual situation to identify what is actually going on.
13534        if (false) {
13535            for (int i=0; i<mLaunchingProviders.size(); i++) {
13536                ContentProviderRecord cpr = (ContentProviderRecord)
13537                        mLaunchingProviders.get(i);
13538                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13539                    synchronized (cpr) {
13540                        cpr.launchingApp = null;
13541                        cpr.notifyAll();
13542                    }
13543                }
13544            }
13545        }
13546
13547        skipCurrentReceiverLocked(app);
13548
13549        // Unregister any receivers.
13550        for (int i=app.receivers.size()-1; i>=0; i--) {
13551            removeReceiverLocked(app.receivers.valueAt(i));
13552        }
13553        app.receivers.clear();
13554
13555        // If the app is undergoing backup, tell the backup manager about it
13556        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13557            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13558                    + mBackupTarget.appInfo + " died during backup");
13559            try {
13560                IBackupManager bm = IBackupManager.Stub.asInterface(
13561                        ServiceManager.getService(Context.BACKUP_SERVICE));
13562                bm.agentDisconnected(app.info.packageName);
13563            } catch (RemoteException e) {
13564                // can't happen; backup manager is local
13565            }
13566        }
13567
13568        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13569            ProcessChangeItem item = mPendingProcessChanges.get(i);
13570            if (item.pid == app.pid) {
13571                mPendingProcessChanges.remove(i);
13572                mAvailProcessChanges.add(item);
13573            }
13574        }
13575        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13576
13577        // If the caller is restarting this app, then leave it in its
13578        // current lists and let the caller take care of it.
13579        if (restarting) {
13580            return;
13581        }
13582
13583        if (!app.persistent || app.isolated) {
13584            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13585                    "Removing non-persistent process during cleanup: " + app);
13586            mProcessNames.remove(app.processName, app.uid);
13587            mIsolatedProcesses.remove(app.uid);
13588            if (mHeavyWeightProcess == app) {
13589                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13590                        mHeavyWeightProcess.userId, 0));
13591                mHeavyWeightProcess = null;
13592            }
13593        } else if (!app.removed) {
13594            // This app is persistent, so we need to keep its record around.
13595            // If it is not already on the pending app list, add it there
13596            // and start a new process for it.
13597            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13598                mPersistentStartingProcesses.add(app);
13599                restart = true;
13600            }
13601        }
13602        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13603                "Clean-up removing on hold: " + app);
13604        mProcessesOnHold.remove(app);
13605
13606        if (app == mHomeProcess) {
13607            mHomeProcess = null;
13608        }
13609        if (app == mPreviousProcess) {
13610            mPreviousProcess = null;
13611        }
13612
13613        if (restart && !app.isolated) {
13614            // We have components that still need to be running in the
13615            // process, so re-launch it.
13616            mProcessNames.put(app.processName, app.uid, app);
13617            startProcessLocked(app, "restart", app.processName);
13618        } else if (app.pid > 0 && app.pid != MY_PID) {
13619            // Goodbye!
13620            boolean removed;
13621            synchronized (mPidsSelfLocked) {
13622                mPidsSelfLocked.remove(app.pid);
13623                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13624            }
13625            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13626            if (app.isolated) {
13627                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13628            }
13629            app.setPid(0);
13630        }
13631    }
13632
13633    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13634        // Look through the content providers we are waiting to have launched,
13635        // and if any run in this process then either schedule a restart of
13636        // the process or kill the client waiting for it if this process has
13637        // gone bad.
13638        int NL = mLaunchingProviders.size();
13639        boolean restart = false;
13640        for (int i=0; i<NL; i++) {
13641            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13642            if (cpr.launchingApp == app) {
13643                if (!alwaysBad && !app.bad) {
13644                    restart = true;
13645                } else {
13646                    removeDyingProviderLocked(app, cpr, true);
13647                    // cpr should have been removed from mLaunchingProviders
13648                    NL = mLaunchingProviders.size();
13649                    i--;
13650                }
13651            }
13652        }
13653        return restart;
13654    }
13655
13656    // =========================================================
13657    // SERVICES
13658    // =========================================================
13659
13660    @Override
13661    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13662            int flags) {
13663        enforceNotIsolatedCaller("getServices");
13664        synchronized (this) {
13665            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13666        }
13667    }
13668
13669    @Override
13670    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13671        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13672        synchronized (this) {
13673            return mServices.getRunningServiceControlPanelLocked(name);
13674        }
13675    }
13676
13677    @Override
13678    public ComponentName startService(IApplicationThread caller, Intent service,
13679            String resolvedType, int userId) {
13680        enforceNotIsolatedCaller("startService");
13681        // Refuse possible leaked file descriptors
13682        if (service != null && service.hasFileDescriptors() == true) {
13683            throw new IllegalArgumentException("File descriptors passed in Intent");
13684        }
13685
13686        if (DEBUG_SERVICE)
13687            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13688        synchronized(this) {
13689            final int callingPid = Binder.getCallingPid();
13690            final int callingUid = Binder.getCallingUid();
13691            final long origId = Binder.clearCallingIdentity();
13692            ComponentName res = mServices.startServiceLocked(caller, service,
13693                    resolvedType, callingPid, callingUid, userId);
13694            Binder.restoreCallingIdentity(origId);
13695            return res;
13696        }
13697    }
13698
13699    ComponentName startServiceInPackage(int uid,
13700            Intent service, String resolvedType, int userId) {
13701        synchronized(this) {
13702            if (DEBUG_SERVICE)
13703                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13704            final long origId = Binder.clearCallingIdentity();
13705            ComponentName res = mServices.startServiceLocked(null, service,
13706                    resolvedType, -1, uid, userId);
13707            Binder.restoreCallingIdentity(origId);
13708            return res;
13709        }
13710    }
13711
13712    @Override
13713    public int stopService(IApplicationThread caller, Intent service,
13714            String resolvedType, int userId) {
13715        enforceNotIsolatedCaller("stopService");
13716        // Refuse possible leaked file descriptors
13717        if (service != null && service.hasFileDescriptors() == true) {
13718            throw new IllegalArgumentException("File descriptors passed in Intent");
13719        }
13720
13721        synchronized(this) {
13722            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13723        }
13724    }
13725
13726    @Override
13727    public IBinder peekService(Intent service, String resolvedType) {
13728        enforceNotIsolatedCaller("peekService");
13729        // Refuse possible leaked file descriptors
13730        if (service != null && service.hasFileDescriptors() == true) {
13731            throw new IllegalArgumentException("File descriptors passed in Intent");
13732        }
13733        synchronized(this) {
13734            return mServices.peekServiceLocked(service, resolvedType);
13735        }
13736    }
13737
13738    @Override
13739    public boolean stopServiceToken(ComponentName className, IBinder token,
13740            int startId) {
13741        synchronized(this) {
13742            return mServices.stopServiceTokenLocked(className, token, startId);
13743        }
13744    }
13745
13746    @Override
13747    public void setServiceForeground(ComponentName className, IBinder token,
13748            int id, Notification notification, boolean removeNotification) {
13749        synchronized(this) {
13750            mServices.setServiceForegroundLocked(className, token, id, notification,
13751                    removeNotification);
13752        }
13753    }
13754
13755    @Override
13756    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13757            boolean requireFull, String name, String callerPackage) {
13758        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13759                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13760    }
13761
13762    int unsafeConvertIncomingUser(int userId) {
13763        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13764                ? mCurrentUserId : userId;
13765    }
13766
13767    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13768            int allowMode, String name, String callerPackage) {
13769        final int callingUserId = UserHandle.getUserId(callingUid);
13770        if (callingUserId == userId) {
13771            return userId;
13772        }
13773
13774        // Note that we may be accessing mCurrentUserId outside of a lock...
13775        // shouldn't be a big deal, if this is being called outside
13776        // of a locked context there is intrinsically a race with
13777        // the value the caller will receive and someone else changing it.
13778        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13779        // we will switch to the calling user if access to the current user fails.
13780        int targetUserId = unsafeConvertIncomingUser(userId);
13781
13782        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13783            final boolean allow;
13784            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13785                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13786                // If the caller has this permission, they always pass go.  And collect $200.
13787                allow = true;
13788            } else if (allowMode == ALLOW_FULL_ONLY) {
13789                // We require full access, sucks to be you.
13790                allow = false;
13791            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13792                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13793                // If the caller does not have either permission, they are always doomed.
13794                allow = false;
13795            } else if (allowMode == ALLOW_NON_FULL) {
13796                // We are blanket allowing non-full access, you lucky caller!
13797                allow = true;
13798            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13799                // We may or may not allow this depending on whether the two users are
13800                // in the same profile.
13801                synchronized (mUserProfileGroupIdsSelfLocked) {
13802                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13803                            UserInfo.NO_PROFILE_GROUP_ID);
13804                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13805                            UserInfo.NO_PROFILE_GROUP_ID);
13806                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13807                            && callingProfile == targetProfile;
13808                }
13809            } else {
13810                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13811            }
13812            if (!allow) {
13813                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13814                    // In this case, they would like to just execute as their
13815                    // owner user instead of failing.
13816                    targetUserId = callingUserId;
13817                } else {
13818                    StringBuilder builder = new StringBuilder(128);
13819                    builder.append("Permission Denial: ");
13820                    builder.append(name);
13821                    if (callerPackage != null) {
13822                        builder.append(" from ");
13823                        builder.append(callerPackage);
13824                    }
13825                    builder.append(" asks to run as user ");
13826                    builder.append(userId);
13827                    builder.append(" but is calling from user ");
13828                    builder.append(UserHandle.getUserId(callingUid));
13829                    builder.append("; this requires ");
13830                    builder.append(INTERACT_ACROSS_USERS_FULL);
13831                    if (allowMode != ALLOW_FULL_ONLY) {
13832                        builder.append(" or ");
13833                        builder.append(INTERACT_ACROSS_USERS);
13834                    }
13835                    String msg = builder.toString();
13836                    Slog.w(TAG, msg);
13837                    throw new SecurityException(msg);
13838                }
13839            }
13840        }
13841        if (!allowAll && targetUserId < 0) {
13842            throw new IllegalArgumentException(
13843                    "Call does not support special user #" + targetUserId);
13844        }
13845        return targetUserId;
13846    }
13847
13848    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13849            String className, int flags) {
13850        boolean result = false;
13851        // For apps that don't have pre-defined UIDs, check for permission
13852        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13853            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13854                if (ActivityManager.checkUidPermission(
13855                        INTERACT_ACROSS_USERS,
13856                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13857                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13858                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13859                            + " requests FLAG_SINGLE_USER, but app does not hold "
13860                            + INTERACT_ACROSS_USERS;
13861                    Slog.w(TAG, msg);
13862                    throw new SecurityException(msg);
13863                }
13864                // Permission passed
13865                result = true;
13866            }
13867        } else if ("system".equals(componentProcessName)) {
13868            result = true;
13869        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
13870                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13871            // Phone app is allowed to export singleuser providers.
13872            result = true;
13873        } else {
13874            // App with pre-defined UID, check if it's a persistent app
13875            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13876        }
13877        if (DEBUG_MU) {
13878            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13879                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13880        }
13881        return result;
13882    }
13883
13884    /**
13885     * Checks to see if the caller is in the same app as the singleton
13886     * component, or the component is in a special app. It allows special apps
13887     * to export singleton components but prevents exporting singleton
13888     * components for regular apps.
13889     */
13890    boolean isValidSingletonCall(int callingUid, int componentUid) {
13891        int componentAppId = UserHandle.getAppId(componentUid);
13892        return UserHandle.isSameApp(callingUid, componentUid)
13893                || componentAppId == Process.SYSTEM_UID
13894                || componentAppId == Process.PHONE_UID
13895                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13896                        == PackageManager.PERMISSION_GRANTED;
13897    }
13898
13899    public int bindService(IApplicationThread caller, IBinder token,
13900            Intent service, String resolvedType,
13901            IServiceConnection connection, int flags, int userId) {
13902        enforceNotIsolatedCaller("bindService");
13903        // Refuse possible leaked file descriptors
13904        if (service != null && service.hasFileDescriptors() == true) {
13905            throw new IllegalArgumentException("File descriptors passed in Intent");
13906        }
13907
13908        synchronized(this) {
13909            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13910                    connection, flags, userId);
13911        }
13912    }
13913
13914    public boolean unbindService(IServiceConnection connection) {
13915        synchronized (this) {
13916            return mServices.unbindServiceLocked(connection);
13917        }
13918    }
13919
13920    public void publishService(IBinder token, Intent intent, IBinder service) {
13921        // Refuse possible leaked file descriptors
13922        if (intent != null && intent.hasFileDescriptors() == true) {
13923            throw new IllegalArgumentException("File descriptors passed in Intent");
13924        }
13925
13926        synchronized(this) {
13927            if (!(token instanceof ServiceRecord)) {
13928                throw new IllegalArgumentException("Invalid service token");
13929            }
13930            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13931        }
13932    }
13933
13934    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13935        // Refuse possible leaked file descriptors
13936        if (intent != null && intent.hasFileDescriptors() == true) {
13937            throw new IllegalArgumentException("File descriptors passed in Intent");
13938        }
13939
13940        synchronized(this) {
13941            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13942        }
13943    }
13944
13945    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13946        synchronized(this) {
13947            if (!(token instanceof ServiceRecord)) {
13948                throw new IllegalArgumentException("Invalid service token");
13949            }
13950            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13951        }
13952    }
13953
13954    // =========================================================
13955    // BACKUP AND RESTORE
13956    // =========================================================
13957
13958    // Cause the target app to be launched if necessary and its backup agent
13959    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13960    // activity manager to announce its creation.
13961    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13962        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13963        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13964
13965        synchronized(this) {
13966            // !!! TODO: currently no check here that we're already bound
13967            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13968            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13969            synchronized (stats) {
13970                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13971            }
13972
13973            // Backup agent is now in use, its package can't be stopped.
13974            try {
13975                AppGlobals.getPackageManager().setPackageStoppedState(
13976                        app.packageName, false, UserHandle.getUserId(app.uid));
13977            } catch (RemoteException e) {
13978            } catch (IllegalArgumentException e) {
13979                Slog.w(TAG, "Failed trying to unstop package "
13980                        + app.packageName + ": " + e);
13981            }
13982
13983            BackupRecord r = new BackupRecord(ss, app, backupMode);
13984            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13985                    ? new ComponentName(app.packageName, app.backupAgentName)
13986                    : new ComponentName("android", "FullBackupAgent");
13987            // startProcessLocked() returns existing proc's record if it's already running
13988            ProcessRecord proc = startProcessLocked(app.processName, app,
13989                    false, 0, "backup", hostingName, false, false, false);
13990            if (proc == null) {
13991                Slog.e(TAG, "Unable to start backup agent process " + r);
13992                return false;
13993            }
13994
13995            r.app = proc;
13996            mBackupTarget = r;
13997            mBackupAppName = app.packageName;
13998
13999            // Try not to kill the process during backup
14000            updateOomAdjLocked(proc);
14001
14002            // If the process is already attached, schedule the creation of the backup agent now.
14003            // If it is not yet live, this will be done when it attaches to the framework.
14004            if (proc.thread != null) {
14005                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14006                try {
14007                    proc.thread.scheduleCreateBackupAgent(app,
14008                            compatibilityInfoForPackageLocked(app), backupMode);
14009                } catch (RemoteException e) {
14010                    // Will time out on the backup manager side
14011                }
14012            } else {
14013                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14014            }
14015            // Invariants: at this point, the target app process exists and the application
14016            // is either already running or in the process of coming up.  mBackupTarget and
14017            // mBackupAppName describe the app, so that when it binds back to the AM we
14018            // know that it's scheduled for a backup-agent operation.
14019        }
14020
14021        return true;
14022    }
14023
14024    @Override
14025    public void clearPendingBackup() {
14026        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14027        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14028
14029        synchronized (this) {
14030            mBackupTarget = null;
14031            mBackupAppName = null;
14032        }
14033    }
14034
14035    // A backup agent has just come up
14036    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14037        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14038                + " = " + agent);
14039
14040        synchronized(this) {
14041            if (!agentPackageName.equals(mBackupAppName)) {
14042                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14043                return;
14044            }
14045        }
14046
14047        long oldIdent = Binder.clearCallingIdentity();
14048        try {
14049            IBackupManager bm = IBackupManager.Stub.asInterface(
14050                    ServiceManager.getService(Context.BACKUP_SERVICE));
14051            bm.agentConnected(agentPackageName, agent);
14052        } catch (RemoteException e) {
14053            // can't happen; the backup manager service is local
14054        } catch (Exception e) {
14055            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14056            e.printStackTrace();
14057        } finally {
14058            Binder.restoreCallingIdentity(oldIdent);
14059        }
14060    }
14061
14062    // done with this agent
14063    public void unbindBackupAgent(ApplicationInfo appInfo) {
14064        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14065        if (appInfo == null) {
14066            Slog.w(TAG, "unbind backup agent for null app");
14067            return;
14068        }
14069
14070        synchronized(this) {
14071            try {
14072                if (mBackupAppName == null) {
14073                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14074                    return;
14075                }
14076
14077                if (!mBackupAppName.equals(appInfo.packageName)) {
14078                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14079                    return;
14080                }
14081
14082                // Not backing this app up any more; reset its OOM adjustment
14083                final ProcessRecord proc = mBackupTarget.app;
14084                updateOomAdjLocked(proc);
14085
14086                // If the app crashed during backup, 'thread' will be null here
14087                if (proc.thread != null) {
14088                    try {
14089                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14090                                compatibilityInfoForPackageLocked(appInfo));
14091                    } catch (Exception e) {
14092                        Slog.e(TAG, "Exception when unbinding backup agent:");
14093                        e.printStackTrace();
14094                    }
14095                }
14096            } finally {
14097                mBackupTarget = null;
14098                mBackupAppName = null;
14099            }
14100        }
14101    }
14102    // =========================================================
14103    // BROADCASTS
14104    // =========================================================
14105
14106    private final List getStickiesLocked(String action, IntentFilter filter,
14107            List cur, int userId) {
14108        final ContentResolver resolver = mContext.getContentResolver();
14109        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14110        if (stickies == null) {
14111            return cur;
14112        }
14113        final ArrayList<Intent> list = stickies.get(action);
14114        if (list == null) {
14115            return cur;
14116        }
14117        int N = list.size();
14118        for (int i=0; i<N; i++) {
14119            Intent intent = list.get(i);
14120            if (filter.match(resolver, intent, true, TAG) >= 0) {
14121                if (cur == null) {
14122                    cur = new ArrayList<Intent>();
14123                }
14124                cur.add(intent);
14125            }
14126        }
14127        return cur;
14128    }
14129
14130    boolean isPendingBroadcastProcessLocked(int pid) {
14131        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14132                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14133    }
14134
14135    void skipPendingBroadcastLocked(int pid) {
14136            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14137            for (BroadcastQueue queue : mBroadcastQueues) {
14138                queue.skipPendingBroadcastLocked(pid);
14139            }
14140    }
14141
14142    // The app just attached; send any pending broadcasts that it should receive
14143    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14144        boolean didSomething = false;
14145        for (BroadcastQueue queue : mBroadcastQueues) {
14146            didSomething |= queue.sendPendingBroadcastsLocked(app);
14147        }
14148        return didSomething;
14149    }
14150
14151    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14152            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14153        enforceNotIsolatedCaller("registerReceiver");
14154        int callingUid;
14155        int callingPid;
14156        synchronized(this) {
14157            ProcessRecord callerApp = null;
14158            if (caller != null) {
14159                callerApp = getRecordForAppLocked(caller);
14160                if (callerApp == null) {
14161                    throw new SecurityException(
14162                            "Unable to find app for caller " + caller
14163                            + " (pid=" + Binder.getCallingPid()
14164                            + ") when registering receiver " + receiver);
14165                }
14166                if (callerApp.info.uid != Process.SYSTEM_UID &&
14167                        !callerApp.pkgList.containsKey(callerPackage) &&
14168                        !"android".equals(callerPackage)) {
14169                    throw new SecurityException("Given caller package " + callerPackage
14170                            + " is not running in process " + callerApp);
14171                }
14172                callingUid = callerApp.info.uid;
14173                callingPid = callerApp.pid;
14174            } else {
14175                callerPackage = null;
14176                callingUid = Binder.getCallingUid();
14177                callingPid = Binder.getCallingPid();
14178            }
14179
14180            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14181                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14182
14183            List allSticky = null;
14184
14185            // Look for any matching sticky broadcasts...
14186            Iterator actions = filter.actionsIterator();
14187            if (actions != null) {
14188                while (actions.hasNext()) {
14189                    String action = (String)actions.next();
14190                    allSticky = getStickiesLocked(action, filter, allSticky,
14191                            UserHandle.USER_ALL);
14192                    allSticky = getStickiesLocked(action, filter, allSticky,
14193                            UserHandle.getUserId(callingUid));
14194                }
14195            } else {
14196                allSticky = getStickiesLocked(null, filter, allSticky,
14197                        UserHandle.USER_ALL);
14198                allSticky = getStickiesLocked(null, filter, allSticky,
14199                        UserHandle.getUserId(callingUid));
14200            }
14201
14202            // The first sticky in the list is returned directly back to
14203            // the client.
14204            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14205
14206            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14207                    + ": " + sticky);
14208
14209            if (receiver == null) {
14210                return sticky;
14211            }
14212
14213            ReceiverList rl
14214                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14215            if (rl == null) {
14216                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14217                        userId, receiver);
14218                if (rl.app != null) {
14219                    rl.app.receivers.add(rl);
14220                } else {
14221                    try {
14222                        receiver.asBinder().linkToDeath(rl, 0);
14223                    } catch (RemoteException e) {
14224                        return sticky;
14225                    }
14226                    rl.linkedToDeath = true;
14227                }
14228                mRegisteredReceivers.put(receiver.asBinder(), rl);
14229            } else if (rl.uid != callingUid) {
14230                throw new IllegalArgumentException(
14231                        "Receiver requested to register for uid " + callingUid
14232                        + " was previously registered for uid " + rl.uid);
14233            } else if (rl.pid != callingPid) {
14234                throw new IllegalArgumentException(
14235                        "Receiver requested to register for pid " + callingPid
14236                        + " was previously registered for pid " + rl.pid);
14237            } else if (rl.userId != userId) {
14238                throw new IllegalArgumentException(
14239                        "Receiver requested to register for user " + userId
14240                        + " was previously registered for user " + rl.userId);
14241            }
14242            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14243                    permission, callingUid, userId);
14244            rl.add(bf);
14245            if (!bf.debugCheck()) {
14246                Slog.w(TAG, "==> For Dynamic broadast");
14247            }
14248            mReceiverResolver.addFilter(bf);
14249
14250            // Enqueue broadcasts for all existing stickies that match
14251            // this filter.
14252            if (allSticky != null) {
14253                ArrayList receivers = new ArrayList();
14254                receivers.add(bf);
14255
14256                int N = allSticky.size();
14257                for (int i=0; i<N; i++) {
14258                    Intent intent = (Intent)allSticky.get(i);
14259                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14260                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14261                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14262                            null, null, false, true, true, -1);
14263                    queue.enqueueParallelBroadcastLocked(r);
14264                    queue.scheduleBroadcastsLocked();
14265                }
14266            }
14267
14268            return sticky;
14269        }
14270    }
14271
14272    public void unregisterReceiver(IIntentReceiver receiver) {
14273        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14274
14275        final long origId = Binder.clearCallingIdentity();
14276        try {
14277            boolean doTrim = false;
14278
14279            synchronized(this) {
14280                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14281                if (rl != null) {
14282                    if (rl.curBroadcast != null) {
14283                        BroadcastRecord r = rl.curBroadcast;
14284                        final boolean doNext = finishReceiverLocked(
14285                                receiver.asBinder(), r.resultCode, r.resultData,
14286                                r.resultExtras, r.resultAbort);
14287                        if (doNext) {
14288                            doTrim = true;
14289                            r.queue.processNextBroadcast(false);
14290                        }
14291                    }
14292
14293                    if (rl.app != null) {
14294                        rl.app.receivers.remove(rl);
14295                    }
14296                    removeReceiverLocked(rl);
14297                    if (rl.linkedToDeath) {
14298                        rl.linkedToDeath = false;
14299                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14300                    }
14301                }
14302            }
14303
14304            // If we actually concluded any broadcasts, we might now be able
14305            // to trim the recipients' apps from our working set
14306            if (doTrim) {
14307                trimApplications();
14308                return;
14309            }
14310
14311        } finally {
14312            Binder.restoreCallingIdentity(origId);
14313        }
14314    }
14315
14316    void removeReceiverLocked(ReceiverList rl) {
14317        mRegisteredReceivers.remove(rl.receiver.asBinder());
14318        int N = rl.size();
14319        for (int i=0; i<N; i++) {
14320            mReceiverResolver.removeFilter(rl.get(i));
14321        }
14322    }
14323
14324    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14325        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14326            ProcessRecord r = mLruProcesses.get(i);
14327            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14328                try {
14329                    r.thread.dispatchPackageBroadcast(cmd, packages);
14330                } catch (RemoteException ex) {
14331                }
14332            }
14333        }
14334    }
14335
14336    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14337            int[] users) {
14338        List<ResolveInfo> receivers = null;
14339        try {
14340            HashSet<ComponentName> singleUserReceivers = null;
14341            boolean scannedFirstReceivers = false;
14342            for (int user : users) {
14343                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14344                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14345                if (user != 0 && newReceivers != null) {
14346                    // If this is not the primary user, we need to check for
14347                    // any receivers that should be filtered out.
14348                    for (int i=0; i<newReceivers.size(); i++) {
14349                        ResolveInfo ri = newReceivers.get(i);
14350                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14351                            newReceivers.remove(i);
14352                            i--;
14353                        }
14354                    }
14355                }
14356                if (newReceivers != null && newReceivers.size() == 0) {
14357                    newReceivers = null;
14358                }
14359                if (receivers == null) {
14360                    receivers = newReceivers;
14361                } else if (newReceivers != null) {
14362                    // We need to concatenate the additional receivers
14363                    // found with what we have do far.  This would be easy,
14364                    // but we also need to de-dup any receivers that are
14365                    // singleUser.
14366                    if (!scannedFirstReceivers) {
14367                        // Collect any single user receivers we had already retrieved.
14368                        scannedFirstReceivers = true;
14369                        for (int i=0; i<receivers.size(); i++) {
14370                            ResolveInfo ri = receivers.get(i);
14371                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14372                                ComponentName cn = new ComponentName(
14373                                        ri.activityInfo.packageName, ri.activityInfo.name);
14374                                if (singleUserReceivers == null) {
14375                                    singleUserReceivers = new HashSet<ComponentName>();
14376                                }
14377                                singleUserReceivers.add(cn);
14378                            }
14379                        }
14380                    }
14381                    // Add the new results to the existing results, tracking
14382                    // and de-dupping single user receivers.
14383                    for (int i=0; i<newReceivers.size(); i++) {
14384                        ResolveInfo ri = newReceivers.get(i);
14385                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14386                            ComponentName cn = new ComponentName(
14387                                    ri.activityInfo.packageName, ri.activityInfo.name);
14388                            if (singleUserReceivers == null) {
14389                                singleUserReceivers = new HashSet<ComponentName>();
14390                            }
14391                            if (!singleUserReceivers.contains(cn)) {
14392                                singleUserReceivers.add(cn);
14393                                receivers.add(ri);
14394                            }
14395                        } else {
14396                            receivers.add(ri);
14397                        }
14398                    }
14399                }
14400            }
14401        } catch (RemoteException ex) {
14402            // pm is in same process, this will never happen.
14403        }
14404        return receivers;
14405    }
14406
14407    private final int broadcastIntentLocked(ProcessRecord callerApp,
14408            String callerPackage, Intent intent, String resolvedType,
14409            IIntentReceiver resultTo, int resultCode, String resultData,
14410            Bundle map, String requiredPermission, int appOp,
14411            boolean ordered, boolean sticky, int callingPid, int callingUid,
14412            int userId) {
14413        intent = new Intent(intent);
14414
14415        // By default broadcasts do not go to stopped apps.
14416        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14417
14418        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14419            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14420            + " ordered=" + ordered + " userid=" + userId);
14421        if ((resultTo != null) && !ordered) {
14422            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14423        }
14424
14425        userId = handleIncomingUser(callingPid, callingUid, userId,
14426                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14427
14428        // Make sure that the user who is receiving this broadcast is started.
14429        // If not, we will just skip it.
14430
14431
14432        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14433            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14434                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14435                Slog.w(TAG, "Skipping broadcast of " + intent
14436                        + ": user " + userId + " is stopped");
14437                return ActivityManager.BROADCAST_SUCCESS;
14438            }
14439        }
14440
14441        /*
14442         * Prevent non-system code (defined here to be non-persistent
14443         * processes) from sending protected broadcasts.
14444         */
14445        int callingAppId = UserHandle.getAppId(callingUid);
14446        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14447            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14448            || callingAppId == Process.NFC_UID || callingUid == 0) {
14449            // Always okay.
14450        } else if (callerApp == null || !callerApp.persistent) {
14451            try {
14452                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14453                        intent.getAction())) {
14454                    String msg = "Permission Denial: not allowed to send broadcast "
14455                            + intent.getAction() + " from pid="
14456                            + callingPid + ", uid=" + callingUid;
14457                    Slog.w(TAG, msg);
14458                    throw new SecurityException(msg);
14459                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14460                    // Special case for compatibility: we don't want apps to send this,
14461                    // but historically it has not been protected and apps may be using it
14462                    // to poke their own app widget.  So, instead of making it protected,
14463                    // just limit it to the caller.
14464                    if (callerApp == null) {
14465                        String msg = "Permission Denial: not allowed to send broadcast "
14466                                + intent.getAction() + " from unknown caller.";
14467                        Slog.w(TAG, msg);
14468                        throw new SecurityException(msg);
14469                    } else if (intent.getComponent() != null) {
14470                        // They are good enough to send to an explicit component...  verify
14471                        // it is being sent to the calling app.
14472                        if (!intent.getComponent().getPackageName().equals(
14473                                callerApp.info.packageName)) {
14474                            String msg = "Permission Denial: not allowed to send broadcast "
14475                                    + intent.getAction() + " to "
14476                                    + intent.getComponent().getPackageName() + " from "
14477                                    + callerApp.info.packageName;
14478                            Slog.w(TAG, msg);
14479                            throw new SecurityException(msg);
14480                        }
14481                    } else {
14482                        // Limit broadcast to their own package.
14483                        intent.setPackage(callerApp.info.packageName);
14484                    }
14485                }
14486            } catch (RemoteException e) {
14487                Slog.w(TAG, "Remote exception", e);
14488                return ActivityManager.BROADCAST_SUCCESS;
14489            }
14490        }
14491
14492        // Handle special intents: if this broadcast is from the package
14493        // manager about a package being removed, we need to remove all of
14494        // its activities from the history stack.
14495        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14496                intent.getAction());
14497        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14498                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14499                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14500                || uidRemoved) {
14501            if (checkComponentPermission(
14502                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14503                    callingPid, callingUid, -1, true)
14504                    == PackageManager.PERMISSION_GRANTED) {
14505                if (uidRemoved) {
14506                    final Bundle intentExtras = intent.getExtras();
14507                    final int uid = intentExtras != null
14508                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14509                    if (uid >= 0) {
14510                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14511                        synchronized (bs) {
14512                            bs.removeUidStatsLocked(uid);
14513                        }
14514                        mAppOpsService.uidRemoved(uid);
14515                    }
14516                } else {
14517                    // If resources are unavailable just force stop all
14518                    // those packages and flush the attribute cache as well.
14519                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14520                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14521                        if (list != null && (list.length > 0)) {
14522                            for (String pkg : list) {
14523                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14524                                        "storage unmount");
14525                            }
14526                            sendPackageBroadcastLocked(
14527                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14528                        }
14529                    } else {
14530                        Uri data = intent.getData();
14531                        String ssp;
14532                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14533                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14534                                    intent.getAction());
14535                            boolean fullUninstall = removed &&
14536                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14537                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14538                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14539                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14540                                        false, fullUninstall, userId,
14541                                        removed ? "pkg removed" : "pkg changed");
14542                            }
14543                            if (removed) {
14544                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14545                                        new String[] {ssp}, userId);
14546                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14547                                    mAppOpsService.packageRemoved(
14548                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14549
14550                                    // Remove all permissions granted from/to this package
14551                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14552                                }
14553                            }
14554                        }
14555                    }
14556                }
14557            } else {
14558                String msg = "Permission Denial: " + intent.getAction()
14559                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14560                        + ", uid=" + callingUid + ")"
14561                        + " requires "
14562                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14563                Slog.w(TAG, msg);
14564                throw new SecurityException(msg);
14565            }
14566
14567        // Special case for adding a package: by default turn on compatibility
14568        // mode.
14569        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14570            Uri data = intent.getData();
14571            String ssp;
14572            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14573                mCompatModePackages.handlePackageAddedLocked(ssp,
14574                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14575            }
14576        }
14577
14578        /*
14579         * If this is the time zone changed action, queue up a message that will reset the timezone
14580         * of all currently running processes. This message will get queued up before the broadcast
14581         * happens.
14582         */
14583        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14584            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14585        }
14586
14587        /*
14588         * If the user set the time, let all running processes know.
14589         */
14590        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14591            final int is24Hour = intent.getBooleanExtra(
14592                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14593            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14594        }
14595
14596        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14597            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14598        }
14599
14600        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14601            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14602            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14603        }
14604
14605        // Add to the sticky list if requested.
14606        if (sticky) {
14607            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14608                    callingPid, callingUid)
14609                    != PackageManager.PERMISSION_GRANTED) {
14610                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14611                        + callingPid + ", uid=" + callingUid
14612                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14613                Slog.w(TAG, msg);
14614                throw new SecurityException(msg);
14615            }
14616            if (requiredPermission != null) {
14617                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14618                        + " and enforce permission " + requiredPermission);
14619                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14620            }
14621            if (intent.getComponent() != null) {
14622                throw new SecurityException(
14623                        "Sticky broadcasts can't target a specific component");
14624            }
14625            // We use userId directly here, since the "all" target is maintained
14626            // as a separate set of sticky broadcasts.
14627            if (userId != UserHandle.USER_ALL) {
14628                // But first, if this is not a broadcast to all users, then
14629                // make sure it doesn't conflict with an existing broadcast to
14630                // all users.
14631                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14632                        UserHandle.USER_ALL);
14633                if (stickies != null) {
14634                    ArrayList<Intent> list = stickies.get(intent.getAction());
14635                    if (list != null) {
14636                        int N = list.size();
14637                        int i;
14638                        for (i=0; i<N; i++) {
14639                            if (intent.filterEquals(list.get(i))) {
14640                                throw new IllegalArgumentException(
14641                                        "Sticky broadcast " + intent + " for user "
14642                                        + userId + " conflicts with existing global broadcast");
14643                            }
14644                        }
14645                    }
14646                }
14647            }
14648            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14649            if (stickies == null) {
14650                stickies = new ArrayMap<String, ArrayList<Intent>>();
14651                mStickyBroadcasts.put(userId, stickies);
14652            }
14653            ArrayList<Intent> list = stickies.get(intent.getAction());
14654            if (list == null) {
14655                list = new ArrayList<Intent>();
14656                stickies.put(intent.getAction(), list);
14657            }
14658            int N = list.size();
14659            int i;
14660            for (i=0; i<N; i++) {
14661                if (intent.filterEquals(list.get(i))) {
14662                    // This sticky already exists, replace it.
14663                    list.set(i, new Intent(intent));
14664                    break;
14665                }
14666            }
14667            if (i >= N) {
14668                list.add(new Intent(intent));
14669            }
14670        }
14671
14672        int[] users;
14673        if (userId == UserHandle.USER_ALL) {
14674            // Caller wants broadcast to go to all started users.
14675            users = mStartedUserArray;
14676        } else {
14677            // Caller wants broadcast to go to one specific user.
14678            users = new int[] {userId};
14679        }
14680
14681        // Figure out who all will receive this broadcast.
14682        List receivers = null;
14683        List<BroadcastFilter> registeredReceivers = null;
14684        // Need to resolve the intent to interested receivers...
14685        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14686                 == 0) {
14687            receivers = collectReceiverComponents(intent, resolvedType, users);
14688        }
14689        if (intent.getComponent() == null) {
14690            registeredReceivers = mReceiverResolver.queryIntent(intent,
14691                    resolvedType, false, userId);
14692        }
14693
14694        final boolean replacePending =
14695                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14696
14697        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14698                + " replacePending=" + replacePending);
14699
14700        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14701        if (!ordered && NR > 0) {
14702            // If we are not serializing this broadcast, then send the
14703            // registered receivers separately so they don't wait for the
14704            // components to be launched.
14705            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14706            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14707                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14708                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14709                    ordered, sticky, false, userId);
14710            if (DEBUG_BROADCAST) Slog.v(
14711                    TAG, "Enqueueing parallel broadcast " + r);
14712            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14713            if (!replaced) {
14714                queue.enqueueParallelBroadcastLocked(r);
14715                queue.scheduleBroadcastsLocked();
14716            }
14717            registeredReceivers = null;
14718            NR = 0;
14719        }
14720
14721        // Merge into one list.
14722        int ir = 0;
14723        if (receivers != null) {
14724            // A special case for PACKAGE_ADDED: do not allow the package
14725            // being added to see this broadcast.  This prevents them from
14726            // using this as a back door to get run as soon as they are
14727            // installed.  Maybe in the future we want to have a special install
14728            // broadcast or such for apps, but we'd like to deliberately make
14729            // this decision.
14730            String skipPackages[] = null;
14731            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14732                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14733                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14734                Uri data = intent.getData();
14735                if (data != null) {
14736                    String pkgName = data.getSchemeSpecificPart();
14737                    if (pkgName != null) {
14738                        skipPackages = new String[] { pkgName };
14739                    }
14740                }
14741            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14742                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14743            }
14744            if (skipPackages != null && (skipPackages.length > 0)) {
14745                for (String skipPackage : skipPackages) {
14746                    if (skipPackage != null) {
14747                        int NT = receivers.size();
14748                        for (int it=0; it<NT; it++) {
14749                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14750                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14751                                receivers.remove(it);
14752                                it--;
14753                                NT--;
14754                            }
14755                        }
14756                    }
14757                }
14758            }
14759
14760            int NT = receivers != null ? receivers.size() : 0;
14761            int it = 0;
14762            ResolveInfo curt = null;
14763            BroadcastFilter curr = null;
14764            while (it < NT && ir < NR) {
14765                if (curt == null) {
14766                    curt = (ResolveInfo)receivers.get(it);
14767                }
14768                if (curr == null) {
14769                    curr = registeredReceivers.get(ir);
14770                }
14771                if (curr.getPriority() >= curt.priority) {
14772                    // Insert this broadcast record into the final list.
14773                    receivers.add(it, curr);
14774                    ir++;
14775                    curr = null;
14776                    it++;
14777                    NT++;
14778                } else {
14779                    // Skip to the next ResolveInfo in the final list.
14780                    it++;
14781                    curt = null;
14782                }
14783            }
14784        }
14785        while (ir < NR) {
14786            if (receivers == null) {
14787                receivers = new ArrayList();
14788            }
14789            receivers.add(registeredReceivers.get(ir));
14790            ir++;
14791        }
14792
14793        if ((receivers != null && receivers.size() > 0)
14794                || resultTo != null) {
14795            BroadcastQueue queue = broadcastQueueForIntent(intent);
14796            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14797                    callerPackage, callingPid, callingUid, resolvedType,
14798                    requiredPermission, appOp, receivers, resultTo, resultCode,
14799                    resultData, map, ordered, sticky, false, userId);
14800            if (DEBUG_BROADCAST) Slog.v(
14801                    TAG, "Enqueueing ordered broadcast " + r
14802                    + ": prev had " + queue.mOrderedBroadcasts.size());
14803            if (DEBUG_BROADCAST) {
14804                int seq = r.intent.getIntExtra("seq", -1);
14805                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14806            }
14807            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14808            if (!replaced) {
14809                queue.enqueueOrderedBroadcastLocked(r);
14810                queue.scheduleBroadcastsLocked();
14811            }
14812        }
14813
14814        return ActivityManager.BROADCAST_SUCCESS;
14815    }
14816
14817    final Intent verifyBroadcastLocked(Intent intent) {
14818        // Refuse possible leaked file descriptors
14819        if (intent != null && intent.hasFileDescriptors() == true) {
14820            throw new IllegalArgumentException("File descriptors passed in Intent");
14821        }
14822
14823        int flags = intent.getFlags();
14824
14825        if (!mProcessesReady) {
14826            // if the caller really truly claims to know what they're doing, go
14827            // ahead and allow the broadcast without launching any receivers
14828            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14829                intent = new Intent(intent);
14830                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14831            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14832                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14833                        + " before boot completion");
14834                throw new IllegalStateException("Cannot broadcast before boot completed");
14835            }
14836        }
14837
14838        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14839            throw new IllegalArgumentException(
14840                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14841        }
14842
14843        return intent;
14844    }
14845
14846    public final int broadcastIntent(IApplicationThread caller,
14847            Intent intent, String resolvedType, IIntentReceiver resultTo,
14848            int resultCode, String resultData, Bundle map,
14849            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14850        enforceNotIsolatedCaller("broadcastIntent");
14851        synchronized(this) {
14852            intent = verifyBroadcastLocked(intent);
14853
14854            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14855            final int callingPid = Binder.getCallingPid();
14856            final int callingUid = Binder.getCallingUid();
14857            final long origId = Binder.clearCallingIdentity();
14858            int res = broadcastIntentLocked(callerApp,
14859                    callerApp != null ? callerApp.info.packageName : null,
14860                    intent, resolvedType, resultTo,
14861                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14862                    callingPid, callingUid, userId);
14863            Binder.restoreCallingIdentity(origId);
14864            return res;
14865        }
14866    }
14867
14868    int broadcastIntentInPackage(String packageName, int uid,
14869            Intent intent, String resolvedType, IIntentReceiver resultTo,
14870            int resultCode, String resultData, Bundle map,
14871            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14872        synchronized(this) {
14873            intent = verifyBroadcastLocked(intent);
14874
14875            final long origId = Binder.clearCallingIdentity();
14876            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14877                    resultTo, resultCode, resultData, map, requiredPermission,
14878                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14879            Binder.restoreCallingIdentity(origId);
14880            return res;
14881        }
14882    }
14883
14884    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14885        // Refuse possible leaked file descriptors
14886        if (intent != null && intent.hasFileDescriptors() == true) {
14887            throw new IllegalArgumentException("File descriptors passed in Intent");
14888        }
14889
14890        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14891                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14892
14893        synchronized(this) {
14894            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14895                    != PackageManager.PERMISSION_GRANTED) {
14896                String msg = "Permission Denial: unbroadcastIntent() from pid="
14897                        + Binder.getCallingPid()
14898                        + ", uid=" + Binder.getCallingUid()
14899                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14900                Slog.w(TAG, msg);
14901                throw new SecurityException(msg);
14902            }
14903            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14904            if (stickies != null) {
14905                ArrayList<Intent> list = stickies.get(intent.getAction());
14906                if (list != null) {
14907                    int N = list.size();
14908                    int i;
14909                    for (i=0; i<N; i++) {
14910                        if (intent.filterEquals(list.get(i))) {
14911                            list.remove(i);
14912                            break;
14913                        }
14914                    }
14915                    if (list.size() <= 0) {
14916                        stickies.remove(intent.getAction());
14917                    }
14918                }
14919                if (stickies.size() <= 0) {
14920                    mStickyBroadcasts.remove(userId);
14921                }
14922            }
14923        }
14924    }
14925
14926    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14927            String resultData, Bundle resultExtras, boolean resultAbort) {
14928        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14929        if (r == null) {
14930            Slog.w(TAG, "finishReceiver called but not found on queue");
14931            return false;
14932        }
14933
14934        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14935    }
14936
14937    void backgroundServicesFinishedLocked(int userId) {
14938        for (BroadcastQueue queue : mBroadcastQueues) {
14939            queue.backgroundServicesFinishedLocked(userId);
14940        }
14941    }
14942
14943    public void finishReceiver(IBinder who, int resultCode, String resultData,
14944            Bundle resultExtras, boolean resultAbort) {
14945        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14946
14947        // Refuse possible leaked file descriptors
14948        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14949            throw new IllegalArgumentException("File descriptors passed in Bundle");
14950        }
14951
14952        final long origId = Binder.clearCallingIdentity();
14953        try {
14954            boolean doNext = false;
14955            BroadcastRecord r;
14956
14957            synchronized(this) {
14958                r = broadcastRecordForReceiverLocked(who);
14959                if (r != null) {
14960                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14961                        resultData, resultExtras, resultAbort, true);
14962                }
14963            }
14964
14965            if (doNext) {
14966                r.queue.processNextBroadcast(false);
14967            }
14968            trimApplications();
14969        } finally {
14970            Binder.restoreCallingIdentity(origId);
14971        }
14972    }
14973
14974    // =========================================================
14975    // INSTRUMENTATION
14976    // =========================================================
14977
14978    public boolean startInstrumentation(ComponentName className,
14979            String profileFile, int flags, Bundle arguments,
14980            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14981            int userId, String abiOverride) {
14982        enforceNotIsolatedCaller("startInstrumentation");
14983        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14984                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14985        // Refuse possible leaked file descriptors
14986        if (arguments != null && arguments.hasFileDescriptors()) {
14987            throw new IllegalArgumentException("File descriptors passed in Bundle");
14988        }
14989
14990        synchronized(this) {
14991            InstrumentationInfo ii = null;
14992            ApplicationInfo ai = null;
14993            try {
14994                ii = mContext.getPackageManager().getInstrumentationInfo(
14995                    className, STOCK_PM_FLAGS);
14996                ai = AppGlobals.getPackageManager().getApplicationInfo(
14997                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14998            } catch (PackageManager.NameNotFoundException e) {
14999            } catch (RemoteException e) {
15000            }
15001            if (ii == null) {
15002                reportStartInstrumentationFailure(watcher, className,
15003                        "Unable to find instrumentation info for: " + className);
15004                return false;
15005            }
15006            if (ai == null) {
15007                reportStartInstrumentationFailure(watcher, className,
15008                        "Unable to find instrumentation target package: " + ii.targetPackage);
15009                return false;
15010            }
15011
15012            int match = mContext.getPackageManager().checkSignatures(
15013                    ii.targetPackage, ii.packageName);
15014            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15015                String msg = "Permission Denial: starting instrumentation "
15016                        + className + " from pid="
15017                        + Binder.getCallingPid()
15018                        + ", uid=" + Binder.getCallingPid()
15019                        + " not allowed because package " + ii.packageName
15020                        + " does not have a signature matching the target "
15021                        + ii.targetPackage;
15022                reportStartInstrumentationFailure(watcher, className, msg);
15023                throw new SecurityException(msg);
15024            }
15025
15026            final long origId = Binder.clearCallingIdentity();
15027            // Instrumentation can kill and relaunch even persistent processes
15028            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15029                    "start instr");
15030            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15031            app.instrumentationClass = className;
15032            app.instrumentationInfo = ai;
15033            app.instrumentationProfileFile = profileFile;
15034            app.instrumentationArguments = arguments;
15035            app.instrumentationWatcher = watcher;
15036            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15037            app.instrumentationResultClass = className;
15038            Binder.restoreCallingIdentity(origId);
15039        }
15040
15041        return true;
15042    }
15043
15044    /**
15045     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15046     * error to the logs, but if somebody is watching, send the report there too.  This enables
15047     * the "am" command to report errors with more information.
15048     *
15049     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15050     * @param cn The component name of the instrumentation.
15051     * @param report The error report.
15052     */
15053    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15054            ComponentName cn, String report) {
15055        Slog.w(TAG, report);
15056        try {
15057            if (watcher != null) {
15058                Bundle results = new Bundle();
15059                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15060                results.putString("Error", report);
15061                watcher.instrumentationStatus(cn, -1, results);
15062            }
15063        } catch (RemoteException e) {
15064            Slog.w(TAG, e);
15065        }
15066    }
15067
15068    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15069        if (app.instrumentationWatcher != null) {
15070            try {
15071                // NOTE:  IInstrumentationWatcher *must* be oneway here
15072                app.instrumentationWatcher.instrumentationFinished(
15073                    app.instrumentationClass,
15074                    resultCode,
15075                    results);
15076            } catch (RemoteException e) {
15077            }
15078        }
15079        if (app.instrumentationUiAutomationConnection != null) {
15080            try {
15081                app.instrumentationUiAutomationConnection.shutdown();
15082            } catch (RemoteException re) {
15083                /* ignore */
15084            }
15085            // Only a UiAutomation can set this flag and now that
15086            // it is finished we make sure it is reset to its default.
15087            mUserIsMonkey = false;
15088        }
15089        app.instrumentationWatcher = null;
15090        app.instrumentationUiAutomationConnection = null;
15091        app.instrumentationClass = null;
15092        app.instrumentationInfo = null;
15093        app.instrumentationProfileFile = null;
15094        app.instrumentationArguments = null;
15095
15096        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15097                "finished inst");
15098    }
15099
15100    public void finishInstrumentation(IApplicationThread target,
15101            int resultCode, Bundle results) {
15102        int userId = UserHandle.getCallingUserId();
15103        // Refuse possible leaked file descriptors
15104        if (results != null && results.hasFileDescriptors()) {
15105            throw new IllegalArgumentException("File descriptors passed in Intent");
15106        }
15107
15108        synchronized(this) {
15109            ProcessRecord app = getRecordForAppLocked(target);
15110            if (app == null) {
15111                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15112                return;
15113            }
15114            final long origId = Binder.clearCallingIdentity();
15115            finishInstrumentationLocked(app, resultCode, results);
15116            Binder.restoreCallingIdentity(origId);
15117        }
15118    }
15119
15120    // =========================================================
15121    // CONFIGURATION
15122    // =========================================================
15123
15124    public ConfigurationInfo getDeviceConfigurationInfo() {
15125        ConfigurationInfo config = new ConfigurationInfo();
15126        synchronized (this) {
15127            config.reqTouchScreen = mConfiguration.touchscreen;
15128            config.reqKeyboardType = mConfiguration.keyboard;
15129            config.reqNavigation = mConfiguration.navigation;
15130            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15131                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15132                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15133            }
15134            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15135                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15136                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15137            }
15138            config.reqGlEsVersion = GL_ES_VERSION;
15139        }
15140        return config;
15141    }
15142
15143    ActivityStack getFocusedStack() {
15144        return mStackSupervisor.getFocusedStack();
15145    }
15146
15147    public Configuration getConfiguration() {
15148        Configuration ci;
15149        synchronized(this) {
15150            ci = new Configuration(mConfiguration);
15151        }
15152        return ci;
15153    }
15154
15155    public void updatePersistentConfiguration(Configuration values) {
15156        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15157                "updateConfiguration()");
15158        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15159                "updateConfiguration()");
15160        if (values == null) {
15161            throw new NullPointerException("Configuration must not be null");
15162        }
15163
15164        synchronized(this) {
15165            final long origId = Binder.clearCallingIdentity();
15166            updateConfigurationLocked(values, null, true, false);
15167            Binder.restoreCallingIdentity(origId);
15168        }
15169    }
15170
15171    public void updateConfiguration(Configuration values) {
15172        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15173                "updateConfiguration()");
15174
15175        synchronized(this) {
15176            if (values == null && mWindowManager != null) {
15177                // sentinel: fetch the current configuration from the window manager
15178                values = mWindowManager.computeNewConfiguration();
15179            }
15180
15181            if (mWindowManager != null) {
15182                mProcessList.applyDisplaySize(mWindowManager);
15183            }
15184
15185            final long origId = Binder.clearCallingIdentity();
15186            if (values != null) {
15187                Settings.System.clearConfiguration(values);
15188            }
15189            updateConfigurationLocked(values, null, false, false);
15190            Binder.restoreCallingIdentity(origId);
15191        }
15192    }
15193
15194    /**
15195     * Do either or both things: (1) change the current configuration, and (2)
15196     * make sure the given activity is running with the (now) current
15197     * configuration.  Returns true if the activity has been left running, or
15198     * false if <var>starting</var> is being destroyed to match the new
15199     * configuration.
15200     * @param persistent TODO
15201     */
15202    boolean updateConfigurationLocked(Configuration values,
15203            ActivityRecord starting, boolean persistent, boolean initLocale) {
15204        int changes = 0;
15205
15206        if (values != null) {
15207            Configuration newConfig = new Configuration(mConfiguration);
15208            changes = newConfig.updateFrom(values);
15209            if (changes != 0) {
15210                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15211                    Slog.i(TAG, "Updating configuration to: " + values);
15212                }
15213
15214                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15215
15216                if (values.locale != null && !initLocale) {
15217                    saveLocaleLocked(values.locale,
15218                                     !values.locale.equals(mConfiguration.locale),
15219                                     values.userSetLocale);
15220                }
15221
15222                mConfigurationSeq++;
15223                if (mConfigurationSeq <= 0) {
15224                    mConfigurationSeq = 1;
15225                }
15226                newConfig.seq = mConfigurationSeq;
15227                mConfiguration = newConfig;
15228                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15229                //mUsageStatsService.noteStartConfig(newConfig);
15230
15231                final Configuration configCopy = new Configuration(mConfiguration);
15232
15233                // TODO: If our config changes, should we auto dismiss any currently
15234                // showing dialogs?
15235                mShowDialogs = shouldShowDialogs(newConfig);
15236
15237                AttributeCache ac = AttributeCache.instance();
15238                if (ac != null) {
15239                    ac.updateConfiguration(configCopy);
15240                }
15241
15242                // Make sure all resources in our process are updated
15243                // right now, so that anyone who is going to retrieve
15244                // resource values after we return will be sure to get
15245                // the new ones.  This is especially important during
15246                // boot, where the first config change needs to guarantee
15247                // all resources have that config before following boot
15248                // code is executed.
15249                mSystemThread.applyConfigurationToResources(configCopy);
15250
15251                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15252                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15253                    msg.obj = new Configuration(configCopy);
15254                    mHandler.sendMessage(msg);
15255                }
15256
15257                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15258                    ProcessRecord app = mLruProcesses.get(i);
15259                    try {
15260                        if (app.thread != null) {
15261                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15262                                    + app.processName + " new config " + mConfiguration);
15263                            app.thread.scheduleConfigurationChanged(configCopy);
15264                        }
15265                    } catch (Exception e) {
15266                    }
15267                }
15268                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15269                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15270                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15271                        | Intent.FLAG_RECEIVER_FOREGROUND);
15272                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15273                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15274                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15275                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15276                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15277                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15278                    broadcastIntentLocked(null, null, intent,
15279                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15280                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15281                }
15282            }
15283        }
15284
15285        boolean kept = true;
15286        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15287        // mainStack is null during startup.
15288        if (mainStack != null) {
15289            if (changes != 0 && starting == null) {
15290                // If the configuration changed, and the caller is not already
15291                // in the process of starting an activity, then find the top
15292                // activity to check if its configuration needs to change.
15293                starting = mainStack.topRunningActivityLocked(null);
15294            }
15295
15296            if (starting != null) {
15297                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15298                // And we need to make sure at this point that all other activities
15299                // are made visible with the correct configuration.
15300                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15301            }
15302        }
15303
15304        if (values != null && mWindowManager != null) {
15305            mWindowManager.setNewConfiguration(mConfiguration);
15306        }
15307
15308        return kept;
15309    }
15310
15311    /**
15312     * Decide based on the configuration whether we should shouw the ANR,
15313     * crash, etc dialogs.  The idea is that if there is no affordnace to
15314     * press the on-screen buttons, we shouldn't show the dialog.
15315     *
15316     * A thought: SystemUI might also want to get told about this, the Power
15317     * dialog / global actions also might want different behaviors.
15318     */
15319    private static final boolean shouldShowDialogs(Configuration config) {
15320        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15321                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15322    }
15323
15324    /**
15325     * Save the locale.  You must be inside a synchronized (this) block.
15326     */
15327    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15328        if(isDiff) {
15329            SystemProperties.set("user.language", l.getLanguage());
15330            SystemProperties.set("user.region", l.getCountry());
15331        }
15332
15333        if(isPersist) {
15334            SystemProperties.set("persist.sys.language", l.getLanguage());
15335            SystemProperties.set("persist.sys.country", l.getCountry());
15336            SystemProperties.set("persist.sys.localevar", l.getVariant());
15337        }
15338    }
15339
15340    @Override
15341    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15342        ActivityRecord srec = ActivityRecord.forToken(token);
15343        return srec != null && srec.task.affinity != null &&
15344                srec.task.affinity.equals(destAffinity);
15345    }
15346
15347    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15348            Intent resultData) {
15349
15350        synchronized (this) {
15351            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15352            if (stack != null) {
15353                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15354            }
15355            return false;
15356        }
15357    }
15358
15359    public int getLaunchedFromUid(IBinder activityToken) {
15360        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15361        if (srec == null) {
15362            return -1;
15363        }
15364        return srec.launchedFromUid;
15365    }
15366
15367    public String getLaunchedFromPackage(IBinder activityToken) {
15368        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15369        if (srec == null) {
15370            return null;
15371        }
15372        return srec.launchedFromPackage;
15373    }
15374
15375    // =========================================================
15376    // LIFETIME MANAGEMENT
15377    // =========================================================
15378
15379    // Returns which broadcast queue the app is the current [or imminent] receiver
15380    // on, or 'null' if the app is not an active broadcast recipient.
15381    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15382        BroadcastRecord r = app.curReceiver;
15383        if (r != null) {
15384            return r.queue;
15385        }
15386
15387        // It's not the current receiver, but it might be starting up to become one
15388        synchronized (this) {
15389            for (BroadcastQueue queue : mBroadcastQueues) {
15390                r = queue.mPendingBroadcast;
15391                if (r != null && r.curApp == app) {
15392                    // found it; report which queue it's in
15393                    return queue;
15394                }
15395            }
15396        }
15397
15398        return null;
15399    }
15400
15401    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15402            boolean doingAll, long now) {
15403        if (mAdjSeq == app.adjSeq) {
15404            // This adjustment has already been computed.
15405            return app.curRawAdj;
15406        }
15407
15408        if (app.thread == null) {
15409            app.adjSeq = mAdjSeq;
15410            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15411            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15412            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15413        }
15414
15415        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15416        app.adjSource = null;
15417        app.adjTarget = null;
15418        app.empty = false;
15419        app.cached = false;
15420
15421        final int activitiesSize = app.activities.size();
15422
15423        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15424            // The max adjustment doesn't allow this app to be anything
15425            // below foreground, so it is not worth doing work for it.
15426            app.adjType = "fixed";
15427            app.adjSeq = mAdjSeq;
15428            app.curRawAdj = app.maxAdj;
15429            app.foregroundActivities = false;
15430            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15431            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15432            // System processes can do UI, and when they do we want to have
15433            // them trim their memory after the user leaves the UI.  To
15434            // facilitate this, here we need to determine whether or not it
15435            // is currently showing UI.
15436            app.systemNoUi = true;
15437            if (app == TOP_APP) {
15438                app.systemNoUi = false;
15439            } else if (activitiesSize > 0) {
15440                for (int j = 0; j < activitiesSize; j++) {
15441                    final ActivityRecord r = app.activities.get(j);
15442                    if (r.visible) {
15443                        app.systemNoUi = false;
15444                    }
15445                }
15446            }
15447            if (!app.systemNoUi) {
15448                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15449            }
15450            return (app.curAdj=app.maxAdj);
15451        }
15452
15453        app.systemNoUi = false;
15454
15455        // Determine the importance of the process, starting with most
15456        // important to least, and assign an appropriate OOM adjustment.
15457        int adj;
15458        int schedGroup;
15459        int procState;
15460        boolean foregroundActivities = false;
15461        BroadcastQueue queue;
15462        if (app == TOP_APP) {
15463            // The last app on the list is the foreground app.
15464            adj = ProcessList.FOREGROUND_APP_ADJ;
15465            schedGroup = Process.THREAD_GROUP_DEFAULT;
15466            app.adjType = "top-activity";
15467            foregroundActivities = true;
15468            procState = ActivityManager.PROCESS_STATE_TOP;
15469        } else if (app.instrumentationClass != null) {
15470            // Don't want to kill running instrumentation.
15471            adj = ProcessList.FOREGROUND_APP_ADJ;
15472            schedGroup = Process.THREAD_GROUP_DEFAULT;
15473            app.adjType = "instrumentation";
15474            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15475        } else if ((queue = isReceivingBroadcast(app)) != null) {
15476            // An app that is currently receiving a broadcast also
15477            // counts as being in the foreground for OOM killer purposes.
15478            // It's placed in a sched group based on the nature of the
15479            // broadcast as reflected by which queue it's active in.
15480            adj = ProcessList.FOREGROUND_APP_ADJ;
15481            schedGroup = (queue == mFgBroadcastQueue)
15482                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15483            app.adjType = "broadcast";
15484            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15485        } else if (app.executingServices.size() > 0) {
15486            // An app that is currently executing a service callback also
15487            // counts as being in the foreground.
15488            adj = ProcessList.FOREGROUND_APP_ADJ;
15489            schedGroup = app.execServicesFg ?
15490                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15491            app.adjType = "exec-service";
15492            procState = ActivityManager.PROCESS_STATE_SERVICE;
15493            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15494        } else {
15495            // As far as we know the process is empty.  We may change our mind later.
15496            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15497            // At this point we don't actually know the adjustment.  Use the cached adj
15498            // value that the caller wants us to.
15499            adj = cachedAdj;
15500            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15501            app.cached = true;
15502            app.empty = true;
15503            app.adjType = "cch-empty";
15504        }
15505
15506        // Examine all activities if not already foreground.
15507        if (!foregroundActivities && activitiesSize > 0) {
15508            for (int j = 0; j < activitiesSize; j++) {
15509                final ActivityRecord r = app.activities.get(j);
15510                if (r.app != app) {
15511                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15512                            + app + "?!?");
15513                    continue;
15514                }
15515                if (r.visible) {
15516                    // App has a visible activity; only upgrade adjustment.
15517                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15518                        adj = ProcessList.VISIBLE_APP_ADJ;
15519                        app.adjType = "visible";
15520                    }
15521                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15522                        procState = ActivityManager.PROCESS_STATE_TOP;
15523                    }
15524                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15525                    app.cached = false;
15526                    app.empty = false;
15527                    foregroundActivities = true;
15528                    break;
15529                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15530                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15531                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15532                        app.adjType = "pausing";
15533                    }
15534                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15535                        procState = ActivityManager.PROCESS_STATE_TOP;
15536                    }
15537                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15538                    app.cached = false;
15539                    app.empty = false;
15540                    foregroundActivities = true;
15541                } else if (r.state == ActivityState.STOPPING) {
15542                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15543                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15544                        app.adjType = "stopping";
15545                    }
15546                    // For the process state, we will at this point consider the
15547                    // process to be cached.  It will be cached either as an activity
15548                    // or empty depending on whether the activity is finishing.  We do
15549                    // this so that we can treat the process as cached for purposes of
15550                    // memory trimming (determing current memory level, trim command to
15551                    // send to process) since there can be an arbitrary number of stopping
15552                    // processes and they should soon all go into the cached state.
15553                    if (!r.finishing) {
15554                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15555                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15556                        }
15557                    }
15558                    app.cached = false;
15559                    app.empty = false;
15560                    foregroundActivities = true;
15561                } else {
15562                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15563                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15564                        app.adjType = "cch-act";
15565                    }
15566                }
15567            }
15568        }
15569
15570        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15571            if (app.foregroundServices) {
15572                // The user is aware of this app, so make it visible.
15573                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15574                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15575                app.cached = false;
15576                app.adjType = "fg-service";
15577                schedGroup = Process.THREAD_GROUP_DEFAULT;
15578            } else if (app.forcingToForeground != null) {
15579                // The user is aware of this app, so make it visible.
15580                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15581                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15582                app.cached = false;
15583                app.adjType = "force-fg";
15584                app.adjSource = app.forcingToForeground;
15585                schedGroup = Process.THREAD_GROUP_DEFAULT;
15586            }
15587        }
15588
15589        if (app == mHeavyWeightProcess) {
15590            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15591                // We don't want to kill the current heavy-weight process.
15592                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15593                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15594                app.cached = false;
15595                app.adjType = "heavy";
15596            }
15597            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15598                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15599            }
15600        }
15601
15602        if (app == mHomeProcess) {
15603            if (adj > ProcessList.HOME_APP_ADJ) {
15604                // This process is hosting what we currently consider to be the
15605                // home app, so we don't want to let it go into the background.
15606                adj = ProcessList.HOME_APP_ADJ;
15607                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15608                app.cached = false;
15609                app.adjType = "home";
15610            }
15611            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15612                procState = ActivityManager.PROCESS_STATE_HOME;
15613            }
15614        }
15615
15616        if (app == mPreviousProcess && app.activities.size() > 0) {
15617            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15618                // This was the previous process that showed UI to the user.
15619                // We want to try to keep it around more aggressively, to give
15620                // a good experience around switching between two apps.
15621                adj = ProcessList.PREVIOUS_APP_ADJ;
15622                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15623                app.cached = false;
15624                app.adjType = "previous";
15625            }
15626            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15627                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15628            }
15629        }
15630
15631        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15632                + " reason=" + app.adjType);
15633
15634        // By default, we use the computed adjustment.  It may be changed if
15635        // there are applications dependent on our services or providers, but
15636        // this gives us a baseline and makes sure we don't get into an
15637        // infinite recursion.
15638        app.adjSeq = mAdjSeq;
15639        app.curRawAdj = adj;
15640        app.hasStartedServices = false;
15641
15642        if (mBackupTarget != null && app == mBackupTarget.app) {
15643            // If possible we want to avoid killing apps while they're being backed up
15644            if (adj > ProcessList.BACKUP_APP_ADJ) {
15645                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15646                adj = ProcessList.BACKUP_APP_ADJ;
15647                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15648                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15649                }
15650                app.adjType = "backup";
15651                app.cached = false;
15652            }
15653            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15654                procState = ActivityManager.PROCESS_STATE_BACKUP;
15655            }
15656        }
15657
15658        boolean mayBeTop = false;
15659
15660        for (int is = app.services.size()-1;
15661                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15662                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15663                        || procState > ActivityManager.PROCESS_STATE_TOP);
15664                is--) {
15665            ServiceRecord s = app.services.valueAt(is);
15666            if (s.startRequested) {
15667                app.hasStartedServices = true;
15668                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15669                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15670                }
15671                if (app.hasShownUi && app != mHomeProcess) {
15672                    // If this process has shown some UI, let it immediately
15673                    // go to the LRU list because it may be pretty heavy with
15674                    // UI stuff.  We'll tag it with a label just to help
15675                    // debug and understand what is going on.
15676                    if (adj > ProcessList.SERVICE_ADJ) {
15677                        app.adjType = "cch-started-ui-services";
15678                    }
15679                } else {
15680                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15681                        // This service has seen some activity within
15682                        // recent memory, so we will keep its process ahead
15683                        // of the background processes.
15684                        if (adj > ProcessList.SERVICE_ADJ) {
15685                            adj = ProcessList.SERVICE_ADJ;
15686                            app.adjType = "started-services";
15687                            app.cached = false;
15688                        }
15689                    }
15690                    // If we have let the service slide into the background
15691                    // state, still have some text describing what it is doing
15692                    // even though the service no longer has an impact.
15693                    if (adj > ProcessList.SERVICE_ADJ) {
15694                        app.adjType = "cch-started-services";
15695                    }
15696                }
15697            }
15698            for (int conni = s.connections.size()-1;
15699                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15700                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15701                            || procState > ActivityManager.PROCESS_STATE_TOP);
15702                    conni--) {
15703                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15704                for (int i = 0;
15705                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15706                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15707                                || procState > ActivityManager.PROCESS_STATE_TOP);
15708                        i++) {
15709                    // XXX should compute this based on the max of
15710                    // all connected clients.
15711                    ConnectionRecord cr = clist.get(i);
15712                    if (cr.binding.client == app) {
15713                        // Binding to ourself is not interesting.
15714                        continue;
15715                    }
15716                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15717                        ProcessRecord client = cr.binding.client;
15718                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15719                                TOP_APP, doingAll, now);
15720                        int clientProcState = client.curProcState;
15721                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15722                            // If the other app is cached for any reason, for purposes here
15723                            // we are going to consider it empty.  The specific cached state
15724                            // doesn't propagate except under certain conditions.
15725                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15726                        }
15727                        String adjType = null;
15728                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15729                            // Not doing bind OOM management, so treat
15730                            // this guy more like a started service.
15731                            if (app.hasShownUi && app != mHomeProcess) {
15732                                // If this process has shown some UI, let it immediately
15733                                // go to the LRU list because it may be pretty heavy with
15734                                // UI stuff.  We'll tag it with a label just to help
15735                                // debug and understand what is going on.
15736                                if (adj > clientAdj) {
15737                                    adjType = "cch-bound-ui-services";
15738                                }
15739                                app.cached = false;
15740                                clientAdj = adj;
15741                                clientProcState = procState;
15742                            } else {
15743                                if (now >= (s.lastActivity
15744                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15745                                    // This service has not seen activity within
15746                                    // recent memory, so allow it to drop to the
15747                                    // LRU list if there is no other reason to keep
15748                                    // it around.  We'll also tag it with a label just
15749                                    // to help debug and undertand what is going on.
15750                                    if (adj > clientAdj) {
15751                                        adjType = "cch-bound-services";
15752                                    }
15753                                    clientAdj = adj;
15754                                }
15755                            }
15756                        }
15757                        if (adj > clientAdj) {
15758                            // If this process has recently shown UI, and
15759                            // the process that is binding to it is less
15760                            // important than being visible, then we don't
15761                            // care about the binding as much as we care
15762                            // about letting this process get into the LRU
15763                            // list to be killed and restarted if needed for
15764                            // memory.
15765                            if (app.hasShownUi && app != mHomeProcess
15766                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15767                                adjType = "cch-bound-ui-services";
15768                            } else {
15769                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15770                                        |Context.BIND_IMPORTANT)) != 0) {
15771                                    adj = clientAdj;
15772                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15773                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15774                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15775                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15776                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15777                                    adj = clientAdj;
15778                                } else {
15779                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15780                                        adj = ProcessList.VISIBLE_APP_ADJ;
15781                                    }
15782                                }
15783                                if (!client.cached) {
15784                                    app.cached = false;
15785                                }
15786                                adjType = "service";
15787                            }
15788                        }
15789                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15790                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15791                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15792                            }
15793                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15794                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15795                                    // Special handling of clients who are in the top state.
15796                                    // We *may* want to consider this process to be in the
15797                                    // top state as well, but only if there is not another
15798                                    // reason for it to be running.  Being on the top is a
15799                                    // special state, meaning you are specifically running
15800                                    // for the current top app.  If the process is already
15801                                    // running in the background for some other reason, it
15802                                    // is more important to continue considering it to be
15803                                    // in the background state.
15804                                    mayBeTop = true;
15805                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15806                                } else {
15807                                    // Special handling for above-top states (persistent
15808                                    // processes).  These should not bring the current process
15809                                    // into the top state, since they are not on top.  Instead
15810                                    // give them the best state after that.
15811                                    clientProcState =
15812                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15813                                }
15814                            }
15815                        } else {
15816                            if (clientProcState <
15817                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15818                                clientProcState =
15819                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15820                            }
15821                        }
15822                        if (procState > clientProcState) {
15823                            procState = clientProcState;
15824                        }
15825                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15826                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15827                            app.pendingUiClean = true;
15828                        }
15829                        if (adjType != null) {
15830                            app.adjType = adjType;
15831                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15832                                    .REASON_SERVICE_IN_USE;
15833                            app.adjSource = cr.binding.client;
15834                            app.adjSourceProcState = clientProcState;
15835                            app.adjTarget = s.name;
15836                        }
15837                    }
15838                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15839                        app.treatLikeActivity = true;
15840                    }
15841                    final ActivityRecord a = cr.activity;
15842                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15843                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15844                                (a.visible || a.state == ActivityState.RESUMED
15845                                 || a.state == ActivityState.PAUSING)) {
15846                            adj = ProcessList.FOREGROUND_APP_ADJ;
15847                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15848                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15849                            }
15850                            app.cached = false;
15851                            app.adjType = "service";
15852                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15853                                    .REASON_SERVICE_IN_USE;
15854                            app.adjSource = a;
15855                            app.adjSourceProcState = procState;
15856                            app.adjTarget = s.name;
15857                        }
15858                    }
15859                }
15860            }
15861        }
15862
15863        for (int provi = app.pubProviders.size()-1;
15864                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15865                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15866                        || procState > ActivityManager.PROCESS_STATE_TOP);
15867                provi--) {
15868            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15869            for (int i = cpr.connections.size()-1;
15870                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15871                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15872                            || procState > ActivityManager.PROCESS_STATE_TOP);
15873                    i--) {
15874                ContentProviderConnection conn = cpr.connections.get(i);
15875                ProcessRecord client = conn.client;
15876                if (client == app) {
15877                    // Being our own client is not interesting.
15878                    continue;
15879                }
15880                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15881                int clientProcState = client.curProcState;
15882                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15883                    // If the other app is cached for any reason, for purposes here
15884                    // we are going to consider it empty.
15885                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15886                }
15887                if (adj > clientAdj) {
15888                    if (app.hasShownUi && app != mHomeProcess
15889                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15890                        app.adjType = "cch-ui-provider";
15891                    } else {
15892                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15893                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15894                        app.adjType = "provider";
15895                    }
15896                    app.cached &= client.cached;
15897                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15898                            .REASON_PROVIDER_IN_USE;
15899                    app.adjSource = client;
15900                    app.adjSourceProcState = clientProcState;
15901                    app.adjTarget = cpr.name;
15902                }
15903                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15904                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15905                        // Special handling of clients who are in the top state.
15906                        // We *may* want to consider this process to be in the
15907                        // top state as well, but only if there is not another
15908                        // reason for it to be running.  Being on the top is a
15909                        // special state, meaning you are specifically running
15910                        // for the current top app.  If the process is already
15911                        // running in the background for some other reason, it
15912                        // is more important to continue considering it to be
15913                        // in the background state.
15914                        mayBeTop = true;
15915                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15916                    } else {
15917                        // Special handling for above-top states (persistent
15918                        // processes).  These should not bring the current process
15919                        // into the top state, since they are not on top.  Instead
15920                        // give them the best state after that.
15921                        clientProcState =
15922                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15923                    }
15924                }
15925                if (procState > clientProcState) {
15926                    procState = clientProcState;
15927                }
15928                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15929                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15930                }
15931            }
15932            // If the provider has external (non-framework) process
15933            // dependencies, ensure that its adjustment is at least
15934            // FOREGROUND_APP_ADJ.
15935            if (cpr.hasExternalProcessHandles()) {
15936                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15937                    adj = ProcessList.FOREGROUND_APP_ADJ;
15938                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15939                    app.cached = false;
15940                    app.adjType = "provider";
15941                    app.adjTarget = cpr.name;
15942                }
15943                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15944                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15945                }
15946            }
15947        }
15948
15949        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15950            // A client of one of our services or providers is in the top state.  We
15951            // *may* want to be in the top state, but not if we are already running in
15952            // the background for some other reason.  For the decision here, we are going
15953            // to pick out a few specific states that we want to remain in when a client
15954            // is top (states that tend to be longer-term) and otherwise allow it to go
15955            // to the top state.
15956            switch (procState) {
15957                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15958                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15959                case ActivityManager.PROCESS_STATE_SERVICE:
15960                    // These all are longer-term states, so pull them up to the top
15961                    // of the background states, but not all the way to the top state.
15962                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15963                    break;
15964                default:
15965                    // Otherwise, top is a better choice, so take it.
15966                    procState = ActivityManager.PROCESS_STATE_TOP;
15967                    break;
15968            }
15969        }
15970
15971        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15972            if (app.hasClientActivities) {
15973                // This is a cached process, but with client activities.  Mark it so.
15974                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15975                app.adjType = "cch-client-act";
15976            } else if (app.treatLikeActivity) {
15977                // This is a cached process, but somebody wants us to treat it like it has
15978                // an activity, okay!
15979                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15980                app.adjType = "cch-as-act";
15981            }
15982        }
15983
15984        if (adj == ProcessList.SERVICE_ADJ) {
15985            if (doingAll) {
15986                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15987                mNewNumServiceProcs++;
15988                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15989                if (!app.serviceb) {
15990                    // This service isn't far enough down on the LRU list to
15991                    // normally be a B service, but if we are low on RAM and it
15992                    // is large we want to force it down since we would prefer to
15993                    // keep launcher over it.
15994                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15995                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15996                        app.serviceHighRam = true;
15997                        app.serviceb = true;
15998                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15999                    } else {
16000                        mNewNumAServiceProcs++;
16001                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16002                    }
16003                } else {
16004                    app.serviceHighRam = false;
16005                }
16006            }
16007            if (app.serviceb) {
16008                adj = ProcessList.SERVICE_B_ADJ;
16009            }
16010        }
16011
16012        app.curRawAdj = adj;
16013
16014        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16015        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16016        if (adj > app.maxAdj) {
16017            adj = app.maxAdj;
16018            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16019                schedGroup = Process.THREAD_GROUP_DEFAULT;
16020            }
16021        }
16022
16023        // Do final modification to adj.  Everything we do between here and applying
16024        // the final setAdj must be done in this function, because we will also use
16025        // it when computing the final cached adj later.  Note that we don't need to
16026        // worry about this for max adj above, since max adj will always be used to
16027        // keep it out of the cached vaues.
16028        app.curAdj = app.modifyRawOomAdj(adj);
16029        app.curSchedGroup = schedGroup;
16030        app.curProcState = procState;
16031        app.foregroundActivities = foregroundActivities;
16032
16033        return app.curRawAdj;
16034    }
16035
16036    /**
16037     * Schedule PSS collection of a process.
16038     */
16039    void requestPssLocked(ProcessRecord proc, int procState) {
16040        if (mPendingPssProcesses.contains(proc)) {
16041            return;
16042        }
16043        if (mPendingPssProcesses.size() == 0) {
16044            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16045        }
16046        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16047        proc.pssProcState = procState;
16048        mPendingPssProcesses.add(proc);
16049    }
16050
16051    /**
16052     * Schedule PSS collection of all processes.
16053     */
16054    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16055        if (!always) {
16056            if (now < (mLastFullPssTime +
16057                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16058                return;
16059            }
16060        }
16061        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16062        mLastFullPssTime = now;
16063        mFullPssPending = true;
16064        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16065        mPendingPssProcesses.clear();
16066        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16067            ProcessRecord app = mLruProcesses.get(i);
16068            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16069                app.pssProcState = app.setProcState;
16070                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16071                        isSleeping(), now);
16072                mPendingPssProcesses.add(app);
16073            }
16074        }
16075        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16076    }
16077
16078    /**
16079     * Ask a given process to GC right now.
16080     */
16081    final void performAppGcLocked(ProcessRecord app) {
16082        try {
16083            app.lastRequestedGc = SystemClock.uptimeMillis();
16084            if (app.thread != null) {
16085                if (app.reportLowMemory) {
16086                    app.reportLowMemory = false;
16087                    app.thread.scheduleLowMemory();
16088                } else {
16089                    app.thread.processInBackground();
16090                }
16091            }
16092        } catch (Exception e) {
16093            // whatever.
16094        }
16095    }
16096
16097    /**
16098     * Returns true if things are idle enough to perform GCs.
16099     */
16100    private final boolean canGcNowLocked() {
16101        boolean processingBroadcasts = false;
16102        for (BroadcastQueue q : mBroadcastQueues) {
16103            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16104                processingBroadcasts = true;
16105            }
16106        }
16107        return !processingBroadcasts
16108                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16109    }
16110
16111    /**
16112     * Perform GCs on all processes that are waiting for it, but only
16113     * if things are idle.
16114     */
16115    final void performAppGcsLocked() {
16116        final int N = mProcessesToGc.size();
16117        if (N <= 0) {
16118            return;
16119        }
16120        if (canGcNowLocked()) {
16121            while (mProcessesToGc.size() > 0) {
16122                ProcessRecord proc = mProcessesToGc.remove(0);
16123                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16124                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16125                            <= SystemClock.uptimeMillis()) {
16126                        // To avoid spamming the system, we will GC processes one
16127                        // at a time, waiting a few seconds between each.
16128                        performAppGcLocked(proc);
16129                        scheduleAppGcsLocked();
16130                        return;
16131                    } else {
16132                        // It hasn't been long enough since we last GCed this
16133                        // process...  put it in the list to wait for its time.
16134                        addProcessToGcListLocked(proc);
16135                        break;
16136                    }
16137                }
16138            }
16139
16140            scheduleAppGcsLocked();
16141        }
16142    }
16143
16144    /**
16145     * If all looks good, perform GCs on all processes waiting for them.
16146     */
16147    final void performAppGcsIfAppropriateLocked() {
16148        if (canGcNowLocked()) {
16149            performAppGcsLocked();
16150            return;
16151        }
16152        // Still not idle, wait some more.
16153        scheduleAppGcsLocked();
16154    }
16155
16156    /**
16157     * Schedule the execution of all pending app GCs.
16158     */
16159    final void scheduleAppGcsLocked() {
16160        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16161
16162        if (mProcessesToGc.size() > 0) {
16163            // Schedule a GC for the time to the next process.
16164            ProcessRecord proc = mProcessesToGc.get(0);
16165            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16166
16167            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16168            long now = SystemClock.uptimeMillis();
16169            if (when < (now+GC_TIMEOUT)) {
16170                when = now + GC_TIMEOUT;
16171            }
16172            mHandler.sendMessageAtTime(msg, when);
16173        }
16174    }
16175
16176    /**
16177     * Add a process to the array of processes waiting to be GCed.  Keeps the
16178     * list in sorted order by the last GC time.  The process can't already be
16179     * on the list.
16180     */
16181    final void addProcessToGcListLocked(ProcessRecord proc) {
16182        boolean added = false;
16183        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16184            if (mProcessesToGc.get(i).lastRequestedGc <
16185                    proc.lastRequestedGc) {
16186                added = true;
16187                mProcessesToGc.add(i+1, proc);
16188                break;
16189            }
16190        }
16191        if (!added) {
16192            mProcessesToGc.add(0, proc);
16193        }
16194    }
16195
16196    /**
16197     * Set up to ask a process to GC itself.  This will either do it
16198     * immediately, or put it on the list of processes to gc the next
16199     * time things are idle.
16200     */
16201    final void scheduleAppGcLocked(ProcessRecord app) {
16202        long now = SystemClock.uptimeMillis();
16203        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16204            return;
16205        }
16206        if (!mProcessesToGc.contains(app)) {
16207            addProcessToGcListLocked(app);
16208            scheduleAppGcsLocked();
16209        }
16210    }
16211
16212    final void checkExcessivePowerUsageLocked(boolean doKills) {
16213        updateCpuStatsNow();
16214
16215        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16216        boolean doWakeKills = doKills;
16217        boolean doCpuKills = doKills;
16218        if (mLastPowerCheckRealtime == 0) {
16219            doWakeKills = false;
16220        }
16221        if (mLastPowerCheckUptime == 0) {
16222            doCpuKills = false;
16223        }
16224        if (stats.isScreenOn()) {
16225            doWakeKills = false;
16226        }
16227        final long curRealtime = SystemClock.elapsedRealtime();
16228        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16229        final long curUptime = SystemClock.uptimeMillis();
16230        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16231        mLastPowerCheckRealtime = curRealtime;
16232        mLastPowerCheckUptime = curUptime;
16233        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16234            doWakeKills = false;
16235        }
16236        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16237            doCpuKills = false;
16238        }
16239        int i = mLruProcesses.size();
16240        while (i > 0) {
16241            i--;
16242            ProcessRecord app = mLruProcesses.get(i);
16243            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16244                long wtime;
16245                synchronized (stats) {
16246                    wtime = stats.getProcessWakeTime(app.info.uid,
16247                            app.pid, curRealtime);
16248                }
16249                long wtimeUsed = wtime - app.lastWakeTime;
16250                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16251                if (DEBUG_POWER) {
16252                    StringBuilder sb = new StringBuilder(128);
16253                    sb.append("Wake for ");
16254                    app.toShortString(sb);
16255                    sb.append(": over ");
16256                    TimeUtils.formatDuration(realtimeSince, sb);
16257                    sb.append(" used ");
16258                    TimeUtils.formatDuration(wtimeUsed, sb);
16259                    sb.append(" (");
16260                    sb.append((wtimeUsed*100)/realtimeSince);
16261                    sb.append("%)");
16262                    Slog.i(TAG, sb.toString());
16263                    sb.setLength(0);
16264                    sb.append("CPU for ");
16265                    app.toShortString(sb);
16266                    sb.append(": over ");
16267                    TimeUtils.formatDuration(uptimeSince, sb);
16268                    sb.append(" used ");
16269                    TimeUtils.formatDuration(cputimeUsed, sb);
16270                    sb.append(" (");
16271                    sb.append((cputimeUsed*100)/uptimeSince);
16272                    sb.append("%)");
16273                    Slog.i(TAG, sb.toString());
16274                }
16275                // If a process has held a wake lock for more
16276                // than 50% of the time during this period,
16277                // that sounds bad.  Kill!
16278                if (doWakeKills && realtimeSince > 0
16279                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16280                    synchronized (stats) {
16281                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16282                                realtimeSince, wtimeUsed);
16283                    }
16284                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16285                            + " during " + realtimeSince);
16286                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16287                } else if (doCpuKills && uptimeSince > 0
16288                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16289                    synchronized (stats) {
16290                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16291                                uptimeSince, cputimeUsed);
16292                    }
16293                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16294                            + " during " + uptimeSince);
16295                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16296                } else {
16297                    app.lastWakeTime = wtime;
16298                    app.lastCpuTime = app.curCpuTime;
16299                }
16300            }
16301        }
16302    }
16303
16304    private final boolean applyOomAdjLocked(ProcessRecord app,
16305            ProcessRecord TOP_APP, boolean doingAll, long now) {
16306        boolean success = true;
16307
16308        if (app.curRawAdj != app.setRawAdj) {
16309            app.setRawAdj = app.curRawAdj;
16310        }
16311
16312        int changes = 0;
16313
16314        if (app.curAdj != app.setAdj) {
16315            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16316            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16317                TAG, "Set " + app.pid + " " + app.processName +
16318                " adj " + app.curAdj + ": " + app.adjType);
16319            app.setAdj = app.curAdj;
16320        }
16321
16322        if (app.setSchedGroup != app.curSchedGroup) {
16323            app.setSchedGroup = app.curSchedGroup;
16324            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16325                    "Setting process group of " + app.processName
16326                    + " to " + app.curSchedGroup);
16327            if (app.waitingToKill != null &&
16328                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16329                killUnneededProcessLocked(app, app.waitingToKill);
16330                success = false;
16331            } else {
16332                if (true) {
16333                    long oldId = Binder.clearCallingIdentity();
16334                    try {
16335                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16336                    } catch (Exception e) {
16337                        Slog.w(TAG, "Failed setting process group of " + app.pid
16338                                + " to " + app.curSchedGroup);
16339                        e.printStackTrace();
16340                    } finally {
16341                        Binder.restoreCallingIdentity(oldId);
16342                    }
16343                } else {
16344                    if (app.thread != null) {
16345                        try {
16346                            app.thread.setSchedulingGroup(app.curSchedGroup);
16347                        } catch (RemoteException e) {
16348                        }
16349                    }
16350                }
16351                Process.setSwappiness(app.pid,
16352                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16353            }
16354        }
16355        if (app.repForegroundActivities != app.foregroundActivities) {
16356            app.repForegroundActivities = app.foregroundActivities;
16357            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16358        }
16359        if (app.repProcState != app.curProcState) {
16360            app.repProcState = app.curProcState;
16361            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16362            if (app.thread != null) {
16363                try {
16364                    if (false) {
16365                        //RuntimeException h = new RuntimeException("here");
16366                        Slog.i(TAG, "Sending new process state " + app.repProcState
16367                                + " to " + app /*, h*/);
16368                    }
16369                    app.thread.setProcessState(app.repProcState);
16370                } catch (RemoteException e) {
16371                }
16372            }
16373        }
16374        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16375                app.setProcState)) {
16376            app.lastStateTime = now;
16377            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16378                    isSleeping(), now);
16379            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16380                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16381                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16382                    + (app.nextPssTime-now) + ": " + app);
16383        } else {
16384            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16385                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16386                requestPssLocked(app, app.setProcState);
16387                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16388                        isSleeping(), now);
16389            } else if (false && DEBUG_PSS) {
16390                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16391            }
16392        }
16393        if (app.setProcState != app.curProcState) {
16394            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16395                    "Proc state change of " + app.processName
16396                    + " to " + app.curProcState);
16397            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16398            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16399            if (setImportant && !curImportant) {
16400                // This app is no longer something we consider important enough to allow to
16401                // use arbitrary amounts of battery power.  Note
16402                // its current wake lock time to later know to kill it if
16403                // it is not behaving well.
16404                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16405                synchronized (stats) {
16406                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16407                            app.pid, SystemClock.elapsedRealtime());
16408                }
16409                app.lastCpuTime = app.curCpuTime;
16410
16411            }
16412            app.setProcState = app.curProcState;
16413            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16414                app.notCachedSinceIdle = false;
16415            }
16416            if (!doingAll) {
16417                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16418            } else {
16419                app.procStateChanged = true;
16420            }
16421        }
16422
16423        if (changes != 0) {
16424            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16425            int i = mPendingProcessChanges.size()-1;
16426            ProcessChangeItem item = null;
16427            while (i >= 0) {
16428                item = mPendingProcessChanges.get(i);
16429                if (item.pid == app.pid) {
16430                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16431                    break;
16432                }
16433                i--;
16434            }
16435            if (i < 0) {
16436                // No existing item in pending changes; need a new one.
16437                final int NA = mAvailProcessChanges.size();
16438                if (NA > 0) {
16439                    item = mAvailProcessChanges.remove(NA-1);
16440                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16441                } else {
16442                    item = new ProcessChangeItem();
16443                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16444                }
16445                item.changes = 0;
16446                item.pid = app.pid;
16447                item.uid = app.info.uid;
16448                if (mPendingProcessChanges.size() == 0) {
16449                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16450                            "*** Enqueueing dispatch processes changed!");
16451                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16452                }
16453                mPendingProcessChanges.add(item);
16454            }
16455            item.changes |= changes;
16456            item.processState = app.repProcState;
16457            item.foregroundActivities = app.repForegroundActivities;
16458            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16459                    + Integer.toHexString(System.identityHashCode(item))
16460                    + " " + app.toShortString() + ": changes=" + item.changes
16461                    + " procState=" + item.processState
16462                    + " foreground=" + item.foregroundActivities
16463                    + " type=" + app.adjType + " source=" + app.adjSource
16464                    + " target=" + app.adjTarget);
16465        }
16466
16467        return success;
16468    }
16469
16470    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16471        if (proc.thread != null) {
16472            if (proc.baseProcessTracker != null) {
16473                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16474            }
16475            if (proc.repProcState >= 0) {
16476                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16477                        proc.repProcState);
16478            }
16479        }
16480    }
16481
16482    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16483            ProcessRecord TOP_APP, boolean doingAll, long now) {
16484        if (app.thread == null) {
16485            return false;
16486        }
16487
16488        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16489
16490        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16491    }
16492
16493    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16494            boolean oomAdj) {
16495        if (isForeground != proc.foregroundServices) {
16496            proc.foregroundServices = isForeground;
16497            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16498                    proc.info.uid);
16499            if (isForeground) {
16500                if (curProcs == null) {
16501                    curProcs = new ArrayList<ProcessRecord>();
16502                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16503                }
16504                if (!curProcs.contains(proc)) {
16505                    curProcs.add(proc);
16506                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16507                            proc.info.packageName, proc.info.uid);
16508                }
16509            } else {
16510                if (curProcs != null) {
16511                    if (curProcs.remove(proc)) {
16512                        mBatteryStatsService.noteEvent(
16513                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16514                                proc.info.packageName, proc.info.uid);
16515                        if (curProcs.size() <= 0) {
16516                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16517                        }
16518                    }
16519                }
16520            }
16521            if (oomAdj) {
16522                updateOomAdjLocked();
16523            }
16524        }
16525    }
16526
16527    private final ActivityRecord resumedAppLocked() {
16528        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16529        String pkg;
16530        int uid;
16531        if (act != null) {
16532            pkg = act.packageName;
16533            uid = act.info.applicationInfo.uid;
16534        } else {
16535            pkg = null;
16536            uid = -1;
16537        }
16538        // Has the UID or resumed package name changed?
16539        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16540                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16541            if (mCurResumedPackage != null) {
16542                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16543                        mCurResumedPackage, mCurResumedUid);
16544            }
16545            mCurResumedPackage = pkg;
16546            mCurResumedUid = uid;
16547            if (mCurResumedPackage != null) {
16548                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16549                        mCurResumedPackage, mCurResumedUid);
16550            }
16551        }
16552        return act;
16553    }
16554
16555    final boolean updateOomAdjLocked(ProcessRecord app) {
16556        final ActivityRecord TOP_ACT = resumedAppLocked();
16557        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16558        final boolean wasCached = app.cached;
16559
16560        mAdjSeq++;
16561
16562        // This is the desired cached adjusment we want to tell it to use.
16563        // If our app is currently cached, we know it, and that is it.  Otherwise,
16564        // we don't know it yet, and it needs to now be cached we will then
16565        // need to do a complete oom adj.
16566        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16567                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16568        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16569                SystemClock.uptimeMillis());
16570        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16571            // Changed to/from cached state, so apps after it in the LRU
16572            // list may also be changed.
16573            updateOomAdjLocked();
16574        }
16575        return success;
16576    }
16577
16578    final void updateOomAdjLocked() {
16579        final ActivityRecord TOP_ACT = resumedAppLocked();
16580        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16581        final long now = SystemClock.uptimeMillis();
16582        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16583        final int N = mLruProcesses.size();
16584
16585        if (false) {
16586            RuntimeException e = new RuntimeException();
16587            e.fillInStackTrace();
16588            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16589        }
16590
16591        mAdjSeq++;
16592        mNewNumServiceProcs = 0;
16593        mNewNumAServiceProcs = 0;
16594
16595        final int emptyProcessLimit;
16596        final int cachedProcessLimit;
16597        if (mProcessLimit <= 0) {
16598            emptyProcessLimit = cachedProcessLimit = 0;
16599        } else if (mProcessLimit == 1) {
16600            emptyProcessLimit = 1;
16601            cachedProcessLimit = 0;
16602        } else {
16603            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16604            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16605        }
16606
16607        // Let's determine how many processes we have running vs.
16608        // how many slots we have for background processes; we may want
16609        // to put multiple processes in a slot of there are enough of
16610        // them.
16611        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16612                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16613        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16614        if (numEmptyProcs > cachedProcessLimit) {
16615            // If there are more empty processes than our limit on cached
16616            // processes, then use the cached process limit for the factor.
16617            // This ensures that the really old empty processes get pushed
16618            // down to the bottom, so if we are running low on memory we will
16619            // have a better chance at keeping around more cached processes
16620            // instead of a gazillion empty processes.
16621            numEmptyProcs = cachedProcessLimit;
16622        }
16623        int emptyFactor = numEmptyProcs/numSlots;
16624        if (emptyFactor < 1) emptyFactor = 1;
16625        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16626        if (cachedFactor < 1) cachedFactor = 1;
16627        int stepCached = 0;
16628        int stepEmpty = 0;
16629        int numCached = 0;
16630        int numEmpty = 0;
16631        int numTrimming = 0;
16632
16633        mNumNonCachedProcs = 0;
16634        mNumCachedHiddenProcs = 0;
16635
16636        // First update the OOM adjustment for each of the
16637        // application processes based on their current state.
16638        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16639        int nextCachedAdj = curCachedAdj+1;
16640        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16641        int nextEmptyAdj = curEmptyAdj+2;
16642        for (int i=N-1; i>=0; i--) {
16643            ProcessRecord app = mLruProcesses.get(i);
16644            if (!app.killedByAm && app.thread != null) {
16645                app.procStateChanged = false;
16646                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16647
16648                // If we haven't yet assigned the final cached adj
16649                // to the process, do that now.
16650                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16651                    switch (app.curProcState) {
16652                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16653                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16654                            // This process is a cached process holding activities...
16655                            // assign it the next cached value for that type, and then
16656                            // step that cached level.
16657                            app.curRawAdj = curCachedAdj;
16658                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16659                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16660                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16661                                    + ")");
16662                            if (curCachedAdj != nextCachedAdj) {
16663                                stepCached++;
16664                                if (stepCached >= cachedFactor) {
16665                                    stepCached = 0;
16666                                    curCachedAdj = nextCachedAdj;
16667                                    nextCachedAdj += 2;
16668                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16669                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16670                                    }
16671                                }
16672                            }
16673                            break;
16674                        default:
16675                            // For everything else, assign next empty cached process
16676                            // level and bump that up.  Note that this means that
16677                            // long-running services that have dropped down to the
16678                            // cached level will be treated as empty (since their process
16679                            // state is still as a service), which is what we want.
16680                            app.curRawAdj = curEmptyAdj;
16681                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16682                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16683                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16684                                    + ")");
16685                            if (curEmptyAdj != nextEmptyAdj) {
16686                                stepEmpty++;
16687                                if (stepEmpty >= emptyFactor) {
16688                                    stepEmpty = 0;
16689                                    curEmptyAdj = nextEmptyAdj;
16690                                    nextEmptyAdj += 2;
16691                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16692                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16693                                    }
16694                                }
16695                            }
16696                            break;
16697                    }
16698                }
16699
16700                applyOomAdjLocked(app, TOP_APP, true, now);
16701
16702                // Count the number of process types.
16703                switch (app.curProcState) {
16704                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16705                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16706                        mNumCachedHiddenProcs++;
16707                        numCached++;
16708                        if (numCached > cachedProcessLimit) {
16709                            killUnneededProcessLocked(app, "cached #" + numCached);
16710                        }
16711                        break;
16712                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16713                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16714                                && app.lastActivityTime < oldTime) {
16715                            killUnneededProcessLocked(app, "empty for "
16716                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16717                                    / 1000) + "s");
16718                        } else {
16719                            numEmpty++;
16720                            if (numEmpty > emptyProcessLimit) {
16721                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16722                            }
16723                        }
16724                        break;
16725                    default:
16726                        mNumNonCachedProcs++;
16727                        break;
16728                }
16729
16730                if (app.isolated && app.services.size() <= 0) {
16731                    // If this is an isolated process, and there are no
16732                    // services running in it, then the process is no longer
16733                    // needed.  We agressively kill these because we can by
16734                    // definition not re-use the same process again, and it is
16735                    // good to avoid having whatever code was running in them
16736                    // left sitting around after no longer needed.
16737                    killUnneededProcessLocked(app, "isolated not needed");
16738                }
16739
16740                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16741                        && !app.killedByAm) {
16742                    numTrimming++;
16743                }
16744            }
16745        }
16746
16747        mNumServiceProcs = mNewNumServiceProcs;
16748
16749        // Now determine the memory trimming level of background processes.
16750        // Unfortunately we need to start at the back of the list to do this
16751        // properly.  We only do this if the number of background apps we
16752        // are managing to keep around is less than half the maximum we desire;
16753        // if we are keeping a good number around, we'll let them use whatever
16754        // memory they want.
16755        final int numCachedAndEmpty = numCached + numEmpty;
16756        int memFactor;
16757        if (numCached <= ProcessList.TRIM_CACHED_APPS
16758                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16759            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16760                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16761            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16762                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16763            } else {
16764                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16765            }
16766        } else {
16767            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16768        }
16769        // We always allow the memory level to go up (better).  We only allow it to go
16770        // down if we are in a state where that is allowed, *and* the total number of processes
16771        // has gone down since last time.
16772        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16773                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16774                + " last=" + mLastNumProcesses);
16775        if (memFactor > mLastMemoryLevel) {
16776            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16777                memFactor = mLastMemoryLevel;
16778                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16779            }
16780        }
16781        mLastMemoryLevel = memFactor;
16782        mLastNumProcesses = mLruProcesses.size();
16783        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16784        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16785        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16786            if (mLowRamStartTime == 0) {
16787                mLowRamStartTime = now;
16788            }
16789            int step = 0;
16790            int fgTrimLevel;
16791            switch (memFactor) {
16792                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16793                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16794                    break;
16795                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16796                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16797                    break;
16798                default:
16799                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16800                    break;
16801            }
16802            int factor = numTrimming/3;
16803            int minFactor = 2;
16804            if (mHomeProcess != null) minFactor++;
16805            if (mPreviousProcess != null) minFactor++;
16806            if (factor < minFactor) factor = minFactor;
16807            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16808            for (int i=N-1; i>=0; i--) {
16809                ProcessRecord app = mLruProcesses.get(i);
16810                if (allChanged || app.procStateChanged) {
16811                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16812                    app.procStateChanged = false;
16813                }
16814                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16815                        && !app.killedByAm) {
16816                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16817                        try {
16818                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16819                                    "Trimming memory of " + app.processName
16820                                    + " to " + curLevel);
16821                            app.thread.scheduleTrimMemory(curLevel);
16822                        } catch (RemoteException e) {
16823                        }
16824                        if (false) {
16825                            // For now we won't do this; our memory trimming seems
16826                            // to be good enough at this point that destroying
16827                            // activities causes more harm than good.
16828                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16829                                    && app != mHomeProcess && app != mPreviousProcess) {
16830                                // Need to do this on its own message because the stack may not
16831                                // be in a consistent state at this point.
16832                                // For these apps we will also finish their activities
16833                                // to help them free memory.
16834                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16835                            }
16836                        }
16837                    }
16838                    app.trimMemoryLevel = curLevel;
16839                    step++;
16840                    if (step >= factor) {
16841                        step = 0;
16842                        switch (curLevel) {
16843                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16844                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16845                                break;
16846                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16847                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16848                                break;
16849                        }
16850                    }
16851                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16852                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16853                            && app.thread != null) {
16854                        try {
16855                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16856                                    "Trimming memory of heavy-weight " + app.processName
16857                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16858                            app.thread.scheduleTrimMemory(
16859                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16860                        } catch (RemoteException e) {
16861                        }
16862                    }
16863                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16864                } else {
16865                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16866                            || app.systemNoUi) && app.pendingUiClean) {
16867                        // If this application is now in the background and it
16868                        // had done UI, then give it the special trim level to
16869                        // have it free UI resources.
16870                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16871                        if (app.trimMemoryLevel < level && app.thread != null) {
16872                            try {
16873                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16874                                        "Trimming memory of bg-ui " + app.processName
16875                                        + " to " + level);
16876                                app.thread.scheduleTrimMemory(level);
16877                            } catch (RemoteException e) {
16878                            }
16879                        }
16880                        app.pendingUiClean = false;
16881                    }
16882                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16883                        try {
16884                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16885                                    "Trimming memory of fg " + app.processName
16886                                    + " to " + fgTrimLevel);
16887                            app.thread.scheduleTrimMemory(fgTrimLevel);
16888                        } catch (RemoteException e) {
16889                        }
16890                    }
16891                    app.trimMemoryLevel = fgTrimLevel;
16892                }
16893            }
16894        } else {
16895            if (mLowRamStartTime != 0) {
16896                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16897                mLowRamStartTime = 0;
16898            }
16899            for (int i=N-1; i>=0; i--) {
16900                ProcessRecord app = mLruProcesses.get(i);
16901                if (allChanged || app.procStateChanged) {
16902                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16903                    app.procStateChanged = false;
16904                }
16905                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16906                        || app.systemNoUi) && app.pendingUiClean) {
16907                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16908                            && app.thread != null) {
16909                        try {
16910                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16911                                    "Trimming memory of ui hidden " + app.processName
16912                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16913                            app.thread.scheduleTrimMemory(
16914                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16915                        } catch (RemoteException e) {
16916                        }
16917                    }
16918                    app.pendingUiClean = false;
16919                }
16920                app.trimMemoryLevel = 0;
16921            }
16922        }
16923
16924        if (mAlwaysFinishActivities) {
16925            // Need to do this on its own message because the stack may not
16926            // be in a consistent state at this point.
16927            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16928        }
16929
16930        if (allChanged) {
16931            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16932        }
16933
16934        if (mProcessStats.shouldWriteNowLocked(now)) {
16935            mHandler.post(new Runnable() {
16936                @Override public void run() {
16937                    synchronized (ActivityManagerService.this) {
16938                        mProcessStats.writeStateAsyncLocked();
16939                    }
16940                }
16941            });
16942        }
16943
16944        if (DEBUG_OOM_ADJ) {
16945            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16946        }
16947    }
16948
16949    final void trimApplications() {
16950        synchronized (this) {
16951            int i;
16952
16953            // First remove any unused application processes whose package
16954            // has been removed.
16955            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16956                final ProcessRecord app = mRemovedProcesses.get(i);
16957                if (app.activities.size() == 0
16958                        && app.curReceiver == null && app.services.size() == 0) {
16959                    Slog.i(
16960                        TAG, "Exiting empty application process "
16961                        + app.processName + " ("
16962                        + (app.thread != null ? app.thread.asBinder() : null)
16963                        + ")\n");
16964                    if (app.pid > 0 && app.pid != MY_PID) {
16965                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16966                                app.processName, app.setAdj, "empty");
16967                        app.killedByAm = true;
16968                        Process.killProcessQuiet(app.pid);
16969                        Process.killProcessGroup(app.info.uid, app.pid);
16970                    } else {
16971                        try {
16972                            app.thread.scheduleExit();
16973                        } catch (Exception e) {
16974                            // Ignore exceptions.
16975                        }
16976                    }
16977                    cleanUpApplicationRecordLocked(app, false, true, -1);
16978                    mRemovedProcesses.remove(i);
16979
16980                    if (app.persistent) {
16981                        addAppLocked(app.info, false, null /* ABI override */);
16982                    }
16983                }
16984            }
16985
16986            // Now update the oom adj for all processes.
16987            updateOomAdjLocked();
16988        }
16989    }
16990
16991    /** This method sends the specified signal to each of the persistent apps */
16992    public void signalPersistentProcesses(int sig) throws RemoteException {
16993        if (sig != Process.SIGNAL_USR1) {
16994            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16995        }
16996
16997        synchronized (this) {
16998            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16999                    != PackageManager.PERMISSION_GRANTED) {
17000                throw new SecurityException("Requires permission "
17001                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17002            }
17003
17004            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17005                ProcessRecord r = mLruProcesses.get(i);
17006                if (r.thread != null && r.persistent) {
17007                    Process.sendSignal(r.pid, sig);
17008                }
17009            }
17010        }
17011    }
17012
17013    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
17014        if (proc == null || proc == mProfileProc) {
17015            proc = mProfileProc;
17016            path = mProfileFile;
17017            profileType = mProfileType;
17018            clearProfilerLocked();
17019        }
17020        if (proc == null) {
17021            return;
17022        }
17023        try {
17024            proc.thread.profilerControl(false, path, null, profileType);
17025        } catch (RemoteException e) {
17026            throw new IllegalStateException("Process disappeared");
17027        }
17028    }
17029
17030    private void clearProfilerLocked() {
17031        if (mProfileFd != null) {
17032            try {
17033                mProfileFd.close();
17034            } catch (IOException e) {
17035            }
17036        }
17037        mProfileApp = null;
17038        mProfileProc = null;
17039        mProfileFile = null;
17040        mProfileType = 0;
17041        mAutoStopProfiler = false;
17042    }
17043
17044    public boolean profileControl(String process, int userId, boolean start,
17045            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
17046
17047        try {
17048            synchronized (this) {
17049                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17050                // its own permission.
17051                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17052                        != PackageManager.PERMISSION_GRANTED) {
17053                    throw new SecurityException("Requires permission "
17054                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17055                }
17056
17057                if (start && fd == null) {
17058                    throw new IllegalArgumentException("null fd");
17059                }
17060
17061                ProcessRecord proc = null;
17062                if (process != null) {
17063                    proc = findProcessLocked(process, userId, "profileControl");
17064                }
17065
17066                if (start && (proc == null || proc.thread == null)) {
17067                    throw new IllegalArgumentException("Unknown process: " + process);
17068                }
17069
17070                if (start) {
17071                    stopProfilerLocked(null, null, 0);
17072                    setProfileApp(proc.info, proc.processName, path, fd, false);
17073                    mProfileProc = proc;
17074                    mProfileType = profileType;
17075                    try {
17076                        fd = fd.dup();
17077                    } catch (IOException e) {
17078                        fd = null;
17079                    }
17080                    proc.thread.profilerControl(start, path, fd, profileType);
17081                    fd = null;
17082                    mProfileFd = null;
17083                } else {
17084                    stopProfilerLocked(proc, path, profileType);
17085                    if (fd != null) {
17086                        try {
17087                            fd.close();
17088                        } catch (IOException e) {
17089                        }
17090                    }
17091                }
17092
17093                return true;
17094            }
17095        } catch (RemoteException e) {
17096            throw new IllegalStateException("Process disappeared");
17097        } finally {
17098            if (fd != null) {
17099                try {
17100                    fd.close();
17101                } catch (IOException e) {
17102                }
17103            }
17104        }
17105    }
17106
17107    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17108        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17109                userId, true, ALLOW_FULL_ONLY, callName, null);
17110        ProcessRecord proc = null;
17111        try {
17112            int pid = Integer.parseInt(process);
17113            synchronized (mPidsSelfLocked) {
17114                proc = mPidsSelfLocked.get(pid);
17115            }
17116        } catch (NumberFormatException e) {
17117        }
17118
17119        if (proc == null) {
17120            ArrayMap<String, SparseArray<ProcessRecord>> all
17121                    = mProcessNames.getMap();
17122            SparseArray<ProcessRecord> procs = all.get(process);
17123            if (procs != null && procs.size() > 0) {
17124                proc = procs.valueAt(0);
17125                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17126                    for (int i=1; i<procs.size(); i++) {
17127                        ProcessRecord thisProc = procs.valueAt(i);
17128                        if (thisProc.userId == userId) {
17129                            proc = thisProc;
17130                            break;
17131                        }
17132                    }
17133                }
17134            }
17135        }
17136
17137        return proc;
17138    }
17139
17140    public boolean dumpHeap(String process, int userId, boolean managed,
17141            String path, ParcelFileDescriptor fd) throws RemoteException {
17142
17143        try {
17144            synchronized (this) {
17145                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17146                // its own permission (same as profileControl).
17147                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17148                        != PackageManager.PERMISSION_GRANTED) {
17149                    throw new SecurityException("Requires permission "
17150                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17151                }
17152
17153                if (fd == null) {
17154                    throw new IllegalArgumentException("null fd");
17155                }
17156
17157                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17158                if (proc == null || proc.thread == null) {
17159                    throw new IllegalArgumentException("Unknown process: " + process);
17160                }
17161
17162                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17163                if (!isDebuggable) {
17164                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17165                        throw new SecurityException("Process not debuggable: " + proc);
17166                    }
17167                }
17168
17169                proc.thread.dumpHeap(managed, path, fd);
17170                fd = null;
17171                return true;
17172            }
17173        } catch (RemoteException e) {
17174            throw new IllegalStateException("Process disappeared");
17175        } finally {
17176            if (fd != null) {
17177                try {
17178                    fd.close();
17179                } catch (IOException e) {
17180                }
17181            }
17182        }
17183    }
17184
17185    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17186    public void monitor() {
17187        synchronized (this) { }
17188    }
17189
17190    void onCoreSettingsChange(Bundle settings) {
17191        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17192            ProcessRecord processRecord = mLruProcesses.get(i);
17193            try {
17194                if (processRecord.thread != null) {
17195                    processRecord.thread.setCoreSettings(settings);
17196                }
17197            } catch (RemoteException re) {
17198                /* ignore */
17199            }
17200        }
17201    }
17202
17203    // Multi-user methods
17204
17205    /**
17206     * Start user, if its not already running, but don't bring it to foreground.
17207     */
17208    @Override
17209    public boolean startUserInBackground(final int userId) {
17210        return startUser(userId, /* foreground */ false);
17211    }
17212
17213    /**
17214     * Refreshes the list of users related to the current user when either a
17215     * user switch happens or when a new related user is started in the
17216     * background.
17217     */
17218    private void updateCurrentProfileIdsLocked() {
17219        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17220                mCurrentUserId, false /* enabledOnly */);
17221        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17222        for (int i = 0; i < currentProfileIds.length; i++) {
17223            currentProfileIds[i] = profiles.get(i).id;
17224        }
17225        mCurrentProfileIds = currentProfileIds;
17226
17227        synchronized (mUserProfileGroupIdsSelfLocked) {
17228            mUserProfileGroupIdsSelfLocked.clear();
17229            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17230            for (int i = 0; i < users.size(); i++) {
17231                UserInfo user = users.get(i);
17232                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17233                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17234                }
17235            }
17236        }
17237    }
17238
17239    private Set getProfileIdsLocked(int userId) {
17240        Set userIds = new HashSet<Integer>();
17241        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17242                userId, false /* enabledOnly */);
17243        for (UserInfo user : profiles) {
17244            userIds.add(Integer.valueOf(user.id));
17245        }
17246        return userIds;
17247    }
17248
17249    @Override
17250    public boolean switchUser(final int userId) {
17251        return startUser(userId, /* foregound */ true);
17252    }
17253
17254    private boolean startUser(final int userId, boolean foreground) {
17255        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17256                != PackageManager.PERMISSION_GRANTED) {
17257            String msg = "Permission Denial: switchUser() from pid="
17258                    + Binder.getCallingPid()
17259                    + ", uid=" + Binder.getCallingUid()
17260                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17261            Slog.w(TAG, msg);
17262            throw new SecurityException(msg);
17263        }
17264
17265        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17266
17267        final long ident = Binder.clearCallingIdentity();
17268        try {
17269            synchronized (this) {
17270                final int oldUserId = mCurrentUserId;
17271                if (oldUserId == userId) {
17272                    return true;
17273                }
17274
17275                mStackSupervisor.setLockTaskModeLocked(null, false);
17276
17277                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17278                if (userInfo == null) {
17279                    Slog.w(TAG, "No user info for user #" + userId);
17280                    return false;
17281                }
17282                if (foreground && userInfo.isManagedProfile()) {
17283                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17284                    return false;
17285                }
17286
17287                if (foreground) {
17288                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17289                            R.anim.screen_user_enter);
17290                }
17291
17292                boolean needStart = false;
17293
17294                // If the user we are switching to is not currently started, then
17295                // we need to start it now.
17296                if (mStartedUsers.get(userId) == null) {
17297                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17298                    updateStartedUserArrayLocked();
17299                    needStart = true;
17300                }
17301
17302                final Integer userIdInt = Integer.valueOf(userId);
17303                mUserLru.remove(userIdInt);
17304                mUserLru.add(userIdInt);
17305
17306                if (foreground) {
17307                    mCurrentUserId = userId;
17308                    updateCurrentProfileIdsLocked();
17309                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17310                    // Once the internal notion of the active user has switched, we lock the device
17311                    // with the option to show the user switcher on the keyguard.
17312                    mWindowManager.lockNow(null);
17313                } else {
17314                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17315                    updateCurrentProfileIdsLocked();
17316                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17317                    mUserLru.remove(currentUserIdInt);
17318                    mUserLru.add(currentUserIdInt);
17319                }
17320
17321                final UserStartedState uss = mStartedUsers.get(userId);
17322
17323                // Make sure user is in the started state.  If it is currently
17324                // stopping, we need to knock that off.
17325                if (uss.mState == UserStartedState.STATE_STOPPING) {
17326                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17327                    // so we can just fairly silently bring the user back from
17328                    // the almost-dead.
17329                    uss.mState = UserStartedState.STATE_RUNNING;
17330                    updateStartedUserArrayLocked();
17331                    needStart = true;
17332                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17333                    // This means ACTION_SHUTDOWN has been sent, so we will
17334                    // need to treat this as a new boot of the user.
17335                    uss.mState = UserStartedState.STATE_BOOTING;
17336                    updateStartedUserArrayLocked();
17337                    needStart = true;
17338                }
17339
17340                if (uss.mState == UserStartedState.STATE_BOOTING) {
17341                    // Booting up a new user, need to tell system services about it.
17342                    // Note that this is on the same handler as scheduling of broadcasts,
17343                    // which is important because it needs to go first.
17344                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
17345                }
17346
17347                if (foreground) {
17348                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17349                            oldUserId));
17350                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17351                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17352                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17353                            oldUserId, userId, uss));
17354                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17355                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17356                }
17357
17358                if (needStart) {
17359                    // Send USER_STARTED broadcast
17360                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17361                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17362                            | Intent.FLAG_RECEIVER_FOREGROUND);
17363                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17364                    broadcastIntentLocked(null, null, intent,
17365                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17366                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17367                }
17368
17369                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17370                    if (userId != UserHandle.USER_OWNER) {
17371                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17372                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17373                        broadcastIntentLocked(null, null, intent, null,
17374                                new IIntentReceiver.Stub() {
17375                                    public void performReceive(Intent intent, int resultCode,
17376                                            String data, Bundle extras, boolean ordered,
17377                                            boolean sticky, int sendingUser) {
17378                                        userInitialized(uss, userId);
17379                                    }
17380                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17381                                true, false, MY_PID, Process.SYSTEM_UID,
17382                                userId);
17383                        uss.initializing = true;
17384                    } else {
17385                        getUserManagerLocked().makeInitialized(userInfo.id);
17386                    }
17387                }
17388
17389                if (foreground) {
17390                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17391                    if (homeInFront) {
17392                        startHomeActivityLocked(userId);
17393                    } else {
17394                        mStackSupervisor.resumeTopActivitiesLocked();
17395                    }
17396                    EventLogTags.writeAmSwitchUser(userId);
17397                    getUserManagerLocked().userForeground(userId);
17398                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17399                } else {
17400                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17401                }
17402
17403                if (needStart) {
17404                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17405                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17406                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17407                    broadcastIntentLocked(null, null, intent,
17408                            null, new IIntentReceiver.Stub() {
17409                                @Override
17410                                public void performReceive(Intent intent, int resultCode, String data,
17411                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17412                                        throws RemoteException {
17413                                }
17414                            }, 0, null, null,
17415                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17416                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17417                }
17418            }
17419        } finally {
17420            Binder.restoreCallingIdentity(ident);
17421        }
17422
17423        return true;
17424    }
17425
17426    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17427        long ident = Binder.clearCallingIdentity();
17428        try {
17429            Intent intent;
17430            if (oldUserId >= 0) {
17431                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17432                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17433                int count = profiles.size();
17434                for (int i = 0; i < count; i++) {
17435                    int profileUserId = profiles.get(i).id;
17436                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17437                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17438                            | Intent.FLAG_RECEIVER_FOREGROUND);
17439                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17440                    broadcastIntentLocked(null, null, intent,
17441                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17442                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17443                }
17444            }
17445            if (newUserId >= 0) {
17446                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17447                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17448                int count = profiles.size();
17449                for (int i = 0; i < count; i++) {
17450                    int profileUserId = profiles.get(i).id;
17451                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17452                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17453                            | Intent.FLAG_RECEIVER_FOREGROUND);
17454                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17455                    broadcastIntentLocked(null, null, intent,
17456                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17457                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17458                }
17459                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17460                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17461                        | Intent.FLAG_RECEIVER_FOREGROUND);
17462                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17463                broadcastIntentLocked(null, null, intent,
17464                        null, null, 0, null, null,
17465                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17466                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17467            }
17468        } finally {
17469            Binder.restoreCallingIdentity(ident);
17470        }
17471    }
17472
17473    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17474            final int newUserId) {
17475        final int N = mUserSwitchObservers.beginBroadcast();
17476        if (N > 0) {
17477            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17478                int mCount = 0;
17479                @Override
17480                public void sendResult(Bundle data) throws RemoteException {
17481                    synchronized (ActivityManagerService.this) {
17482                        if (mCurUserSwitchCallback == this) {
17483                            mCount++;
17484                            if (mCount == N) {
17485                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17486                            }
17487                        }
17488                    }
17489                }
17490            };
17491            synchronized (this) {
17492                uss.switching = true;
17493                mCurUserSwitchCallback = callback;
17494            }
17495            for (int i=0; i<N; i++) {
17496                try {
17497                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17498                            newUserId, callback);
17499                } catch (RemoteException e) {
17500                }
17501            }
17502        } else {
17503            synchronized (this) {
17504                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17505            }
17506        }
17507        mUserSwitchObservers.finishBroadcast();
17508    }
17509
17510    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17511        synchronized (this) {
17512            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17513            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17514        }
17515    }
17516
17517    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17518        mCurUserSwitchCallback = null;
17519        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17520        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17521                oldUserId, newUserId, uss));
17522    }
17523
17524    void userInitialized(UserStartedState uss, int newUserId) {
17525        completeSwitchAndInitalize(uss, newUserId, true, false);
17526    }
17527
17528    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17529        completeSwitchAndInitalize(uss, newUserId, false, true);
17530    }
17531
17532    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17533            boolean clearInitializing, boolean clearSwitching) {
17534        boolean unfrozen = false;
17535        synchronized (this) {
17536            if (clearInitializing) {
17537                uss.initializing = false;
17538                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17539            }
17540            if (clearSwitching) {
17541                uss.switching = false;
17542            }
17543            if (!uss.switching && !uss.initializing) {
17544                mWindowManager.stopFreezingScreen();
17545                unfrozen = true;
17546            }
17547        }
17548        if (unfrozen) {
17549            final int N = mUserSwitchObservers.beginBroadcast();
17550            for (int i=0; i<N; i++) {
17551                try {
17552                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17553                } catch (RemoteException e) {
17554                }
17555            }
17556            mUserSwitchObservers.finishBroadcast();
17557        }
17558    }
17559
17560    void scheduleStartProfilesLocked() {
17561        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17562            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17563                    DateUtils.SECOND_IN_MILLIS);
17564        }
17565    }
17566
17567    void startProfilesLocked() {
17568        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17569        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17570                mCurrentUserId, false /* enabledOnly */);
17571        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17572        for (UserInfo user : profiles) {
17573            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17574                    && user.id != mCurrentUserId) {
17575                toStart.add(user);
17576            }
17577        }
17578        final int n = toStart.size();
17579        int i = 0;
17580        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17581            startUserInBackground(toStart.get(i).id);
17582        }
17583        if (i < n) {
17584            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17585        }
17586    }
17587
17588    void finishUserBoot(UserStartedState uss) {
17589        synchronized (this) {
17590            if (uss.mState == UserStartedState.STATE_BOOTING
17591                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17592                uss.mState = UserStartedState.STATE_RUNNING;
17593                final int userId = uss.mHandle.getIdentifier();
17594                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17595                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17596                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17597                broadcastIntentLocked(null, null, intent,
17598                        null, null, 0, null, null,
17599                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17600                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17601            }
17602        }
17603    }
17604
17605    void finishUserSwitch(UserStartedState uss) {
17606        synchronized (this) {
17607            finishUserBoot(uss);
17608
17609            startProfilesLocked();
17610
17611            int num = mUserLru.size();
17612            int i = 0;
17613            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17614                Integer oldUserId = mUserLru.get(i);
17615                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17616                if (oldUss == null) {
17617                    // Shouldn't happen, but be sane if it does.
17618                    mUserLru.remove(i);
17619                    num--;
17620                    continue;
17621                }
17622                if (oldUss.mState == UserStartedState.STATE_STOPPING
17623                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17624                    // This user is already stopping, doesn't count.
17625                    num--;
17626                    i++;
17627                    continue;
17628                }
17629                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17630                    // Owner and current can't be stopped, but count as running.
17631                    i++;
17632                    continue;
17633                }
17634                // This is a user to be stopped.
17635                stopUserLocked(oldUserId, null);
17636                num--;
17637                i++;
17638            }
17639        }
17640    }
17641
17642    @Override
17643    public int stopUser(final int userId, final IStopUserCallback callback) {
17644        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17645                != PackageManager.PERMISSION_GRANTED) {
17646            String msg = "Permission Denial: switchUser() from pid="
17647                    + Binder.getCallingPid()
17648                    + ", uid=" + Binder.getCallingUid()
17649                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17650            Slog.w(TAG, msg);
17651            throw new SecurityException(msg);
17652        }
17653        if (userId <= 0) {
17654            throw new IllegalArgumentException("Can't stop primary user " + userId);
17655        }
17656        synchronized (this) {
17657            return stopUserLocked(userId, callback);
17658        }
17659    }
17660
17661    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17662        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17663        if (mCurrentUserId == userId) {
17664            return ActivityManager.USER_OP_IS_CURRENT;
17665        }
17666
17667        final UserStartedState uss = mStartedUsers.get(userId);
17668        if (uss == null) {
17669            // User is not started, nothing to do...  but we do need to
17670            // callback if requested.
17671            if (callback != null) {
17672                mHandler.post(new Runnable() {
17673                    @Override
17674                    public void run() {
17675                        try {
17676                            callback.userStopped(userId);
17677                        } catch (RemoteException e) {
17678                        }
17679                    }
17680                });
17681            }
17682            return ActivityManager.USER_OP_SUCCESS;
17683        }
17684
17685        if (callback != null) {
17686            uss.mStopCallbacks.add(callback);
17687        }
17688
17689        if (uss.mState != UserStartedState.STATE_STOPPING
17690                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17691            uss.mState = UserStartedState.STATE_STOPPING;
17692            updateStartedUserArrayLocked();
17693
17694            long ident = Binder.clearCallingIdentity();
17695            try {
17696                // We are going to broadcast ACTION_USER_STOPPING and then
17697                // once that is done send a final ACTION_SHUTDOWN and then
17698                // stop the user.
17699                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17700                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17701                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17702                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17703                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17704                // This is the result receiver for the final shutdown broadcast.
17705                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17706                    @Override
17707                    public void performReceive(Intent intent, int resultCode, String data,
17708                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17709                        finishUserStop(uss);
17710                    }
17711                };
17712                // This is the result receiver for the initial stopping broadcast.
17713                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17714                    @Override
17715                    public void performReceive(Intent intent, int resultCode, String data,
17716                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17717                        // On to the next.
17718                        synchronized (ActivityManagerService.this) {
17719                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17720                                // Whoops, we are being started back up.  Abort, abort!
17721                                return;
17722                            }
17723                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17724                        }
17725                        mBatteryStatsService.noteEvent(
17726                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17727                                Integer.toString(userId), userId);
17728                        mSystemServiceManager.stopUser(userId);
17729                        broadcastIntentLocked(null, null, shutdownIntent,
17730                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17731                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17732                    }
17733                };
17734                // Kick things off.
17735                broadcastIntentLocked(null, null, stoppingIntent,
17736                        null, stoppingReceiver, 0, null, null,
17737                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17738                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17739            } finally {
17740                Binder.restoreCallingIdentity(ident);
17741            }
17742        }
17743
17744        return ActivityManager.USER_OP_SUCCESS;
17745    }
17746
17747    void finishUserStop(UserStartedState uss) {
17748        final int userId = uss.mHandle.getIdentifier();
17749        boolean stopped;
17750        ArrayList<IStopUserCallback> callbacks;
17751        synchronized (this) {
17752            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17753            if (mStartedUsers.get(userId) != uss) {
17754                stopped = false;
17755            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17756                stopped = false;
17757            } else {
17758                stopped = true;
17759                // User can no longer run.
17760                mStartedUsers.remove(userId);
17761                mUserLru.remove(Integer.valueOf(userId));
17762                updateStartedUserArrayLocked();
17763
17764                // Clean up all state and processes associated with the user.
17765                // Kill all the processes for the user.
17766                forceStopUserLocked(userId, "finish user");
17767            }
17768
17769            // Explicitly remove the old information in mRecentTasks.
17770            removeRecentTasksForUserLocked(userId);
17771        }
17772
17773        for (int i=0; i<callbacks.size(); i++) {
17774            try {
17775                if (stopped) callbacks.get(i).userStopped(userId);
17776                else callbacks.get(i).userStopAborted(userId);
17777            } catch (RemoteException e) {
17778            }
17779        }
17780
17781        if (stopped) {
17782            mSystemServiceManager.cleanupUser(userId);
17783            synchronized (this) {
17784                mStackSupervisor.removeUserLocked(userId);
17785            }
17786        }
17787    }
17788
17789    @Override
17790    public UserInfo getCurrentUser() {
17791        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17792                != PackageManager.PERMISSION_GRANTED) && (
17793                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17794                != PackageManager.PERMISSION_GRANTED)) {
17795            String msg = "Permission Denial: getCurrentUser() from pid="
17796                    + Binder.getCallingPid()
17797                    + ", uid=" + Binder.getCallingUid()
17798                    + " requires " + INTERACT_ACROSS_USERS;
17799            Slog.w(TAG, msg);
17800            throw new SecurityException(msg);
17801        }
17802        synchronized (this) {
17803            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17804        }
17805    }
17806
17807    int getCurrentUserIdLocked() {
17808        return mCurrentUserId;
17809    }
17810
17811    @Override
17812    public boolean isUserRunning(int userId, boolean orStopped) {
17813        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17814                != PackageManager.PERMISSION_GRANTED) {
17815            String msg = "Permission Denial: isUserRunning() from pid="
17816                    + Binder.getCallingPid()
17817                    + ", uid=" + Binder.getCallingUid()
17818                    + " requires " + INTERACT_ACROSS_USERS;
17819            Slog.w(TAG, msg);
17820            throw new SecurityException(msg);
17821        }
17822        synchronized (this) {
17823            return isUserRunningLocked(userId, orStopped);
17824        }
17825    }
17826
17827    boolean isUserRunningLocked(int userId, boolean orStopped) {
17828        UserStartedState state = mStartedUsers.get(userId);
17829        if (state == null) {
17830            return false;
17831        }
17832        if (orStopped) {
17833            return true;
17834        }
17835        return state.mState != UserStartedState.STATE_STOPPING
17836                && state.mState != UserStartedState.STATE_SHUTDOWN;
17837    }
17838
17839    @Override
17840    public int[] getRunningUserIds() {
17841        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17842                != PackageManager.PERMISSION_GRANTED) {
17843            String msg = "Permission Denial: isUserRunning() from pid="
17844                    + Binder.getCallingPid()
17845                    + ", uid=" + Binder.getCallingUid()
17846                    + " requires " + INTERACT_ACROSS_USERS;
17847            Slog.w(TAG, msg);
17848            throw new SecurityException(msg);
17849        }
17850        synchronized (this) {
17851            return mStartedUserArray;
17852        }
17853    }
17854
17855    private void updateStartedUserArrayLocked() {
17856        int num = 0;
17857        for (int i=0; i<mStartedUsers.size();  i++) {
17858            UserStartedState uss = mStartedUsers.valueAt(i);
17859            // This list does not include stopping users.
17860            if (uss.mState != UserStartedState.STATE_STOPPING
17861                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17862                num++;
17863            }
17864        }
17865        mStartedUserArray = new int[num];
17866        num = 0;
17867        for (int i=0; i<mStartedUsers.size();  i++) {
17868            UserStartedState uss = mStartedUsers.valueAt(i);
17869            if (uss.mState != UserStartedState.STATE_STOPPING
17870                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17871                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17872                num++;
17873            }
17874        }
17875    }
17876
17877    @Override
17878    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17879        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17880                != PackageManager.PERMISSION_GRANTED) {
17881            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17882                    + Binder.getCallingPid()
17883                    + ", uid=" + Binder.getCallingUid()
17884                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17885            Slog.w(TAG, msg);
17886            throw new SecurityException(msg);
17887        }
17888
17889        mUserSwitchObservers.register(observer);
17890    }
17891
17892    @Override
17893    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17894        mUserSwitchObservers.unregister(observer);
17895    }
17896
17897    private boolean userExists(int userId) {
17898        if (userId == 0) {
17899            return true;
17900        }
17901        UserManagerService ums = getUserManagerLocked();
17902        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17903    }
17904
17905    int[] getUsersLocked() {
17906        UserManagerService ums = getUserManagerLocked();
17907        return ums != null ? ums.getUserIds() : new int[] { 0 };
17908    }
17909
17910    UserManagerService getUserManagerLocked() {
17911        if (mUserManager == null) {
17912            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17913            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17914        }
17915        return mUserManager;
17916    }
17917
17918    private int applyUserId(int uid, int userId) {
17919        return UserHandle.getUid(userId, uid);
17920    }
17921
17922    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17923        if (info == null) return null;
17924        ApplicationInfo newInfo = new ApplicationInfo(info);
17925        newInfo.uid = applyUserId(info.uid, userId);
17926        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17927                + info.packageName;
17928        return newInfo;
17929    }
17930
17931    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17932        if (aInfo == null
17933                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17934            return aInfo;
17935        }
17936
17937        ActivityInfo info = new ActivityInfo(aInfo);
17938        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17939        return info;
17940    }
17941
17942    private final class LocalService extends ActivityManagerInternal {
17943        @Override
17944        public void goingToSleep() {
17945            ActivityManagerService.this.goingToSleep();
17946        }
17947
17948        @Override
17949        public void wakingUp() {
17950            ActivityManagerService.this.wakingUp();
17951        }
17952
17953        @Override
17954        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
17955                String processName, String abiOverride, int uid, Runnable crashHandler) {
17956            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
17957                    processName, abiOverride, uid, crashHandler);
17958        }
17959    }
17960
17961    /**
17962     * An implementation of IAppTask, that allows an app to manage its own tasks via
17963     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17964     * only the process that calls getAppTasks() can call the AppTask methods.
17965     */
17966    class AppTaskImpl extends IAppTask.Stub {
17967        private int mTaskId;
17968        private int mCallingUid;
17969
17970        public AppTaskImpl(int taskId, int callingUid) {
17971            mTaskId = taskId;
17972            mCallingUid = callingUid;
17973        }
17974
17975        @Override
17976        public void finishAndRemoveTask() {
17977            // Ensure that we are called from the same process that created this AppTask
17978            if (mCallingUid != Binder.getCallingUid()) {
17979                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17980                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17981                return;
17982            }
17983
17984            synchronized (ActivityManagerService.this) {
17985                long origId = Binder.clearCallingIdentity();
17986                try {
17987                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17988                    if (tr != null) {
17989                        // Only kill the process if we are not a new document
17990                        int flags = tr.getBaseIntent().getFlags();
17991                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17992                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17993                        removeTaskByIdLocked(mTaskId,
17994                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17995                    }
17996                } finally {
17997                    Binder.restoreCallingIdentity(origId);
17998                }
17999            }
18000        }
18001
18002        @Override
18003        public ActivityManager.RecentTaskInfo getTaskInfo() {
18004            // Ensure that we are called from the same process that created this AppTask
18005            if (mCallingUid != Binder.getCallingUid()) {
18006                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
18007                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18008                return null;
18009            }
18010
18011            synchronized (ActivityManagerService.this) {
18012                long origId = Binder.clearCallingIdentity();
18013                try {
18014                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18015                    if (tr != null) {
18016                        return createRecentTaskInfoFromTaskRecord(tr);
18017                    }
18018                } finally {
18019                    Binder.restoreCallingIdentity(origId);
18020                }
18021                return null;
18022            }
18023        }
18024    }
18025}
18026