ActivityManagerService.java revision 028ceeb472801bcfa5844fc89ed0da8463098824
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, getClass().getClassLoader());
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 int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3438            Intent intent, String resolvedType, IBinder resultTo,
3439            String resultWho, int requestCode, int startFlags,
3440            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3441
3442        // This is very dangerous -- it allows you to perform a start activity (including
3443        // permission grants) as any app that may launch one of your own activities.  So
3444        // we will only allow this to be done from activities that are part of the core framework,
3445        // and then only when they are running as the system.
3446        final ActivityRecord sourceRecord;
3447        final int targetUid;
3448        final String targetPackage;
3449        synchronized (this) {
3450            if (resultTo == null) {
3451                throw new SecurityException("Must be called from an activity");
3452            }
3453            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3454            if (sourceRecord == null) {
3455                throw new SecurityException("Called with bad activity token: " + resultTo);
3456            }
3457            if (!sourceRecord.info.packageName.equals("android")) {
3458                throw new SecurityException(
3459                        "Must be called from an activity that is declared in the android package");
3460            }
3461            if (sourceRecord.app == null) {
3462                throw new SecurityException("Called without a process attached to activity");
3463            }
3464            if (sourceRecord.app.uid != Process.SYSTEM_UID) {
3465                // This is still okay, as long as this activity is running under the
3466                // uid of the original calling activity.
3467                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3468                    throw new SecurityException(
3469                            "Calling activity in uid " + sourceRecord.app.uid
3470                                    + " must be system uid or original calling uid "
3471                                    + sourceRecord.launchedFromUid);
3472                }
3473            }
3474            targetUid = sourceRecord.launchedFromUid;
3475            targetPackage = sourceRecord.launchedFromPackage;
3476        }
3477
3478        // TODO: Switch to user app stacks here.
3479        try {
3480            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3481                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3482                    null, null, null, null, options, UserHandle.getUserId(targetUid), null);
3483            return ret;
3484        } catch (SecurityException e) {
3485            // XXX need to figure out how to propagate to original app.
3486            // A SecurityException here is generally actually a fault of the original
3487            // calling activity (such as a fairly granting permissions), so propagate it
3488            // back to them.
3489            /*
3490            StringBuilder msg = new StringBuilder();
3491            msg.append("While launching");
3492            msg.append(intent.toString());
3493            msg.append(": ");
3494            msg.append(e.getMessage());
3495            */
3496            throw e;
3497        }
3498    }
3499
3500    @Override
3501    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3502            Intent intent, String resolvedType, IBinder resultTo,
3503            String resultWho, int requestCode, int startFlags, String profileFile,
3504            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3505        enforceNotIsolatedCaller("startActivityAndWait");
3506        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3507                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3508        WaitResult res = new WaitResult();
3509        // TODO: Switch to user app stacks here.
3510        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3511                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3512                res, null, options, userId, null);
3513        return res;
3514    }
3515
3516    @Override
3517    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3518            Intent intent, String resolvedType, IBinder resultTo,
3519            String resultWho, int requestCode, int startFlags, Configuration config,
3520            Bundle options, int userId) {
3521        enforceNotIsolatedCaller("startActivityWithConfig");
3522        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3523                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3524        // TODO: Switch to user app stacks here.
3525        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3526                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3527                null, null, null, config, options, userId, null);
3528        return ret;
3529    }
3530
3531    @Override
3532    public int startActivityIntentSender(IApplicationThread caller,
3533            IntentSender intent, Intent fillInIntent, String resolvedType,
3534            IBinder resultTo, String resultWho, int requestCode,
3535            int flagsMask, int flagsValues, Bundle options) {
3536        enforceNotIsolatedCaller("startActivityIntentSender");
3537        // Refuse possible leaked file descriptors
3538        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3539            throw new IllegalArgumentException("File descriptors passed in Intent");
3540        }
3541
3542        IIntentSender sender = intent.getTarget();
3543        if (!(sender instanceof PendingIntentRecord)) {
3544            throw new IllegalArgumentException("Bad PendingIntent object");
3545        }
3546
3547        PendingIntentRecord pir = (PendingIntentRecord)sender;
3548
3549        synchronized (this) {
3550            // If this is coming from the currently resumed activity, it is
3551            // effectively saying that app switches are allowed at this point.
3552            final ActivityStack stack = getFocusedStack();
3553            if (stack.mResumedActivity != null &&
3554                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3555                mAppSwitchesAllowedTime = 0;
3556            }
3557        }
3558        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3559                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3560        return ret;
3561    }
3562
3563    @Override
3564    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3565            Intent intent, String resolvedType, IVoiceInteractionSession session,
3566            IVoiceInteractor interactor, int startFlags, String profileFile,
3567            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3568        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3569                != PackageManager.PERMISSION_GRANTED) {
3570            String msg = "Permission Denial: startVoiceActivity() from pid="
3571                    + Binder.getCallingPid()
3572                    + ", uid=" + Binder.getCallingUid()
3573                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3574            Slog.w(TAG, msg);
3575            throw new SecurityException(msg);
3576        }
3577        if (session == null || interactor == null) {
3578            throw new NullPointerException("null session or interactor");
3579        }
3580        userId = handleIncomingUser(callingPid, callingUid, userId,
3581                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3582        // TODO: Switch to user app stacks here.
3583        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3584                resolvedType, session, interactor, null, null, 0, startFlags,
3585                profileFile, profileFd, null, null, options, userId, null);
3586    }
3587
3588    @Override
3589    public boolean startNextMatchingActivity(IBinder callingActivity,
3590            Intent intent, Bundle options) {
3591        // Refuse possible leaked file descriptors
3592        if (intent != null && intent.hasFileDescriptors() == true) {
3593            throw new IllegalArgumentException("File descriptors passed in Intent");
3594        }
3595
3596        synchronized (this) {
3597            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3598            if (r == null) {
3599                ActivityOptions.abort(options);
3600                return false;
3601            }
3602            if (r.app == null || r.app.thread == null) {
3603                // The caller is not running...  d'oh!
3604                ActivityOptions.abort(options);
3605                return false;
3606            }
3607            intent = new Intent(intent);
3608            // The caller is not allowed to change the data.
3609            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3610            // And we are resetting to find the next component...
3611            intent.setComponent(null);
3612
3613            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3614
3615            ActivityInfo aInfo = null;
3616            try {
3617                List<ResolveInfo> resolves =
3618                    AppGlobals.getPackageManager().queryIntentActivities(
3619                            intent, r.resolvedType,
3620                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3621                            UserHandle.getCallingUserId());
3622
3623                // Look for the original activity in the list...
3624                final int N = resolves != null ? resolves.size() : 0;
3625                for (int i=0; i<N; i++) {
3626                    ResolveInfo rInfo = resolves.get(i);
3627                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3628                            && rInfo.activityInfo.name.equals(r.info.name)) {
3629                        // We found the current one...  the next matching is
3630                        // after it.
3631                        i++;
3632                        if (i<N) {
3633                            aInfo = resolves.get(i).activityInfo;
3634                        }
3635                        if (debug) {
3636                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3637                                    + "/" + r.info.name);
3638                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3639                                    + "/" + aInfo.name);
3640                        }
3641                        break;
3642                    }
3643                }
3644            } catch (RemoteException e) {
3645            }
3646
3647            if (aInfo == null) {
3648                // Nobody who is next!
3649                ActivityOptions.abort(options);
3650                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3651                return false;
3652            }
3653
3654            intent.setComponent(new ComponentName(
3655                    aInfo.applicationInfo.packageName, aInfo.name));
3656            intent.setFlags(intent.getFlags()&~(
3657                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3658                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3659                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3660                    Intent.FLAG_ACTIVITY_NEW_TASK));
3661
3662            // Okay now we need to start the new activity, replacing the
3663            // currently running activity.  This is a little tricky because
3664            // we want to start the new one as if the current one is finished,
3665            // but not finish the current one first so that there is no flicker.
3666            // And thus...
3667            final boolean wasFinishing = r.finishing;
3668            r.finishing = true;
3669
3670            // Propagate reply information over to the new activity.
3671            final ActivityRecord resultTo = r.resultTo;
3672            final String resultWho = r.resultWho;
3673            final int requestCode = r.requestCode;
3674            r.resultTo = null;
3675            if (resultTo != null) {
3676                resultTo.removeResultsLocked(r, resultWho, requestCode);
3677            }
3678
3679            final long origId = Binder.clearCallingIdentity();
3680            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3681                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3682                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3683                    options, false, null, null);
3684            Binder.restoreCallingIdentity(origId);
3685
3686            r.finishing = wasFinishing;
3687            if (res != ActivityManager.START_SUCCESS) {
3688                return false;
3689            }
3690            return true;
3691        }
3692    }
3693
3694    @Override
3695    public final int startActivityFromRecents(int taskId, Bundle options) {
3696        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3697            String msg = "Permission Denial: startActivityFromRecents called without " +
3698                    START_TASKS_FROM_RECENTS;
3699            Slog.w(TAG, msg);
3700            throw new SecurityException(msg);
3701        }
3702        final int callingUid;
3703        final String callingPackage;
3704        final Intent intent;
3705        final int userId;
3706        synchronized (this) {
3707            final TaskRecord task = recentTaskForIdLocked(taskId);
3708            if (task == null) {
3709                throw new ActivityNotFoundException("Task " + taskId + " not found.");
3710            }
3711            callingUid = task.mCallingUid;
3712            callingPackage = task.mCallingPackage;
3713            intent = task.intent;
3714            userId = task.userId;
3715        }
3716        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3717                options, userId, null);
3718    }
3719
3720    final int startActivityInPackage(int uid, String callingPackage,
3721            Intent intent, String resolvedType, IBinder resultTo,
3722            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3723                    IActivityContainer container) {
3724
3725        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3726                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3727
3728        // TODO: Switch to user app stacks here.
3729        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3730                null, null, resultTo, resultWho, requestCode, startFlags,
3731                null, null, null, null, options, userId, container);
3732        return ret;
3733    }
3734
3735    @Override
3736    public final int startActivities(IApplicationThread caller, String callingPackage,
3737            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3738            int userId) {
3739        enforceNotIsolatedCaller("startActivities");
3740        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3741                false, ALLOW_FULL_ONLY, "startActivity", null);
3742        // TODO: Switch to user app stacks here.
3743        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3744                resolvedTypes, resultTo, options, userId);
3745        return ret;
3746    }
3747
3748    final int startActivitiesInPackage(int uid, String callingPackage,
3749            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3750            Bundle options, int userId) {
3751
3752        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3753                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3754        // TODO: Switch to user app stacks here.
3755        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3756                resultTo, options, userId);
3757        return ret;
3758    }
3759
3760    //explicitly remove thd old information in mRecentTasks when removing existing user.
3761    private void removeRecentTasksForUserLocked(int userId) {
3762        if(userId <= 0) {
3763            Slog.i(TAG, "Can't remove recent task on user " + userId);
3764            return;
3765        }
3766
3767        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3768            TaskRecord tr = mRecentTasks.get(i);
3769            if (tr.userId == userId) {
3770                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3771                        + " when finishing user" + userId);
3772                tr.disposeThumbnail();
3773                mRecentTasks.remove(i);
3774            }
3775        }
3776
3777        // Remove tasks from persistent storage.
3778        mTaskPersister.wakeup(null, true);
3779    }
3780
3781    final void addRecentTaskLocked(TaskRecord task) {
3782        int N = mRecentTasks.size();
3783        // Quick case: check if the top-most recent task is the same.
3784        if (N > 0 && mRecentTasks.get(0) == task) {
3785            return;
3786        }
3787        // Another quick case: never add voice sessions.
3788        if (task.voiceSession != null) {
3789            return;
3790        }
3791        // Remove any existing entries that are the same kind of task.
3792        final Intent intent = task.intent;
3793        final boolean document = intent != null && intent.isDocument();
3794        final ComponentName comp = intent.getComponent();
3795
3796        int maxRecents = task.maxRecents - 1;
3797        for (int i=0; i<N; i++) {
3798            final TaskRecord tr = mRecentTasks.get(i);
3799            if (task != tr) {
3800                if (task.userId != tr.userId) {
3801                    continue;
3802                }
3803                if (i > MAX_RECENT_BITMAPS) {
3804                    tr.freeLastThumbnail();
3805                }
3806                final Intent trIntent = tr.intent;
3807                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3808                    (intent == null || !intent.filterEquals(trIntent))) {
3809                    continue;
3810                }
3811                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3812                if (document && trIsDocument) {
3813                    // These are the same document activity (not necessarily the same doc).
3814                    if (maxRecents > 0) {
3815                        --maxRecents;
3816                        continue;
3817                    }
3818                    // Hit the maximum number of documents for this task. Fall through
3819                    // and remove this document from recents.
3820                } else if (document || trIsDocument) {
3821                    // Only one of these is a document. Not the droid we're looking for.
3822                    continue;
3823                }
3824            }
3825
3826            // Either task and tr are the same or, their affinities match or their intents match
3827            // and neither of them is a document, or they are documents using the same activity
3828            // and their maxRecents has been reached.
3829            tr.disposeThumbnail();
3830            mRecentTasks.remove(i);
3831            if (task != tr) {
3832                tr.closeRecentsChain();
3833            }
3834            i--;
3835            N--;
3836            if (task.intent == null) {
3837                // If the new recent task we are adding is not fully
3838                // specified, then replace it with the existing recent task.
3839                task = tr;
3840            }
3841            notifyTaskPersisterLocked(tr, false);
3842        }
3843        if (N >= MAX_RECENT_TASKS) {
3844            final TaskRecord tr = mRecentTasks.remove(N - 1);
3845            tr.disposeThumbnail();
3846            tr.closeRecentsChain();
3847        }
3848        mRecentTasks.add(0, task);
3849    }
3850
3851    @Override
3852    public void reportActivityFullyDrawn(IBinder token) {
3853        synchronized (this) {
3854            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3855            if (r == null) {
3856                return;
3857            }
3858            r.reportFullyDrawnLocked();
3859        }
3860    }
3861
3862    @Override
3863    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3864        synchronized (this) {
3865            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3866            if (r == null) {
3867                return;
3868            }
3869            final long origId = Binder.clearCallingIdentity();
3870            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3871            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3872                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3873            if (config != null) {
3874                r.frozenBeforeDestroy = true;
3875                if (!updateConfigurationLocked(config, r, false, false)) {
3876                    mStackSupervisor.resumeTopActivitiesLocked();
3877                }
3878            }
3879            Binder.restoreCallingIdentity(origId);
3880        }
3881    }
3882
3883    @Override
3884    public int getRequestedOrientation(IBinder token) {
3885        synchronized (this) {
3886            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3887            if (r == null) {
3888                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3889            }
3890            return mWindowManager.getAppOrientation(r.appToken);
3891        }
3892    }
3893
3894    /**
3895     * This is the internal entry point for handling Activity.finish().
3896     *
3897     * @param token The Binder token referencing the Activity we want to finish.
3898     * @param resultCode Result code, if any, from this Activity.
3899     * @param resultData Result data (Intent), if any, from this Activity.
3900     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3901     *            the root Activity in the task.
3902     *
3903     * @return Returns true if the activity successfully finished, or false if it is still running.
3904     */
3905    @Override
3906    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3907            boolean finishTask) {
3908        // Refuse possible leaked file descriptors
3909        if (resultData != null && resultData.hasFileDescriptors() == true) {
3910            throw new IllegalArgumentException("File descriptors passed in Intent");
3911        }
3912
3913        synchronized(this) {
3914            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3915            if (r == null) {
3916                return true;
3917            }
3918            // Keep track of the root activity of the task before we finish it
3919            TaskRecord tr = r.task;
3920            ActivityRecord rootR = tr.getRootActivity();
3921            // Do not allow task to finish in Lock Task mode.
3922            if (tr == mStackSupervisor.mLockTaskModeTask) {
3923                if (rootR == r) {
3924                    mStackSupervisor.showLockTaskToast();
3925                    return false;
3926                }
3927            }
3928            if (mController != null) {
3929                // Find the first activity that is not finishing.
3930                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3931                if (next != null) {
3932                    // ask watcher if this is allowed
3933                    boolean resumeOK = true;
3934                    try {
3935                        resumeOK = mController.activityResuming(next.packageName);
3936                    } catch (RemoteException e) {
3937                        mController = null;
3938                        Watchdog.getInstance().setActivityController(null);
3939                    }
3940
3941                    if (!resumeOK) {
3942                        return false;
3943                    }
3944                }
3945            }
3946            final long origId = Binder.clearCallingIdentity();
3947            try {
3948                boolean res;
3949                if (finishTask && r == rootR) {
3950                    // If requested, remove the task that is associated to this activity only if it
3951                    // was the root activity in the task.  The result code and data is ignored because
3952                    // we don't support returning them across task boundaries.
3953                    res = removeTaskByIdLocked(tr.taskId, 0);
3954                } else {
3955                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3956                            resultData, "app-request", true);
3957                }
3958                return res;
3959            } finally {
3960                Binder.restoreCallingIdentity(origId);
3961            }
3962        }
3963    }
3964
3965    @Override
3966    public final void finishHeavyWeightApp() {
3967        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3968                != PackageManager.PERMISSION_GRANTED) {
3969            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3970                    + Binder.getCallingPid()
3971                    + ", uid=" + Binder.getCallingUid()
3972                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3973            Slog.w(TAG, msg);
3974            throw new SecurityException(msg);
3975        }
3976
3977        synchronized(this) {
3978            if (mHeavyWeightProcess == null) {
3979                return;
3980            }
3981
3982            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3983                    mHeavyWeightProcess.activities);
3984            for (int i=0; i<activities.size(); i++) {
3985                ActivityRecord r = activities.get(i);
3986                if (!r.finishing) {
3987                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3988                            null, "finish-heavy", true);
3989                }
3990            }
3991
3992            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3993                    mHeavyWeightProcess.userId, 0));
3994            mHeavyWeightProcess = null;
3995        }
3996    }
3997
3998    @Override
3999    public void crashApplication(int uid, int initialPid, String packageName,
4000            String message) {
4001        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4002                != PackageManager.PERMISSION_GRANTED) {
4003            String msg = "Permission Denial: crashApplication() from pid="
4004                    + Binder.getCallingPid()
4005                    + ", uid=" + Binder.getCallingUid()
4006                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4007            Slog.w(TAG, msg);
4008            throw new SecurityException(msg);
4009        }
4010
4011        synchronized(this) {
4012            ProcessRecord proc = null;
4013
4014            // Figure out which process to kill.  We don't trust that initialPid
4015            // still has any relation to current pids, so must scan through the
4016            // list.
4017            synchronized (mPidsSelfLocked) {
4018                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4019                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4020                    if (p.uid != uid) {
4021                        continue;
4022                    }
4023                    if (p.pid == initialPid) {
4024                        proc = p;
4025                        break;
4026                    }
4027                    if (p.pkgList.containsKey(packageName)) {
4028                        proc = p;
4029                    }
4030                }
4031            }
4032
4033            if (proc == null) {
4034                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4035                        + " initialPid=" + initialPid
4036                        + " packageName=" + packageName);
4037                return;
4038            }
4039
4040            if (proc.thread != null) {
4041                if (proc.pid == Process.myPid()) {
4042                    Log.w(TAG, "crashApplication: trying to crash self!");
4043                    return;
4044                }
4045                long ident = Binder.clearCallingIdentity();
4046                try {
4047                    proc.thread.scheduleCrash(message);
4048                } catch (RemoteException e) {
4049                }
4050                Binder.restoreCallingIdentity(ident);
4051            }
4052        }
4053    }
4054
4055    @Override
4056    public final void finishSubActivity(IBinder token, String resultWho,
4057            int requestCode) {
4058        synchronized(this) {
4059            final long origId = Binder.clearCallingIdentity();
4060            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4061            if (r != null) {
4062                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4063            }
4064            Binder.restoreCallingIdentity(origId);
4065        }
4066    }
4067
4068    @Override
4069    public boolean finishActivityAffinity(IBinder token) {
4070        synchronized(this) {
4071            final long origId = Binder.clearCallingIdentity();
4072            try {
4073                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4074
4075                ActivityRecord rootR = r.task.getRootActivity();
4076                // Do not allow task to finish in Lock Task mode.
4077                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4078                    if (rootR == r) {
4079                        mStackSupervisor.showLockTaskToast();
4080                        return false;
4081                    }
4082                }
4083                boolean res = false;
4084                if (r != null) {
4085                    res = r.task.stack.finishActivityAffinityLocked(r);
4086                }
4087                return res;
4088            } finally {
4089                Binder.restoreCallingIdentity(origId);
4090            }
4091        }
4092    }
4093
4094    @Override
4095    public void finishVoiceTask(IVoiceInteractionSession session) {
4096        synchronized(this) {
4097            final long origId = Binder.clearCallingIdentity();
4098            try {
4099                mStackSupervisor.finishVoiceTask(session);
4100            } finally {
4101                Binder.restoreCallingIdentity(origId);
4102            }
4103        }
4104
4105    }
4106
4107    @Override
4108    public boolean willActivityBeVisible(IBinder token) {
4109        synchronized(this) {
4110            ActivityStack stack = ActivityRecord.getStackLocked(token);
4111            if (stack != null) {
4112                return stack.willActivityBeVisibleLocked(token);
4113            }
4114            return false;
4115        }
4116    }
4117
4118    @Override
4119    public void overridePendingTransition(IBinder token, String packageName,
4120            int enterAnim, int exitAnim) {
4121        synchronized(this) {
4122            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4123            if (self == null) {
4124                return;
4125            }
4126
4127            final long origId = Binder.clearCallingIdentity();
4128
4129            if (self.state == ActivityState.RESUMED
4130                    || self.state == ActivityState.PAUSING) {
4131                mWindowManager.overridePendingAppTransition(packageName,
4132                        enterAnim, exitAnim, null);
4133            }
4134
4135            Binder.restoreCallingIdentity(origId);
4136        }
4137    }
4138
4139    /**
4140     * Main function for removing an existing process from the activity manager
4141     * as a result of that process going away.  Clears out all connections
4142     * to the process.
4143     */
4144    private final void handleAppDiedLocked(ProcessRecord app,
4145            boolean restarting, boolean allowRestart) {
4146        int pid = app.pid;
4147        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4148        if (!restarting) {
4149            removeLruProcessLocked(app);
4150            if (pid > 0) {
4151                ProcessList.remove(pid);
4152            }
4153        }
4154
4155        if (mProfileProc == app) {
4156            clearProfilerLocked();
4157        }
4158
4159        // Remove this application's activities from active lists.
4160        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4161
4162        app.activities.clear();
4163
4164        if (app.instrumentationClass != null) {
4165            Slog.w(TAG, "Crash of app " + app.processName
4166                  + " running instrumentation " + app.instrumentationClass);
4167            Bundle info = new Bundle();
4168            info.putString("shortMsg", "Process crashed.");
4169            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4170        }
4171
4172        if (!restarting) {
4173            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4174                // If there was nothing to resume, and we are not already
4175                // restarting this process, but there is a visible activity that
4176                // is hosted by the process...  then make sure all visible
4177                // activities are running, taking care of restarting this
4178                // process.
4179                if (hasVisibleActivities) {
4180                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4181                }
4182            }
4183        }
4184    }
4185
4186    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4187        IBinder threadBinder = thread.asBinder();
4188        // Find the application record.
4189        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4190            ProcessRecord rec = mLruProcesses.get(i);
4191            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4192                return i;
4193            }
4194        }
4195        return -1;
4196    }
4197
4198    final ProcessRecord getRecordForAppLocked(
4199            IApplicationThread thread) {
4200        if (thread == null) {
4201            return null;
4202        }
4203
4204        int appIndex = getLRURecordIndexForAppLocked(thread);
4205        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4206    }
4207
4208    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4209        // If there are no longer any background processes running,
4210        // and the app that died was not running instrumentation,
4211        // then tell everyone we are now low on memory.
4212        boolean haveBg = false;
4213        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4214            ProcessRecord rec = mLruProcesses.get(i);
4215            if (rec.thread != null
4216                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4217                haveBg = true;
4218                break;
4219            }
4220        }
4221
4222        if (!haveBg) {
4223            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4224            if (doReport) {
4225                long now = SystemClock.uptimeMillis();
4226                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4227                    doReport = false;
4228                } else {
4229                    mLastMemUsageReportTime = now;
4230                }
4231            }
4232            final ArrayList<ProcessMemInfo> memInfos
4233                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4234            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4235            long now = SystemClock.uptimeMillis();
4236            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4237                ProcessRecord rec = mLruProcesses.get(i);
4238                if (rec == dyingProc || rec.thread == null) {
4239                    continue;
4240                }
4241                if (doReport) {
4242                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4243                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4244                }
4245                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4246                    // The low memory report is overriding any current
4247                    // state for a GC request.  Make sure to do
4248                    // heavy/important/visible/foreground processes first.
4249                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4250                        rec.lastRequestedGc = 0;
4251                    } else {
4252                        rec.lastRequestedGc = rec.lastLowMemory;
4253                    }
4254                    rec.reportLowMemory = true;
4255                    rec.lastLowMemory = now;
4256                    mProcessesToGc.remove(rec);
4257                    addProcessToGcListLocked(rec);
4258                }
4259            }
4260            if (doReport) {
4261                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4262                mHandler.sendMessage(msg);
4263            }
4264            scheduleAppGcsLocked();
4265        }
4266    }
4267
4268    final void appDiedLocked(ProcessRecord app) {
4269       appDiedLocked(app, app.pid, app.thread);
4270    }
4271
4272    final void appDiedLocked(ProcessRecord app, int pid,
4273            IApplicationThread thread) {
4274
4275        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4276        synchronized (stats) {
4277            stats.noteProcessDiedLocked(app.info.uid, pid);
4278        }
4279
4280        Process.killProcessGroup(app.info.uid, pid);
4281
4282        // Clean up already done if the process has been re-started.
4283        if (app.pid == pid && app.thread != null &&
4284                app.thread.asBinder() == thread.asBinder()) {
4285            boolean doLowMem = app.instrumentationClass == null;
4286            boolean doOomAdj = doLowMem;
4287            if (!app.killedByAm) {
4288                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4289                        + ") has died.");
4290                mAllowLowerMemLevel = true;
4291            } else {
4292                // Note that we always want to do oom adj to update our state with the
4293                // new number of procs.
4294                mAllowLowerMemLevel = false;
4295                doLowMem = false;
4296            }
4297            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4298            if (DEBUG_CLEANUP) Slog.v(
4299                TAG, "Dying app: " + app + ", pid: " + pid
4300                + ", thread: " + thread.asBinder());
4301            handleAppDiedLocked(app, false, true);
4302
4303            if (doOomAdj) {
4304                updateOomAdjLocked();
4305            }
4306            if (doLowMem) {
4307                doLowMemReportIfNeededLocked(app);
4308            }
4309        } else if (app.pid != pid) {
4310            // A new process has already been started.
4311            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4312                    + ") has died and restarted (pid " + app.pid + ").");
4313            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4314        } else if (DEBUG_PROCESSES) {
4315            Slog.d(TAG, "Received spurious death notification for thread "
4316                    + thread.asBinder());
4317        }
4318    }
4319
4320    /**
4321     * If a stack trace dump file is configured, dump process stack traces.
4322     * @param clearTraces causes the dump file to be erased prior to the new
4323     *    traces being written, if true; when false, the new traces will be
4324     *    appended to any existing file content.
4325     * @param firstPids of dalvik VM processes to dump stack traces for first
4326     * @param lastPids of dalvik VM processes to dump stack traces for last
4327     * @param nativeProcs optional list of native process names to dump stack crawls
4328     * @return file containing stack traces, or null if no dump file is configured
4329     */
4330    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4331            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4332        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4333        if (tracesPath == null || tracesPath.length() == 0) {
4334            return null;
4335        }
4336
4337        File tracesFile = new File(tracesPath);
4338        try {
4339            File tracesDir = tracesFile.getParentFile();
4340            if (!tracesDir.exists()) {
4341                tracesFile.mkdirs();
4342                if (!SELinux.restorecon(tracesDir)) {
4343                    return null;
4344                }
4345            }
4346            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4347
4348            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4349            tracesFile.createNewFile();
4350            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4351        } catch (IOException e) {
4352            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4353            return null;
4354        }
4355
4356        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4357        return tracesFile;
4358    }
4359
4360    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4361            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4362        // Use a FileObserver to detect when traces finish writing.
4363        // The order of traces is considered important to maintain for legibility.
4364        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4365            @Override
4366            public synchronized void onEvent(int event, String path) { notify(); }
4367        };
4368
4369        try {
4370            observer.startWatching();
4371
4372            // First collect all of the stacks of the most important pids.
4373            if (firstPids != null) {
4374                try {
4375                    int num = firstPids.size();
4376                    for (int i = 0; i < num; i++) {
4377                        synchronized (observer) {
4378                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4379                            observer.wait(200);  // Wait for write-close, give up after 200msec
4380                        }
4381                    }
4382                } catch (InterruptedException e) {
4383                    Log.wtf(TAG, e);
4384                }
4385            }
4386
4387            // Next collect the stacks of the native pids
4388            if (nativeProcs != null) {
4389                int[] pids = Process.getPidsForCommands(nativeProcs);
4390                if (pids != null) {
4391                    for (int pid : pids) {
4392                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4393                    }
4394                }
4395            }
4396
4397            // Lastly, measure CPU usage.
4398            if (processCpuTracker != null) {
4399                processCpuTracker.init();
4400                System.gc();
4401                processCpuTracker.update();
4402                try {
4403                    synchronized (processCpuTracker) {
4404                        processCpuTracker.wait(500); // measure over 1/2 second.
4405                    }
4406                } catch (InterruptedException e) {
4407                }
4408                processCpuTracker.update();
4409
4410                // We'll take the stack crawls of just the top apps using CPU.
4411                final int N = processCpuTracker.countWorkingStats();
4412                int numProcs = 0;
4413                for (int i=0; i<N && numProcs<5; i++) {
4414                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4415                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4416                        numProcs++;
4417                        try {
4418                            synchronized (observer) {
4419                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4420                                observer.wait(200);  // Wait for write-close, give up after 200msec
4421                            }
4422                        } catch (InterruptedException e) {
4423                            Log.wtf(TAG, e);
4424                        }
4425
4426                    }
4427                }
4428            }
4429        } finally {
4430            observer.stopWatching();
4431        }
4432    }
4433
4434    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4435        if (true || IS_USER_BUILD) {
4436            return;
4437        }
4438        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4439        if (tracesPath == null || tracesPath.length() == 0) {
4440            return;
4441        }
4442
4443        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4444        StrictMode.allowThreadDiskWrites();
4445        try {
4446            final File tracesFile = new File(tracesPath);
4447            final File tracesDir = tracesFile.getParentFile();
4448            final File tracesTmp = new File(tracesDir, "__tmp__");
4449            try {
4450                if (!tracesDir.exists()) {
4451                    tracesFile.mkdirs();
4452                    if (!SELinux.restorecon(tracesDir.getPath())) {
4453                        return;
4454                    }
4455                }
4456                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4457
4458                if (tracesFile.exists()) {
4459                    tracesTmp.delete();
4460                    tracesFile.renameTo(tracesTmp);
4461                }
4462                StringBuilder sb = new StringBuilder();
4463                Time tobj = new Time();
4464                tobj.set(System.currentTimeMillis());
4465                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4466                sb.append(": ");
4467                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4468                sb.append(" since ");
4469                sb.append(msg);
4470                FileOutputStream fos = new FileOutputStream(tracesFile);
4471                fos.write(sb.toString().getBytes());
4472                if (app == null) {
4473                    fos.write("\n*** No application process!".getBytes());
4474                }
4475                fos.close();
4476                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4477            } catch (IOException e) {
4478                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4479                return;
4480            }
4481
4482            if (app != null) {
4483                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4484                firstPids.add(app.pid);
4485                dumpStackTraces(tracesPath, firstPids, null, null, null);
4486            }
4487
4488            File lastTracesFile = null;
4489            File curTracesFile = null;
4490            for (int i=9; i>=0; i--) {
4491                String name = String.format(Locale.US, "slow%02d.txt", i);
4492                curTracesFile = new File(tracesDir, name);
4493                if (curTracesFile.exists()) {
4494                    if (lastTracesFile != null) {
4495                        curTracesFile.renameTo(lastTracesFile);
4496                    } else {
4497                        curTracesFile.delete();
4498                    }
4499                }
4500                lastTracesFile = curTracesFile;
4501            }
4502            tracesFile.renameTo(curTracesFile);
4503            if (tracesTmp.exists()) {
4504                tracesTmp.renameTo(tracesFile);
4505            }
4506        } finally {
4507            StrictMode.setThreadPolicy(oldPolicy);
4508        }
4509    }
4510
4511    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4512            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4513        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4514        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4515
4516        if (mController != null) {
4517            try {
4518                // 0 == continue, -1 = kill process immediately
4519                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4520                if (res < 0 && app.pid != MY_PID) {
4521                    Process.killProcess(app.pid);
4522                    Process.killProcessGroup(app.info.uid, app.pid);
4523                }
4524            } catch (RemoteException e) {
4525                mController = null;
4526                Watchdog.getInstance().setActivityController(null);
4527            }
4528        }
4529
4530        long anrTime = SystemClock.uptimeMillis();
4531        if (MONITOR_CPU_USAGE) {
4532            updateCpuStatsNow();
4533        }
4534
4535        synchronized (this) {
4536            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4537            if (mShuttingDown) {
4538                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4539                return;
4540            } else if (app.notResponding) {
4541                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4542                return;
4543            } else if (app.crashing) {
4544                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4545                return;
4546            }
4547
4548            // In case we come through here for the same app before completing
4549            // this one, mark as anring now so we will bail out.
4550            app.notResponding = true;
4551
4552            // Log the ANR to the event log.
4553            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4554                    app.processName, app.info.flags, annotation);
4555
4556            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4557            firstPids.add(app.pid);
4558
4559            int parentPid = app.pid;
4560            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4561            if (parentPid != app.pid) firstPids.add(parentPid);
4562
4563            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4564
4565            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4566                ProcessRecord r = mLruProcesses.get(i);
4567                if (r != null && r.thread != null) {
4568                    int pid = r.pid;
4569                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4570                        if (r.persistent) {
4571                            firstPids.add(pid);
4572                        } else {
4573                            lastPids.put(pid, Boolean.TRUE);
4574                        }
4575                    }
4576                }
4577            }
4578        }
4579
4580        // Log the ANR to the main log.
4581        StringBuilder info = new StringBuilder();
4582        info.setLength(0);
4583        info.append("ANR in ").append(app.processName);
4584        if (activity != null && activity.shortComponentName != null) {
4585            info.append(" (").append(activity.shortComponentName).append(")");
4586        }
4587        info.append("\n");
4588        info.append("PID: ").append(app.pid).append("\n");
4589        if (annotation != null) {
4590            info.append("Reason: ").append(annotation).append("\n");
4591        }
4592        if (parent != null && parent != activity) {
4593            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4594        }
4595
4596        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4597
4598        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4599                NATIVE_STACKS_OF_INTEREST);
4600
4601        String cpuInfo = null;
4602        if (MONITOR_CPU_USAGE) {
4603            updateCpuStatsNow();
4604            synchronized (mProcessCpuThread) {
4605                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4606            }
4607            info.append(processCpuTracker.printCurrentLoad());
4608            info.append(cpuInfo);
4609        }
4610
4611        info.append(processCpuTracker.printCurrentState(anrTime));
4612
4613        Slog.e(TAG, info.toString());
4614        if (tracesFile == null) {
4615            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4616            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4617        }
4618
4619        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4620                cpuInfo, tracesFile, null);
4621
4622        if (mController != null) {
4623            try {
4624                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4625                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4626                if (res != 0) {
4627                    if (res < 0 && app.pid != MY_PID) {
4628                        Process.killProcess(app.pid);
4629                        Process.killProcessGroup(app.info.uid, app.pid);
4630                    } else {
4631                        synchronized (this) {
4632                            mServices.scheduleServiceTimeoutLocked(app);
4633                        }
4634                    }
4635                    return;
4636                }
4637            } catch (RemoteException e) {
4638                mController = null;
4639                Watchdog.getInstance().setActivityController(null);
4640            }
4641        }
4642
4643        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4644        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4645                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4646
4647        synchronized (this) {
4648            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4649                killUnneededProcessLocked(app, "background ANR");
4650                return;
4651            }
4652
4653            // Set the app's notResponding state, and look up the errorReportReceiver
4654            makeAppNotRespondingLocked(app,
4655                    activity != null ? activity.shortComponentName : null,
4656                    annotation != null ? "ANR " + annotation : "ANR",
4657                    info.toString());
4658
4659            // Bring up the infamous App Not Responding dialog
4660            Message msg = Message.obtain();
4661            HashMap<String, Object> map = new HashMap<String, Object>();
4662            msg.what = SHOW_NOT_RESPONDING_MSG;
4663            msg.obj = map;
4664            msg.arg1 = aboveSystem ? 1 : 0;
4665            map.put("app", app);
4666            if (activity != null) {
4667                map.put("activity", activity);
4668            }
4669
4670            mHandler.sendMessage(msg);
4671        }
4672    }
4673
4674    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4675        if (!mLaunchWarningShown) {
4676            mLaunchWarningShown = true;
4677            mHandler.post(new Runnable() {
4678                @Override
4679                public void run() {
4680                    synchronized (ActivityManagerService.this) {
4681                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4682                        d.show();
4683                        mHandler.postDelayed(new Runnable() {
4684                            @Override
4685                            public void run() {
4686                                synchronized (ActivityManagerService.this) {
4687                                    d.dismiss();
4688                                    mLaunchWarningShown = false;
4689                                }
4690                            }
4691                        }, 4000);
4692                    }
4693                }
4694            });
4695        }
4696    }
4697
4698    @Override
4699    public boolean clearApplicationUserData(final String packageName,
4700            final IPackageDataObserver observer, int userId) {
4701        enforceNotIsolatedCaller("clearApplicationUserData");
4702        int uid = Binder.getCallingUid();
4703        int pid = Binder.getCallingPid();
4704        userId = handleIncomingUser(pid, uid,
4705                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4706        long callingId = Binder.clearCallingIdentity();
4707        try {
4708            IPackageManager pm = AppGlobals.getPackageManager();
4709            int pkgUid = -1;
4710            synchronized(this) {
4711                try {
4712                    pkgUid = pm.getPackageUid(packageName, userId);
4713                } catch (RemoteException e) {
4714                }
4715                if (pkgUid == -1) {
4716                    Slog.w(TAG, "Invalid packageName: " + packageName);
4717                    if (observer != null) {
4718                        try {
4719                            observer.onRemoveCompleted(packageName, false);
4720                        } catch (RemoteException e) {
4721                            Slog.i(TAG, "Observer no longer exists.");
4722                        }
4723                    }
4724                    return false;
4725                }
4726                if (uid == pkgUid || checkComponentPermission(
4727                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4728                        pid, uid, -1, true)
4729                        == PackageManager.PERMISSION_GRANTED) {
4730                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4731                } else {
4732                    throw new SecurityException("PID " + pid + " does not have permission "
4733                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4734                                    + " of package " + packageName);
4735                }
4736
4737                // Remove all tasks match the cleared application package and user
4738                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
4739                    final TaskRecord tr = mRecentTasks.get(i);
4740                    final String taskPackageName =
4741                            tr.getBaseIntent().getComponent().getPackageName();
4742                    if (tr.userId != userId) continue;
4743                    if (!taskPackageName.equals(packageName)) continue;
4744                    removeTaskByIdLocked(tr.taskId, 0);
4745                }
4746            }
4747
4748            try {
4749                // Clear application user data
4750                pm.clearApplicationUserData(packageName, observer, userId);
4751
4752                synchronized(this) {
4753                    // Remove all permissions granted from/to this package
4754                    removeUriPermissionsForPackageLocked(packageName, userId, true);
4755                }
4756
4757                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4758                        Uri.fromParts("package", packageName, null));
4759                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4760                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4761                        null, null, 0, null, null, null, false, false, userId);
4762            } catch (RemoteException e) {
4763            }
4764        } finally {
4765            Binder.restoreCallingIdentity(callingId);
4766        }
4767        return true;
4768    }
4769
4770    @Override
4771    public void killBackgroundProcesses(final String packageName, int userId) {
4772        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4773                != PackageManager.PERMISSION_GRANTED &&
4774                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4775                        != PackageManager.PERMISSION_GRANTED) {
4776            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4777                    + Binder.getCallingPid()
4778                    + ", uid=" + Binder.getCallingUid()
4779                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4780            Slog.w(TAG, msg);
4781            throw new SecurityException(msg);
4782        }
4783
4784        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4785                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4786        long callingId = Binder.clearCallingIdentity();
4787        try {
4788            IPackageManager pm = AppGlobals.getPackageManager();
4789            synchronized(this) {
4790                int appId = -1;
4791                try {
4792                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4793                } catch (RemoteException e) {
4794                }
4795                if (appId == -1) {
4796                    Slog.w(TAG, "Invalid packageName: " + packageName);
4797                    return;
4798                }
4799                killPackageProcessesLocked(packageName, appId, userId,
4800                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4801            }
4802        } finally {
4803            Binder.restoreCallingIdentity(callingId);
4804        }
4805    }
4806
4807    @Override
4808    public void killAllBackgroundProcesses() {
4809        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4810                != PackageManager.PERMISSION_GRANTED) {
4811            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4812                    + Binder.getCallingPid()
4813                    + ", uid=" + Binder.getCallingUid()
4814                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4815            Slog.w(TAG, msg);
4816            throw new SecurityException(msg);
4817        }
4818
4819        long callingId = Binder.clearCallingIdentity();
4820        try {
4821            synchronized(this) {
4822                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4823                final int NP = mProcessNames.getMap().size();
4824                for (int ip=0; ip<NP; ip++) {
4825                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4826                    final int NA = apps.size();
4827                    for (int ia=0; ia<NA; ia++) {
4828                        ProcessRecord app = apps.valueAt(ia);
4829                        if (app.persistent) {
4830                            // we don't kill persistent processes
4831                            continue;
4832                        }
4833                        if (app.removed) {
4834                            procs.add(app);
4835                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4836                            app.removed = true;
4837                            procs.add(app);
4838                        }
4839                    }
4840                }
4841
4842                int N = procs.size();
4843                for (int i=0; i<N; i++) {
4844                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4845                }
4846                mAllowLowerMemLevel = true;
4847                updateOomAdjLocked();
4848                doLowMemReportIfNeededLocked(null);
4849            }
4850        } finally {
4851            Binder.restoreCallingIdentity(callingId);
4852        }
4853    }
4854
4855    @Override
4856    public void forceStopPackage(final String packageName, int userId) {
4857        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4858                != PackageManager.PERMISSION_GRANTED) {
4859            String msg = "Permission Denial: forceStopPackage() from pid="
4860                    + Binder.getCallingPid()
4861                    + ", uid=" + Binder.getCallingUid()
4862                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4863            Slog.w(TAG, msg);
4864            throw new SecurityException(msg);
4865        }
4866        final int callingPid = Binder.getCallingPid();
4867        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4868                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4869        long callingId = Binder.clearCallingIdentity();
4870        try {
4871            IPackageManager pm = AppGlobals.getPackageManager();
4872            synchronized(this) {
4873                int[] users = userId == UserHandle.USER_ALL
4874                        ? getUsersLocked() : new int[] { userId };
4875                for (int user : users) {
4876                    int pkgUid = -1;
4877                    try {
4878                        pkgUid = pm.getPackageUid(packageName, user);
4879                    } catch (RemoteException e) {
4880                    }
4881                    if (pkgUid == -1) {
4882                        Slog.w(TAG, "Invalid packageName: " + packageName);
4883                        continue;
4884                    }
4885                    try {
4886                        pm.setPackageStoppedState(packageName, true, user);
4887                    } catch (RemoteException e) {
4888                    } catch (IllegalArgumentException e) {
4889                        Slog.w(TAG, "Failed trying to unstop package "
4890                                + packageName + ": " + e);
4891                    }
4892                    if (isUserRunningLocked(user, false)) {
4893                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4894                    }
4895                }
4896            }
4897        } finally {
4898            Binder.restoreCallingIdentity(callingId);
4899        }
4900    }
4901
4902    @Override
4903    public void addPackageDependency(String packageName) {
4904        synchronized (this) {
4905            int callingPid = Binder.getCallingPid();
4906            if (callingPid == Process.myPid()) {
4907                //  Yeah, um, no.
4908                Slog.w(TAG, "Can't addPackageDependency on system process");
4909                return;
4910            }
4911            ProcessRecord proc;
4912            synchronized (mPidsSelfLocked) {
4913                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4914            }
4915            if (proc != null) {
4916                if (proc.pkgDeps == null) {
4917                    proc.pkgDeps = new ArraySet<String>(1);
4918                }
4919                proc.pkgDeps.add(packageName);
4920            }
4921        }
4922    }
4923
4924    /*
4925     * The pkg name and app id have to be specified.
4926     */
4927    @Override
4928    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4929        if (pkg == null) {
4930            return;
4931        }
4932        // Make sure the uid is valid.
4933        if (appid < 0) {
4934            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4935            return;
4936        }
4937        int callerUid = Binder.getCallingUid();
4938        // Only the system server can kill an application
4939        if (callerUid == Process.SYSTEM_UID) {
4940            // Post an aysnc message to kill the application
4941            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4942            msg.arg1 = appid;
4943            msg.arg2 = 0;
4944            Bundle bundle = new Bundle();
4945            bundle.putString("pkg", pkg);
4946            bundle.putString("reason", reason);
4947            msg.obj = bundle;
4948            mHandler.sendMessage(msg);
4949        } else {
4950            throw new SecurityException(callerUid + " cannot kill pkg: " +
4951                    pkg);
4952        }
4953    }
4954
4955    @Override
4956    public void closeSystemDialogs(String reason) {
4957        enforceNotIsolatedCaller("closeSystemDialogs");
4958
4959        final int pid = Binder.getCallingPid();
4960        final int uid = Binder.getCallingUid();
4961        final long origId = Binder.clearCallingIdentity();
4962        try {
4963            synchronized (this) {
4964                // Only allow this from foreground processes, so that background
4965                // applications can't abuse it to prevent system UI from being shown.
4966                if (uid >= Process.FIRST_APPLICATION_UID) {
4967                    ProcessRecord proc;
4968                    synchronized (mPidsSelfLocked) {
4969                        proc = mPidsSelfLocked.get(pid);
4970                    }
4971                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4972                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4973                                + " from background process " + proc);
4974                        return;
4975                    }
4976                }
4977                closeSystemDialogsLocked(reason);
4978            }
4979        } finally {
4980            Binder.restoreCallingIdentity(origId);
4981        }
4982    }
4983
4984    void closeSystemDialogsLocked(String reason) {
4985        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4986        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4987                | Intent.FLAG_RECEIVER_FOREGROUND);
4988        if (reason != null) {
4989            intent.putExtra("reason", reason);
4990        }
4991        mWindowManager.closeSystemDialogs(reason);
4992
4993        mStackSupervisor.closeSystemDialogsLocked();
4994
4995        broadcastIntentLocked(null, null, intent, null,
4996                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4997                Process.SYSTEM_UID, UserHandle.USER_ALL);
4998    }
4999
5000    @Override
5001    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5002        enforceNotIsolatedCaller("getProcessMemoryInfo");
5003        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5004        for (int i=pids.length-1; i>=0; i--) {
5005            ProcessRecord proc;
5006            int oomAdj;
5007            synchronized (this) {
5008                synchronized (mPidsSelfLocked) {
5009                    proc = mPidsSelfLocked.get(pids[i]);
5010                    oomAdj = proc != null ? proc.setAdj : 0;
5011                }
5012            }
5013            infos[i] = new Debug.MemoryInfo();
5014            Debug.getMemoryInfo(pids[i], infos[i]);
5015            if (proc != null) {
5016                synchronized (this) {
5017                    if (proc.thread != null && proc.setAdj == oomAdj) {
5018                        // Record this for posterity if the process has been stable.
5019                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5020                                infos[i].getTotalUss(), false, proc.pkgList);
5021                    }
5022                }
5023            }
5024        }
5025        return infos;
5026    }
5027
5028    @Override
5029    public long[] getProcessPss(int[] pids) {
5030        enforceNotIsolatedCaller("getProcessPss");
5031        long[] pss = new long[pids.length];
5032        for (int i=pids.length-1; i>=0; i--) {
5033            ProcessRecord proc;
5034            int oomAdj;
5035            synchronized (this) {
5036                synchronized (mPidsSelfLocked) {
5037                    proc = mPidsSelfLocked.get(pids[i]);
5038                    oomAdj = proc != null ? proc.setAdj : 0;
5039                }
5040            }
5041            long[] tmpUss = new long[1];
5042            pss[i] = Debug.getPss(pids[i], tmpUss);
5043            if (proc != null) {
5044                synchronized (this) {
5045                    if (proc.thread != null && proc.setAdj == oomAdj) {
5046                        // Record this for posterity if the process has been stable.
5047                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5048                    }
5049                }
5050            }
5051        }
5052        return pss;
5053    }
5054
5055    @Override
5056    public void killApplicationProcess(String processName, int uid) {
5057        if (processName == null) {
5058            return;
5059        }
5060
5061        int callerUid = Binder.getCallingUid();
5062        // Only the system server can kill an application
5063        if (callerUid == Process.SYSTEM_UID) {
5064            synchronized (this) {
5065                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5066                if (app != null && app.thread != null) {
5067                    try {
5068                        app.thread.scheduleSuicide();
5069                    } catch (RemoteException e) {
5070                        // If the other end already died, then our work here is done.
5071                    }
5072                } else {
5073                    Slog.w(TAG, "Process/uid not found attempting kill of "
5074                            + processName + " / " + uid);
5075                }
5076            }
5077        } else {
5078            throw new SecurityException(callerUid + " cannot kill app process: " +
5079                    processName);
5080        }
5081    }
5082
5083    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5084        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5085                false, true, false, false, UserHandle.getUserId(uid), reason);
5086        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5087                Uri.fromParts("package", packageName, null));
5088        if (!mProcessesReady) {
5089            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5090                    | Intent.FLAG_RECEIVER_FOREGROUND);
5091        }
5092        intent.putExtra(Intent.EXTRA_UID, uid);
5093        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5094        broadcastIntentLocked(null, null, intent,
5095                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5096                false, false,
5097                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5098    }
5099
5100    private void forceStopUserLocked(int userId, String reason) {
5101        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5102        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5103        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5104                | Intent.FLAG_RECEIVER_FOREGROUND);
5105        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5106        broadcastIntentLocked(null, null, intent,
5107                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5108                false, false,
5109                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5110    }
5111
5112    private final boolean killPackageProcessesLocked(String packageName, int appId,
5113            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5114            boolean doit, boolean evenPersistent, String reason) {
5115        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5116
5117        // Remove all processes this package may have touched: all with the
5118        // same UID (except for the system or root user), and all whose name
5119        // matches the package name.
5120        final int NP = mProcessNames.getMap().size();
5121        for (int ip=0; ip<NP; ip++) {
5122            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5123            final int NA = apps.size();
5124            for (int ia=0; ia<NA; ia++) {
5125                ProcessRecord app = apps.valueAt(ia);
5126                if (app.persistent && !evenPersistent) {
5127                    // we don't kill persistent processes
5128                    continue;
5129                }
5130                if (app.removed) {
5131                    if (doit) {
5132                        procs.add(app);
5133                    }
5134                    continue;
5135                }
5136
5137                // Skip process if it doesn't meet our oom adj requirement.
5138                if (app.setAdj < minOomAdj) {
5139                    continue;
5140                }
5141
5142                // If no package is specified, we call all processes under the
5143                // give user id.
5144                if (packageName == null) {
5145                    if (app.userId != userId) {
5146                        continue;
5147                    }
5148                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5149                        continue;
5150                    }
5151                // Package has been specified, we want to hit all processes
5152                // that match it.  We need to qualify this by the processes
5153                // that are running under the specified app and user ID.
5154                } else {
5155                    final boolean isDep = app.pkgDeps != null
5156                            && app.pkgDeps.contains(packageName);
5157                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5158                        continue;
5159                    }
5160                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5161                        continue;
5162                    }
5163                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5164                        continue;
5165                    }
5166                }
5167
5168                // Process has passed all conditions, kill it!
5169                if (!doit) {
5170                    return true;
5171                }
5172                app.removed = true;
5173                procs.add(app);
5174            }
5175        }
5176
5177        int N = procs.size();
5178        for (int i=0; i<N; i++) {
5179            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5180        }
5181        updateOomAdjLocked();
5182        return N > 0;
5183    }
5184
5185    private final boolean forceStopPackageLocked(String name, int appId,
5186            boolean callerWillRestart, boolean purgeCache, boolean doit,
5187            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5188        int i;
5189        int N;
5190
5191        if (userId == UserHandle.USER_ALL && name == null) {
5192            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5193        }
5194
5195        if (appId < 0 && name != null) {
5196            try {
5197                appId = UserHandle.getAppId(
5198                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5199            } catch (RemoteException e) {
5200            }
5201        }
5202
5203        if (doit) {
5204            if (name != null) {
5205                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5206                        + " user=" + userId + ": " + reason);
5207            } else {
5208                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5209            }
5210
5211            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5212            for (int ip=pmap.size()-1; ip>=0; ip--) {
5213                SparseArray<Long> ba = pmap.valueAt(ip);
5214                for (i=ba.size()-1; i>=0; i--) {
5215                    boolean remove = false;
5216                    final int entUid = ba.keyAt(i);
5217                    if (name != null) {
5218                        if (userId == UserHandle.USER_ALL) {
5219                            if (UserHandle.getAppId(entUid) == appId) {
5220                                remove = true;
5221                            }
5222                        } else {
5223                            if (entUid == UserHandle.getUid(userId, appId)) {
5224                                remove = true;
5225                            }
5226                        }
5227                    } else if (UserHandle.getUserId(entUid) == userId) {
5228                        remove = true;
5229                    }
5230                    if (remove) {
5231                        ba.removeAt(i);
5232                    }
5233                }
5234                if (ba.size() == 0) {
5235                    pmap.removeAt(ip);
5236                }
5237            }
5238        }
5239
5240        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5241                -100, callerWillRestart, true, doit, evenPersistent,
5242                name == null ? ("stop user " + userId) : ("stop " + name));
5243
5244        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5245            if (!doit) {
5246                return true;
5247            }
5248            didSomething = true;
5249        }
5250
5251        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5252            if (!doit) {
5253                return true;
5254            }
5255            didSomething = true;
5256        }
5257
5258        if (name == null) {
5259            // Remove all sticky broadcasts from this user.
5260            mStickyBroadcasts.remove(userId);
5261        }
5262
5263        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5264        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5265                userId, providers)) {
5266            if (!doit) {
5267                return true;
5268            }
5269            didSomething = true;
5270        }
5271        N = providers.size();
5272        for (i=0; i<N; i++) {
5273            removeDyingProviderLocked(null, providers.get(i), true);
5274        }
5275
5276        // Remove transient permissions granted from/to this package/user
5277        removeUriPermissionsForPackageLocked(name, userId, false);
5278
5279        if (name == null || uninstalling) {
5280            // Remove pending intents.  For now we only do this when force
5281            // stopping users, because we have some problems when doing this
5282            // for packages -- app widgets are not currently cleaned up for
5283            // such packages, so they can be left with bad pending intents.
5284            if (mIntentSenderRecords.size() > 0) {
5285                Iterator<WeakReference<PendingIntentRecord>> it
5286                        = mIntentSenderRecords.values().iterator();
5287                while (it.hasNext()) {
5288                    WeakReference<PendingIntentRecord> wpir = it.next();
5289                    if (wpir == null) {
5290                        it.remove();
5291                        continue;
5292                    }
5293                    PendingIntentRecord pir = wpir.get();
5294                    if (pir == null) {
5295                        it.remove();
5296                        continue;
5297                    }
5298                    if (name == null) {
5299                        // Stopping user, remove all objects for the user.
5300                        if (pir.key.userId != userId) {
5301                            // Not the same user, skip it.
5302                            continue;
5303                        }
5304                    } else {
5305                        if (UserHandle.getAppId(pir.uid) != appId) {
5306                            // Different app id, skip it.
5307                            continue;
5308                        }
5309                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5310                            // Different user, skip it.
5311                            continue;
5312                        }
5313                        if (!pir.key.packageName.equals(name)) {
5314                            // Different package, skip it.
5315                            continue;
5316                        }
5317                    }
5318                    if (!doit) {
5319                        return true;
5320                    }
5321                    didSomething = true;
5322                    it.remove();
5323                    pir.canceled = true;
5324                    if (pir.key.activity != null) {
5325                        pir.key.activity.pendingResults.remove(pir.ref);
5326                    }
5327                }
5328            }
5329        }
5330
5331        if (doit) {
5332            if (purgeCache && name != null) {
5333                AttributeCache ac = AttributeCache.instance();
5334                if (ac != null) {
5335                    ac.removePackage(name);
5336                }
5337            }
5338            if (mBooted) {
5339                mStackSupervisor.resumeTopActivitiesLocked();
5340                mStackSupervisor.scheduleIdleLocked();
5341            }
5342        }
5343
5344        return didSomething;
5345    }
5346
5347    private final boolean removeProcessLocked(ProcessRecord app,
5348            boolean callerWillRestart, boolean allowRestart, String reason) {
5349        final String name = app.processName;
5350        final int uid = app.uid;
5351        if (DEBUG_PROCESSES) Slog.d(
5352            TAG, "Force removing proc " + app.toShortString() + " (" + name
5353            + "/" + uid + ")");
5354
5355        mProcessNames.remove(name, uid);
5356        mIsolatedProcesses.remove(app.uid);
5357        if (mHeavyWeightProcess == app) {
5358            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5359                    mHeavyWeightProcess.userId, 0));
5360            mHeavyWeightProcess = null;
5361        }
5362        boolean needRestart = false;
5363        if (app.pid > 0 && app.pid != MY_PID) {
5364            int pid = app.pid;
5365            synchronized (mPidsSelfLocked) {
5366                mPidsSelfLocked.remove(pid);
5367                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5368            }
5369            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5370            if (app.isolated) {
5371                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5372            }
5373            killUnneededProcessLocked(app, reason);
5374            Process.killProcessGroup(app.info.uid, app.pid);
5375            handleAppDiedLocked(app, true, allowRestart);
5376            removeLruProcessLocked(app);
5377
5378            if (app.persistent && !app.isolated) {
5379                if (!callerWillRestart) {
5380                    addAppLocked(app.info, false, null /* ABI override */);
5381                } else {
5382                    needRestart = true;
5383                }
5384            }
5385        } else {
5386            mRemovedProcesses.add(app);
5387        }
5388
5389        return needRestart;
5390    }
5391
5392    private final void processStartTimedOutLocked(ProcessRecord app) {
5393        final int pid = app.pid;
5394        boolean gone = false;
5395        synchronized (mPidsSelfLocked) {
5396            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5397            if (knownApp != null && knownApp.thread == null) {
5398                mPidsSelfLocked.remove(pid);
5399                gone = true;
5400            }
5401        }
5402
5403        if (gone) {
5404            Slog.w(TAG, "Process " + app + " failed to attach");
5405            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5406                    pid, app.uid, app.processName);
5407            mProcessNames.remove(app.processName, app.uid);
5408            mIsolatedProcesses.remove(app.uid);
5409            if (mHeavyWeightProcess == app) {
5410                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5411                        mHeavyWeightProcess.userId, 0));
5412                mHeavyWeightProcess = null;
5413            }
5414            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5415            if (app.isolated) {
5416                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5417            }
5418            // Take care of any launching providers waiting for this process.
5419            checkAppInLaunchingProvidersLocked(app, true);
5420            // Take care of any services that are waiting for the process.
5421            mServices.processStartTimedOutLocked(app);
5422            killUnneededProcessLocked(app, "start timeout");
5423            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5424                Slog.w(TAG, "Unattached app died before backup, skipping");
5425                try {
5426                    IBackupManager bm = IBackupManager.Stub.asInterface(
5427                            ServiceManager.getService(Context.BACKUP_SERVICE));
5428                    bm.agentDisconnected(app.info.packageName);
5429                } catch (RemoteException e) {
5430                    // Can't happen; the backup manager is local
5431                }
5432            }
5433            if (isPendingBroadcastProcessLocked(pid)) {
5434                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5435                skipPendingBroadcastLocked(pid);
5436            }
5437        } else {
5438            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5439        }
5440    }
5441
5442    private final boolean attachApplicationLocked(IApplicationThread thread,
5443            int pid) {
5444
5445        // Find the application record that is being attached...  either via
5446        // the pid if we are running in multiple processes, or just pull the
5447        // next app record if we are emulating process with anonymous threads.
5448        ProcessRecord app;
5449        if (pid != MY_PID && pid >= 0) {
5450            synchronized (mPidsSelfLocked) {
5451                app = mPidsSelfLocked.get(pid);
5452            }
5453        } else {
5454            app = null;
5455        }
5456
5457        if (app == null) {
5458            Slog.w(TAG, "No pending application record for pid " + pid
5459                    + " (IApplicationThread " + thread + "); dropping process");
5460            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5461            if (pid > 0 && pid != MY_PID) {
5462                Process.killProcessQuiet(pid);
5463                //TODO: Process.killProcessGroup(app.info.uid, pid);
5464            } else {
5465                try {
5466                    thread.scheduleExit();
5467                } catch (Exception e) {
5468                    // Ignore exceptions.
5469                }
5470            }
5471            return false;
5472        }
5473
5474        // If this application record is still attached to a previous
5475        // process, clean it up now.
5476        if (app.thread != null) {
5477            handleAppDiedLocked(app, true, true);
5478        }
5479
5480        // Tell the process all about itself.
5481
5482        if (localLOGV) Slog.v(
5483                TAG, "Binding process pid " + pid + " to record " + app);
5484
5485        final String processName = app.processName;
5486        try {
5487            AppDeathRecipient adr = new AppDeathRecipient(
5488                    app, pid, thread);
5489            thread.asBinder().linkToDeath(adr, 0);
5490            app.deathRecipient = adr;
5491        } catch (RemoteException e) {
5492            app.resetPackageList(mProcessStats);
5493            startProcessLocked(app, "link fail", processName);
5494            return false;
5495        }
5496
5497        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5498
5499        app.makeActive(thread, mProcessStats);
5500        app.curAdj = app.setAdj = -100;
5501        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5502        app.forcingToForeground = null;
5503        updateProcessForegroundLocked(app, false, false);
5504        app.hasShownUi = false;
5505        app.debugging = false;
5506        app.cached = false;
5507
5508        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5509
5510        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5511        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5512
5513        if (!normalMode) {
5514            Slog.i(TAG, "Launching preboot mode app: " + app);
5515        }
5516
5517        if (localLOGV) Slog.v(
5518            TAG, "New app record " + app
5519            + " thread=" + thread.asBinder() + " pid=" + pid);
5520        try {
5521            int testMode = IApplicationThread.DEBUG_OFF;
5522            if (mDebugApp != null && mDebugApp.equals(processName)) {
5523                testMode = mWaitForDebugger
5524                    ? IApplicationThread.DEBUG_WAIT
5525                    : IApplicationThread.DEBUG_ON;
5526                app.debugging = true;
5527                if (mDebugTransient) {
5528                    mDebugApp = mOrigDebugApp;
5529                    mWaitForDebugger = mOrigWaitForDebugger;
5530                }
5531            }
5532            String profileFile = app.instrumentationProfileFile;
5533            ParcelFileDescriptor profileFd = null;
5534            boolean profileAutoStop = false;
5535            if (mProfileApp != null && mProfileApp.equals(processName)) {
5536                mProfileProc = app;
5537                profileFile = mProfileFile;
5538                profileFd = mProfileFd;
5539                profileAutoStop = mAutoStopProfiler;
5540            }
5541            boolean enableOpenGlTrace = false;
5542            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5543                enableOpenGlTrace = true;
5544                mOpenGlTraceApp = null;
5545            }
5546
5547            // If the app is being launched for restore or full backup, set it up specially
5548            boolean isRestrictedBackupMode = false;
5549            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5550                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5551                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5552                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5553            }
5554
5555            ensurePackageDexOpt(app.instrumentationInfo != null
5556                    ? app.instrumentationInfo.packageName
5557                    : app.info.packageName);
5558            if (app.instrumentationClass != null) {
5559                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5560            }
5561            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5562                    + processName + " with config " + mConfiguration);
5563            ApplicationInfo appInfo = app.instrumentationInfo != null
5564                    ? app.instrumentationInfo : app.info;
5565            app.compat = compatibilityInfoForPackageLocked(appInfo);
5566            if (profileFd != null) {
5567                profileFd = profileFd.dup();
5568            }
5569            thread.bindApplication(processName, appInfo, providers,
5570                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5571                    app.instrumentationArguments, app.instrumentationWatcher,
5572                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5573                    isRestrictedBackupMode || !normalMode, app.persistent,
5574                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5575                    mCoreSettingsObserver.getCoreSettingsLocked());
5576            updateLruProcessLocked(app, false, null);
5577            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5578        } catch (Exception e) {
5579            // todo: Yikes!  What should we do?  For now we will try to
5580            // start another process, but that could easily get us in
5581            // an infinite loop of restarting processes...
5582            Slog.w(TAG, "Exception thrown during bind!", e);
5583
5584            app.resetPackageList(mProcessStats);
5585            app.unlinkDeathRecipient();
5586            startProcessLocked(app, "bind fail", processName);
5587            return false;
5588        }
5589
5590        // Remove this record from the list of starting applications.
5591        mPersistentStartingProcesses.remove(app);
5592        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5593                "Attach application locked removing on hold: " + app);
5594        mProcessesOnHold.remove(app);
5595
5596        boolean badApp = false;
5597        boolean didSomething = false;
5598
5599        // See if the top visible activity is waiting to run in this process...
5600        if (normalMode) {
5601            try {
5602                if (mStackSupervisor.attachApplicationLocked(app)) {
5603                    didSomething = true;
5604                }
5605            } catch (Exception e) {
5606                badApp = true;
5607            }
5608        }
5609
5610        // Find any services that should be running in this process...
5611        if (!badApp) {
5612            try {
5613                didSomething |= mServices.attachApplicationLocked(app, processName);
5614            } catch (Exception e) {
5615                badApp = true;
5616            }
5617        }
5618
5619        // Check if a next-broadcast receiver is in this process...
5620        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5621            try {
5622                didSomething |= sendPendingBroadcastsLocked(app);
5623            } catch (Exception e) {
5624                // If the app died trying to launch the receiver we declare it 'bad'
5625                badApp = true;
5626            }
5627        }
5628
5629        // Check whether the next backup agent is in this process...
5630        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5631            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5632            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5633            try {
5634                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5635                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5636                        mBackupTarget.backupMode);
5637            } catch (Exception e) {
5638                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5639                e.printStackTrace();
5640            }
5641        }
5642
5643        if (badApp) {
5644            // todo: Also need to kill application to deal with all
5645            // kinds of exceptions.
5646            handleAppDiedLocked(app, false, true);
5647            return false;
5648        }
5649
5650        if (!didSomething) {
5651            updateOomAdjLocked();
5652        }
5653
5654        return true;
5655    }
5656
5657    @Override
5658    public final void attachApplication(IApplicationThread thread) {
5659        synchronized (this) {
5660            int callingPid = Binder.getCallingPid();
5661            final long origId = Binder.clearCallingIdentity();
5662            attachApplicationLocked(thread, callingPid);
5663            Binder.restoreCallingIdentity(origId);
5664        }
5665    }
5666
5667    @Override
5668    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5669        final long origId = Binder.clearCallingIdentity();
5670        synchronized (this) {
5671            ActivityStack stack = ActivityRecord.getStackLocked(token);
5672            if (stack != null) {
5673                ActivityRecord r =
5674                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5675                if (stopProfiling) {
5676                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5677                        try {
5678                            mProfileFd.close();
5679                        } catch (IOException e) {
5680                        }
5681                        clearProfilerLocked();
5682                    }
5683                }
5684            }
5685        }
5686        Binder.restoreCallingIdentity(origId);
5687    }
5688
5689    void postEnableScreenAfterBootLocked() {
5690        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
5691    }
5692
5693    void enableScreenAfterBoot() {
5694        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5695                SystemClock.uptimeMillis());
5696        mWindowManager.enableScreenAfterBoot();
5697
5698        synchronized (this) {
5699            updateEventDispatchingLocked();
5700        }
5701    }
5702
5703    @Override
5704    public void showBootMessage(final CharSequence msg, final boolean always) {
5705        enforceNotIsolatedCaller("showBootMessage");
5706        mWindowManager.showBootMessage(msg, always);
5707    }
5708
5709    @Override
5710    public void keyguardWaitingForActivityDrawn() {
5711        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
5712        final long token = Binder.clearCallingIdentity();
5713        try {
5714            synchronized (this) {
5715                if (DEBUG_LOCKSCREEN) logLockScreen("");
5716                mWindowManager.keyguardWaitingForActivityDrawn();
5717            }
5718        } finally {
5719            Binder.restoreCallingIdentity(token);
5720        }
5721    }
5722
5723    final void finishBooting() {
5724        // Register receivers to handle package update events
5725        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5726
5727        // Let system services know.
5728        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
5729
5730        synchronized (this) {
5731            // Ensure that any processes we had put on hold are now started
5732            // up.
5733            final int NP = mProcessesOnHold.size();
5734            if (NP > 0) {
5735                ArrayList<ProcessRecord> procs =
5736                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5737                for (int ip=0; ip<NP; ip++) {
5738                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5739                            + procs.get(ip));
5740                    startProcessLocked(procs.get(ip), "on-hold", null);
5741                }
5742            }
5743
5744            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5745                // Start looking for apps that are abusing wake locks.
5746                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5747                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5748                // Tell anyone interested that we are done booting!
5749                SystemProperties.set("sys.boot_completed", "1");
5750                SystemProperties.set("dev.bootcomplete", "1");
5751                for (int i=0; i<mStartedUsers.size(); i++) {
5752                    UserStartedState uss = mStartedUsers.valueAt(i);
5753                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5754                        uss.mState = UserStartedState.STATE_RUNNING;
5755                        final int userId = mStartedUsers.keyAt(i);
5756                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5757                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5758                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5759                        broadcastIntentLocked(null, null, intent, null,
5760                                new IIntentReceiver.Stub() {
5761                                    @Override
5762                                    public void performReceive(Intent intent, int resultCode,
5763                                            String data, Bundle extras, boolean ordered,
5764                                            boolean sticky, int sendingUser) {
5765                                        synchronized (ActivityManagerService.this) {
5766                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5767                                                    true, false);
5768                                        }
5769                                    }
5770                                },
5771                                0, null, null,
5772                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5773                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5774                                userId);
5775                    }
5776                }
5777                scheduleStartProfilesLocked();
5778            }
5779        }
5780    }
5781
5782    final void ensureBootCompleted() {
5783        boolean booting;
5784        boolean enableScreen;
5785        synchronized (this) {
5786            booting = mBooting;
5787            mBooting = false;
5788            enableScreen = !mBooted;
5789            mBooted = true;
5790        }
5791
5792        if (booting) {
5793            finishBooting();
5794        }
5795
5796        if (enableScreen) {
5797            enableScreenAfterBoot();
5798        }
5799    }
5800
5801    @Override
5802    public final void activityResumed(IBinder token) {
5803        final long origId = Binder.clearCallingIdentity();
5804        synchronized(this) {
5805            ActivityStack stack = ActivityRecord.getStackLocked(token);
5806            if (stack != null) {
5807                ActivityRecord.activityResumedLocked(token);
5808            }
5809        }
5810        Binder.restoreCallingIdentity(origId);
5811    }
5812
5813    @Override
5814    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5815        final long origId = Binder.clearCallingIdentity();
5816        synchronized(this) {
5817            ActivityStack stack = ActivityRecord.getStackLocked(token);
5818            if (stack != null) {
5819                stack.activityPausedLocked(token, false, persistentState);
5820            }
5821        }
5822        Binder.restoreCallingIdentity(origId);
5823    }
5824
5825    @Override
5826    public final void activityStopped(IBinder token, Bundle icicle,
5827            PersistableBundle persistentState, CharSequence description) {
5828        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5829
5830        // Refuse possible leaked file descriptors
5831        if (icicle != null && icicle.hasFileDescriptors()) {
5832            throw new IllegalArgumentException("File descriptors passed in Bundle");
5833        }
5834
5835        final long origId = Binder.clearCallingIdentity();
5836
5837        synchronized (this) {
5838            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5839            if (r != null) {
5840                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5841            }
5842        }
5843
5844        trimApplications();
5845
5846        Binder.restoreCallingIdentity(origId);
5847    }
5848
5849    @Override
5850    public final void activityDestroyed(IBinder token) {
5851        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5852        synchronized (this) {
5853            ActivityStack stack = ActivityRecord.getStackLocked(token);
5854            if (stack != null) {
5855                stack.activityDestroyedLocked(token);
5856            }
5857        }
5858    }
5859
5860    @Override
5861    public final void backgroundResourcesReleased(IBinder token) {
5862        final long origId = Binder.clearCallingIdentity();
5863        try {
5864            synchronized (this) {
5865                ActivityStack stack = ActivityRecord.getStackLocked(token);
5866                if (stack != null) {
5867                    stack.backgroundResourcesReleased(token);
5868                }
5869            }
5870        } finally {
5871            Binder.restoreCallingIdentity(origId);
5872        }
5873    }
5874
5875    @Override
5876    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5877        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5878    }
5879
5880    @Override
5881    public final void notifyEnterAnimationComplete(IBinder token) {
5882        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5883    }
5884
5885    @Override
5886    public String getCallingPackage(IBinder token) {
5887        synchronized (this) {
5888            ActivityRecord r = getCallingRecordLocked(token);
5889            return r != null ? r.info.packageName : null;
5890        }
5891    }
5892
5893    @Override
5894    public ComponentName getCallingActivity(IBinder token) {
5895        synchronized (this) {
5896            ActivityRecord r = getCallingRecordLocked(token);
5897            return r != null ? r.intent.getComponent() : null;
5898        }
5899    }
5900
5901    private ActivityRecord getCallingRecordLocked(IBinder token) {
5902        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5903        if (r == null) {
5904            return null;
5905        }
5906        return r.resultTo;
5907    }
5908
5909    @Override
5910    public ComponentName getActivityClassForToken(IBinder token) {
5911        synchronized(this) {
5912            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5913            if (r == null) {
5914                return null;
5915            }
5916            return r.intent.getComponent();
5917        }
5918    }
5919
5920    @Override
5921    public String getPackageForToken(IBinder token) {
5922        synchronized(this) {
5923            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5924            if (r == null) {
5925                return null;
5926            }
5927            return r.packageName;
5928        }
5929    }
5930
5931    @Override
5932    public IIntentSender getIntentSender(int type,
5933            String packageName, IBinder token, String resultWho,
5934            int requestCode, Intent[] intents, String[] resolvedTypes,
5935            int flags, Bundle options, int userId) {
5936        enforceNotIsolatedCaller("getIntentSender");
5937        // Refuse possible leaked file descriptors
5938        if (intents != null) {
5939            if (intents.length < 1) {
5940                throw new IllegalArgumentException("Intents array length must be >= 1");
5941            }
5942            for (int i=0; i<intents.length; i++) {
5943                Intent intent = intents[i];
5944                if (intent != null) {
5945                    if (intent.hasFileDescriptors()) {
5946                        throw new IllegalArgumentException("File descriptors passed in Intent");
5947                    }
5948                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5949                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5950                        throw new IllegalArgumentException(
5951                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5952                    }
5953                    intents[i] = new Intent(intent);
5954                }
5955            }
5956            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5957                throw new IllegalArgumentException(
5958                        "Intent array length does not match resolvedTypes length");
5959            }
5960        }
5961        if (options != null) {
5962            if (options.hasFileDescriptors()) {
5963                throw new IllegalArgumentException("File descriptors passed in options");
5964            }
5965        }
5966
5967        synchronized(this) {
5968            int callingUid = Binder.getCallingUid();
5969            int origUserId = userId;
5970            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5971                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5972                    ALLOW_NON_FULL, "getIntentSender", null);
5973            if (origUserId == UserHandle.USER_CURRENT) {
5974                // We don't want to evaluate this until the pending intent is
5975                // actually executed.  However, we do want to always do the
5976                // security checking for it above.
5977                userId = UserHandle.USER_CURRENT;
5978            }
5979            try {
5980                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5981                    int uid = AppGlobals.getPackageManager()
5982                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5983                    if (!UserHandle.isSameApp(callingUid, uid)) {
5984                        String msg = "Permission Denial: getIntentSender() from pid="
5985                            + Binder.getCallingPid()
5986                            + ", uid=" + Binder.getCallingUid()
5987                            + ", (need uid=" + uid + ")"
5988                            + " is not allowed to send as package " + packageName;
5989                        Slog.w(TAG, msg);
5990                        throw new SecurityException(msg);
5991                    }
5992                }
5993
5994                return getIntentSenderLocked(type, packageName, callingUid, userId,
5995                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5996
5997            } catch (RemoteException e) {
5998                throw new SecurityException(e);
5999            }
6000        }
6001    }
6002
6003    IIntentSender getIntentSenderLocked(int type, String packageName,
6004            int callingUid, int userId, IBinder token, String resultWho,
6005            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6006            Bundle options) {
6007        if (DEBUG_MU)
6008            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6009        ActivityRecord activity = null;
6010        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6011            activity = ActivityRecord.isInStackLocked(token);
6012            if (activity == null) {
6013                return null;
6014            }
6015            if (activity.finishing) {
6016                return null;
6017            }
6018        }
6019
6020        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6021        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6022        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6023        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6024                |PendingIntent.FLAG_UPDATE_CURRENT);
6025
6026        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6027                type, packageName, activity, resultWho,
6028                requestCode, intents, resolvedTypes, flags, options, userId);
6029        WeakReference<PendingIntentRecord> ref;
6030        ref = mIntentSenderRecords.get(key);
6031        PendingIntentRecord rec = ref != null ? ref.get() : null;
6032        if (rec != null) {
6033            if (!cancelCurrent) {
6034                if (updateCurrent) {
6035                    if (rec.key.requestIntent != null) {
6036                        rec.key.requestIntent.replaceExtras(intents != null ?
6037                                intents[intents.length - 1] : null);
6038                    }
6039                    if (intents != null) {
6040                        intents[intents.length-1] = rec.key.requestIntent;
6041                        rec.key.allIntents = intents;
6042                        rec.key.allResolvedTypes = resolvedTypes;
6043                    } else {
6044                        rec.key.allIntents = null;
6045                        rec.key.allResolvedTypes = null;
6046                    }
6047                }
6048                return rec;
6049            }
6050            rec.canceled = true;
6051            mIntentSenderRecords.remove(key);
6052        }
6053        if (noCreate) {
6054            return rec;
6055        }
6056        rec = new PendingIntentRecord(this, key, callingUid);
6057        mIntentSenderRecords.put(key, rec.ref);
6058        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6059            if (activity.pendingResults == null) {
6060                activity.pendingResults
6061                        = new HashSet<WeakReference<PendingIntentRecord>>();
6062            }
6063            activity.pendingResults.add(rec.ref);
6064        }
6065        return rec;
6066    }
6067
6068    @Override
6069    public void cancelIntentSender(IIntentSender sender) {
6070        if (!(sender instanceof PendingIntentRecord)) {
6071            return;
6072        }
6073        synchronized(this) {
6074            PendingIntentRecord rec = (PendingIntentRecord)sender;
6075            try {
6076                int uid = AppGlobals.getPackageManager()
6077                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6078                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6079                    String msg = "Permission Denial: cancelIntentSender() from pid="
6080                        + Binder.getCallingPid()
6081                        + ", uid=" + Binder.getCallingUid()
6082                        + " is not allowed to cancel packges "
6083                        + rec.key.packageName;
6084                    Slog.w(TAG, msg);
6085                    throw new SecurityException(msg);
6086                }
6087            } catch (RemoteException e) {
6088                throw new SecurityException(e);
6089            }
6090            cancelIntentSenderLocked(rec, true);
6091        }
6092    }
6093
6094    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6095        rec.canceled = true;
6096        mIntentSenderRecords.remove(rec.key);
6097        if (cleanActivity && rec.key.activity != null) {
6098            rec.key.activity.pendingResults.remove(rec.ref);
6099        }
6100    }
6101
6102    @Override
6103    public String getPackageForIntentSender(IIntentSender pendingResult) {
6104        if (!(pendingResult instanceof PendingIntentRecord)) {
6105            return null;
6106        }
6107        try {
6108            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6109            return res.key.packageName;
6110        } catch (ClassCastException e) {
6111        }
6112        return null;
6113    }
6114
6115    @Override
6116    public int getUidForIntentSender(IIntentSender sender) {
6117        if (sender instanceof PendingIntentRecord) {
6118            try {
6119                PendingIntentRecord res = (PendingIntentRecord)sender;
6120                return res.uid;
6121            } catch (ClassCastException e) {
6122            }
6123        }
6124        return -1;
6125    }
6126
6127    @Override
6128    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6129        if (!(pendingResult instanceof PendingIntentRecord)) {
6130            return false;
6131        }
6132        try {
6133            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6134            if (res.key.allIntents == null) {
6135                return false;
6136            }
6137            for (int i=0; i<res.key.allIntents.length; i++) {
6138                Intent intent = res.key.allIntents[i];
6139                if (intent.getPackage() != null && intent.getComponent() != null) {
6140                    return false;
6141                }
6142            }
6143            return true;
6144        } catch (ClassCastException e) {
6145        }
6146        return false;
6147    }
6148
6149    @Override
6150    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6151        if (!(pendingResult instanceof PendingIntentRecord)) {
6152            return false;
6153        }
6154        try {
6155            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6156            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6157                return true;
6158            }
6159            return false;
6160        } catch (ClassCastException e) {
6161        }
6162        return false;
6163    }
6164
6165    @Override
6166    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6167        if (!(pendingResult instanceof PendingIntentRecord)) {
6168            return null;
6169        }
6170        try {
6171            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6172            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6173        } catch (ClassCastException e) {
6174        }
6175        return null;
6176    }
6177
6178    @Override
6179    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6180        if (!(pendingResult instanceof PendingIntentRecord)) {
6181            return null;
6182        }
6183        try {
6184            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6185            Intent intent = res.key.requestIntent;
6186            if (intent != null) {
6187                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6188                        || res.lastTagPrefix.equals(prefix))) {
6189                    return res.lastTag;
6190                }
6191                res.lastTagPrefix = prefix;
6192                StringBuilder sb = new StringBuilder(128);
6193                if (prefix != null) {
6194                    sb.append(prefix);
6195                }
6196                if (intent.getAction() != null) {
6197                    sb.append(intent.getAction());
6198                } else if (intent.getComponent() != null) {
6199                    intent.getComponent().appendShortString(sb);
6200                } else {
6201                    sb.append("?");
6202                }
6203                return res.lastTag = sb.toString();
6204            }
6205        } catch (ClassCastException e) {
6206        }
6207        return null;
6208    }
6209
6210    @Override
6211    public void setProcessLimit(int max) {
6212        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6213                "setProcessLimit()");
6214        synchronized (this) {
6215            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6216            mProcessLimitOverride = max;
6217        }
6218        trimApplications();
6219    }
6220
6221    @Override
6222    public int getProcessLimit() {
6223        synchronized (this) {
6224            return mProcessLimitOverride;
6225        }
6226    }
6227
6228    void foregroundTokenDied(ForegroundToken token) {
6229        synchronized (ActivityManagerService.this) {
6230            synchronized (mPidsSelfLocked) {
6231                ForegroundToken cur
6232                    = mForegroundProcesses.get(token.pid);
6233                if (cur != token) {
6234                    return;
6235                }
6236                mForegroundProcesses.remove(token.pid);
6237                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6238                if (pr == null) {
6239                    return;
6240                }
6241                pr.forcingToForeground = null;
6242                updateProcessForegroundLocked(pr, false, false);
6243            }
6244            updateOomAdjLocked();
6245        }
6246    }
6247
6248    @Override
6249    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6250        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6251                "setProcessForeground()");
6252        synchronized(this) {
6253            boolean changed = false;
6254
6255            synchronized (mPidsSelfLocked) {
6256                ProcessRecord pr = mPidsSelfLocked.get(pid);
6257                if (pr == null && isForeground) {
6258                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6259                    return;
6260                }
6261                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6262                if (oldToken != null) {
6263                    oldToken.token.unlinkToDeath(oldToken, 0);
6264                    mForegroundProcesses.remove(pid);
6265                    if (pr != null) {
6266                        pr.forcingToForeground = null;
6267                    }
6268                    changed = true;
6269                }
6270                if (isForeground && token != null) {
6271                    ForegroundToken newToken = new ForegroundToken() {
6272                        @Override
6273                        public void binderDied() {
6274                            foregroundTokenDied(this);
6275                        }
6276                    };
6277                    newToken.pid = pid;
6278                    newToken.token = token;
6279                    try {
6280                        token.linkToDeath(newToken, 0);
6281                        mForegroundProcesses.put(pid, newToken);
6282                        pr.forcingToForeground = token;
6283                        changed = true;
6284                    } catch (RemoteException e) {
6285                        // If the process died while doing this, we will later
6286                        // do the cleanup with the process death link.
6287                    }
6288                }
6289            }
6290
6291            if (changed) {
6292                updateOomAdjLocked();
6293            }
6294        }
6295    }
6296
6297    // =========================================================
6298    // PERMISSIONS
6299    // =========================================================
6300
6301    static class PermissionController extends IPermissionController.Stub {
6302        ActivityManagerService mActivityManagerService;
6303        PermissionController(ActivityManagerService activityManagerService) {
6304            mActivityManagerService = activityManagerService;
6305        }
6306
6307        @Override
6308        public boolean checkPermission(String permission, int pid, int uid) {
6309            return mActivityManagerService.checkPermission(permission, pid,
6310                    uid) == PackageManager.PERMISSION_GRANTED;
6311        }
6312    }
6313
6314    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6315        @Override
6316        public int checkComponentPermission(String permission, int pid, int uid,
6317                int owningUid, boolean exported) {
6318            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6319                    owningUid, exported);
6320        }
6321
6322        @Override
6323        public Object getAMSLock() {
6324            return ActivityManagerService.this;
6325        }
6326    }
6327
6328    /**
6329     * This can be called with or without the global lock held.
6330     */
6331    int checkComponentPermission(String permission, int pid, int uid,
6332            int owningUid, boolean exported) {
6333        // We might be performing an operation on behalf of an indirect binder
6334        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6335        // client identity accordingly before proceeding.
6336        Identity tlsIdentity = sCallerIdentity.get();
6337        if (tlsIdentity != null) {
6338            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6339                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6340            uid = tlsIdentity.uid;
6341            pid = tlsIdentity.pid;
6342        }
6343
6344        if (pid == MY_PID) {
6345            return PackageManager.PERMISSION_GRANTED;
6346        }
6347
6348        return ActivityManager.checkComponentPermission(permission, uid,
6349                owningUid, exported);
6350    }
6351
6352    /**
6353     * As the only public entry point for permissions checking, this method
6354     * can enforce the semantic that requesting a check on a null global
6355     * permission is automatically denied.  (Internally a null permission
6356     * string is used when calling {@link #checkComponentPermission} in cases
6357     * when only uid-based security is needed.)
6358     *
6359     * This can be called with or without the global lock held.
6360     */
6361    @Override
6362    public int checkPermission(String permission, int pid, int uid) {
6363        if (permission == null) {
6364            return PackageManager.PERMISSION_DENIED;
6365        }
6366        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6367    }
6368
6369    /**
6370     * Binder IPC calls go through the public entry point.
6371     * This can be called with or without the global lock held.
6372     */
6373    int checkCallingPermission(String permission) {
6374        return checkPermission(permission,
6375                Binder.getCallingPid(),
6376                UserHandle.getAppId(Binder.getCallingUid()));
6377    }
6378
6379    /**
6380     * This can be called with or without the global lock held.
6381     */
6382    void enforceCallingPermission(String permission, String func) {
6383        if (checkCallingPermission(permission)
6384                == PackageManager.PERMISSION_GRANTED) {
6385            return;
6386        }
6387
6388        String msg = "Permission Denial: " + func + " from pid="
6389                + Binder.getCallingPid()
6390                + ", uid=" + Binder.getCallingUid()
6391                + " requires " + permission;
6392        Slog.w(TAG, msg);
6393        throw new SecurityException(msg);
6394    }
6395
6396    /**
6397     * Determine if UID is holding permissions required to access {@link Uri} in
6398     * the given {@link ProviderInfo}. Final permission checking is always done
6399     * in {@link ContentProvider}.
6400     */
6401    private final boolean checkHoldingPermissionsLocked(
6402            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6403        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6404                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6405        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6406            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6407                    != PERMISSION_GRANTED) {
6408                return false;
6409            }
6410        }
6411        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6412    }
6413
6414    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6415            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6416        if (pi.applicationInfo.uid == uid) {
6417            return true;
6418        } else if (!pi.exported) {
6419            return false;
6420        }
6421
6422        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6423        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6424        try {
6425            // check if target holds top-level <provider> permissions
6426            if (!readMet && pi.readPermission != null && considerUidPermissions
6427                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6428                readMet = true;
6429            }
6430            if (!writeMet && pi.writePermission != null && considerUidPermissions
6431                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6432                writeMet = true;
6433            }
6434
6435            // track if unprotected read/write is allowed; any denied
6436            // <path-permission> below removes this ability
6437            boolean allowDefaultRead = pi.readPermission == null;
6438            boolean allowDefaultWrite = pi.writePermission == null;
6439
6440            // check if target holds any <path-permission> that match uri
6441            final PathPermission[] pps = pi.pathPermissions;
6442            if (pps != null) {
6443                final String path = grantUri.uri.getPath();
6444                int i = pps.length;
6445                while (i > 0 && (!readMet || !writeMet)) {
6446                    i--;
6447                    PathPermission pp = pps[i];
6448                    if (pp.match(path)) {
6449                        if (!readMet) {
6450                            final String pprperm = pp.getReadPermission();
6451                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6452                                    + pprperm + " for " + pp.getPath()
6453                                    + ": match=" + pp.match(path)
6454                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6455                            if (pprperm != null) {
6456                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6457                                        == PERMISSION_GRANTED) {
6458                                    readMet = true;
6459                                } else {
6460                                    allowDefaultRead = false;
6461                                }
6462                            }
6463                        }
6464                        if (!writeMet) {
6465                            final String ppwperm = pp.getWritePermission();
6466                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6467                                    + ppwperm + " for " + pp.getPath()
6468                                    + ": match=" + pp.match(path)
6469                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6470                            if (ppwperm != null) {
6471                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6472                                        == PERMISSION_GRANTED) {
6473                                    writeMet = true;
6474                                } else {
6475                                    allowDefaultWrite = false;
6476                                }
6477                            }
6478                        }
6479                    }
6480                }
6481            }
6482
6483            // grant unprotected <provider> read/write, if not blocked by
6484            // <path-permission> above
6485            if (allowDefaultRead) readMet = true;
6486            if (allowDefaultWrite) writeMet = true;
6487
6488        } catch (RemoteException e) {
6489            return false;
6490        }
6491
6492        return readMet && writeMet;
6493    }
6494
6495    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6496        ProviderInfo pi = null;
6497        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6498        if (cpr != null) {
6499            pi = cpr.info;
6500        } else {
6501            try {
6502                pi = AppGlobals.getPackageManager().resolveContentProvider(
6503                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6504            } catch (RemoteException ex) {
6505            }
6506        }
6507        return pi;
6508    }
6509
6510    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6511        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6512        if (targetUris != null) {
6513            return targetUris.get(grantUri);
6514        }
6515        return null;
6516    }
6517
6518    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6519            String targetPkg, int targetUid, GrantUri grantUri) {
6520        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6521        if (targetUris == null) {
6522            targetUris = Maps.newArrayMap();
6523            mGrantedUriPermissions.put(targetUid, targetUris);
6524        }
6525
6526        UriPermission perm = targetUris.get(grantUri);
6527        if (perm == null) {
6528            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6529            targetUris.put(grantUri, perm);
6530        }
6531
6532        return perm;
6533    }
6534
6535    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6536            final int modeFlags) {
6537        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6538        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6539                : UriPermission.STRENGTH_OWNED;
6540
6541        // Root gets to do everything.
6542        if (uid == 0) {
6543            return true;
6544        }
6545
6546        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6547        if (perms == null) return false;
6548
6549        // First look for exact match
6550        final UriPermission exactPerm = perms.get(grantUri);
6551        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6552            return true;
6553        }
6554
6555        // No exact match, look for prefixes
6556        final int N = perms.size();
6557        for (int i = 0; i < N; i++) {
6558            final UriPermission perm = perms.valueAt(i);
6559            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6560                    && perm.getStrength(modeFlags) >= minStrength) {
6561                return true;
6562            }
6563        }
6564
6565        return false;
6566    }
6567
6568    @Override
6569    public int checkUriPermission(Uri uri, int pid, int uid,
6570            final int modeFlags, int userId) {
6571        enforceNotIsolatedCaller("checkUriPermission");
6572
6573        // Another redirected-binder-call permissions check as in
6574        // {@link checkComponentPermission}.
6575        Identity tlsIdentity = sCallerIdentity.get();
6576        if (tlsIdentity != null) {
6577            uid = tlsIdentity.uid;
6578            pid = tlsIdentity.pid;
6579        }
6580
6581        // Our own process gets to do everything.
6582        if (pid == MY_PID) {
6583            return PackageManager.PERMISSION_GRANTED;
6584        }
6585        synchronized (this) {
6586            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6587                    ? PackageManager.PERMISSION_GRANTED
6588                    : PackageManager.PERMISSION_DENIED;
6589        }
6590    }
6591
6592    /**
6593     * Check if the targetPkg can be granted permission to access uri by
6594     * the callingUid using the given modeFlags.  Throws a security exception
6595     * if callingUid is not allowed to do this.  Returns the uid of the target
6596     * if the URI permission grant should be performed; returns -1 if it is not
6597     * needed (for example targetPkg already has permission to access the URI).
6598     * If you already know the uid of the target, you can supply it in
6599     * lastTargetUid else set that to -1.
6600     */
6601    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6602            final int modeFlags, int lastTargetUid) {
6603        if (!Intent.isAccessUriMode(modeFlags)) {
6604            return -1;
6605        }
6606
6607        if (targetPkg != null) {
6608            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6609                    "Checking grant " + targetPkg + " permission to " + grantUri);
6610        }
6611
6612        final IPackageManager pm = AppGlobals.getPackageManager();
6613
6614        // If this is not a content: uri, we can't do anything with it.
6615        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6616            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6617                    "Can't grant URI permission for non-content URI: " + grantUri);
6618            return -1;
6619        }
6620
6621        final String authority = grantUri.uri.getAuthority();
6622        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6623        if (pi == null) {
6624            Slog.w(TAG, "No content provider found for permission check: " +
6625                    grantUri.uri.toSafeString());
6626            return -1;
6627        }
6628
6629        int targetUid = lastTargetUid;
6630        if (targetUid < 0 && targetPkg != null) {
6631            try {
6632                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6633                if (targetUid < 0) {
6634                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6635                            "Can't grant URI permission no uid for: " + targetPkg);
6636                    return -1;
6637                }
6638            } catch (RemoteException ex) {
6639                return -1;
6640            }
6641        }
6642
6643        if (targetUid >= 0) {
6644            // First...  does the target actually need this permission?
6645            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6646                // No need to grant the target this permission.
6647                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6648                        "Target " + targetPkg + " already has full permission to " + grantUri);
6649                return -1;
6650            }
6651        } else {
6652            // First...  there is no target package, so can anyone access it?
6653            boolean allowed = pi.exported;
6654            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6655                if (pi.readPermission != null) {
6656                    allowed = false;
6657                }
6658            }
6659            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6660                if (pi.writePermission != null) {
6661                    allowed = false;
6662                }
6663            }
6664            if (allowed) {
6665                return -1;
6666            }
6667        }
6668
6669        /* There is a special cross user grant if:
6670         * - The target is on another user.
6671         * - Apps on the current user can access the uri without any uid permissions.
6672         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6673         * grant uri permissions.
6674         */
6675        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6676                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6677                modeFlags, false /*without considering the uid permissions*/);
6678
6679        // Second...  is the provider allowing granting of URI permissions?
6680        if (!specialCrossUserGrant) {
6681            if (!pi.grantUriPermissions) {
6682                throw new SecurityException("Provider " + pi.packageName
6683                        + "/" + pi.name
6684                        + " does not allow granting of Uri permissions (uri "
6685                        + grantUri + ")");
6686            }
6687            if (pi.uriPermissionPatterns != null) {
6688                final int N = pi.uriPermissionPatterns.length;
6689                boolean allowed = false;
6690                for (int i=0; i<N; i++) {
6691                    if (pi.uriPermissionPatterns[i] != null
6692                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6693                        allowed = true;
6694                        break;
6695                    }
6696                }
6697                if (!allowed) {
6698                    throw new SecurityException("Provider " + pi.packageName
6699                            + "/" + pi.name
6700                            + " does not allow granting of permission to path of Uri "
6701                            + grantUri);
6702                }
6703            }
6704        }
6705
6706        // Third...  does the caller itself have permission to access
6707        // this uri?
6708        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6709            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6710                // Require they hold a strong enough Uri permission
6711                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6712                    throw new SecurityException("Uid " + callingUid
6713                            + " does not have permission to uri " + grantUri);
6714                }
6715            }
6716        }
6717        return targetUid;
6718    }
6719
6720    @Override
6721    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6722            final int modeFlags, int userId) {
6723        enforceNotIsolatedCaller("checkGrantUriPermission");
6724        synchronized(this) {
6725            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6726                    new GrantUri(userId, uri, false), modeFlags, -1);
6727        }
6728    }
6729
6730    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6731            final int modeFlags, UriPermissionOwner owner) {
6732        if (!Intent.isAccessUriMode(modeFlags)) {
6733            return;
6734        }
6735
6736        // So here we are: the caller has the assumed permission
6737        // to the uri, and the target doesn't.  Let's now give this to
6738        // the target.
6739
6740        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6741                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6742
6743        final String authority = grantUri.uri.getAuthority();
6744        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6745        if (pi == null) {
6746            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6747            return;
6748        }
6749
6750        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6751            grantUri.prefix = true;
6752        }
6753        final UriPermission perm = findOrCreateUriPermissionLocked(
6754                pi.packageName, targetPkg, targetUid, grantUri);
6755        perm.grantModes(modeFlags, owner);
6756    }
6757
6758    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6759            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6760        if (targetPkg == null) {
6761            throw new NullPointerException("targetPkg");
6762        }
6763        int targetUid;
6764        final IPackageManager pm = AppGlobals.getPackageManager();
6765        try {
6766            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6767        } catch (RemoteException ex) {
6768            return;
6769        }
6770
6771        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6772                targetUid);
6773        if (targetUid < 0) {
6774            return;
6775        }
6776
6777        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6778                owner);
6779    }
6780
6781    static class NeededUriGrants extends ArrayList<GrantUri> {
6782        final String targetPkg;
6783        final int targetUid;
6784        final int flags;
6785
6786        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6787            this.targetPkg = targetPkg;
6788            this.targetUid = targetUid;
6789            this.flags = flags;
6790        }
6791    }
6792
6793    /**
6794     * Like checkGrantUriPermissionLocked, but takes an Intent.
6795     */
6796    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6797            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6798        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6799                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6800                + " clip=" + (intent != null ? intent.getClipData() : null)
6801                + " from " + intent + "; flags=0x"
6802                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6803
6804        if (targetPkg == null) {
6805            throw new NullPointerException("targetPkg");
6806        }
6807
6808        if (intent == null) {
6809            return null;
6810        }
6811        Uri data = intent.getData();
6812        ClipData clip = intent.getClipData();
6813        if (data == null && clip == null) {
6814            return null;
6815        }
6816        // Default userId for uris in the intent (if they don't specify it themselves)
6817        int contentUserHint = intent.getContentUserHint();
6818        if (contentUserHint == UserHandle.USER_CURRENT) {
6819            contentUserHint = UserHandle.getUserId(callingUid);
6820        }
6821        final IPackageManager pm = AppGlobals.getPackageManager();
6822        int targetUid;
6823        if (needed != null) {
6824            targetUid = needed.targetUid;
6825        } else {
6826            try {
6827                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6828            } catch (RemoteException ex) {
6829                return null;
6830            }
6831            if (targetUid < 0) {
6832                if (DEBUG_URI_PERMISSION) {
6833                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6834                            + " on user " + targetUserId);
6835                }
6836                return null;
6837            }
6838        }
6839        if (data != null) {
6840            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6841            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6842                    targetUid);
6843            if (targetUid > 0) {
6844                if (needed == null) {
6845                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6846                }
6847                needed.add(grantUri);
6848            }
6849        }
6850        if (clip != null) {
6851            for (int i=0; i<clip.getItemCount(); i++) {
6852                Uri uri = clip.getItemAt(i).getUri();
6853                if (uri != null) {
6854                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6855                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6856                            targetUid);
6857                    if (targetUid > 0) {
6858                        if (needed == null) {
6859                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6860                        }
6861                        needed.add(grantUri);
6862                    }
6863                } else {
6864                    Intent clipIntent = clip.getItemAt(i).getIntent();
6865                    if (clipIntent != null) {
6866                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6867                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6868                        if (newNeeded != null) {
6869                            needed = newNeeded;
6870                        }
6871                    }
6872                }
6873            }
6874        }
6875
6876        return needed;
6877    }
6878
6879    /**
6880     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6881     */
6882    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6883            UriPermissionOwner owner) {
6884        if (needed != null) {
6885            for (int i=0; i<needed.size(); i++) {
6886                GrantUri grantUri = needed.get(i);
6887                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6888                        grantUri, needed.flags, owner);
6889            }
6890        }
6891    }
6892
6893    void grantUriPermissionFromIntentLocked(int callingUid,
6894            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6895        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6896                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6897        if (needed == null) {
6898            return;
6899        }
6900
6901        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6902    }
6903
6904    @Override
6905    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6906            final int modeFlags, int userId) {
6907        enforceNotIsolatedCaller("grantUriPermission");
6908        GrantUri grantUri = new GrantUri(userId, uri, false);
6909        synchronized(this) {
6910            final ProcessRecord r = getRecordForAppLocked(caller);
6911            if (r == null) {
6912                throw new SecurityException("Unable to find app for caller "
6913                        + caller
6914                        + " when granting permission to uri " + grantUri);
6915            }
6916            if (targetPkg == null) {
6917                throw new IllegalArgumentException("null target");
6918            }
6919            if (grantUri == null) {
6920                throw new IllegalArgumentException("null uri");
6921            }
6922
6923            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6924                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6925                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6926                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6927
6928            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6929                    UserHandle.getUserId(r.uid));
6930        }
6931    }
6932
6933    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6934        if (perm.modeFlags == 0) {
6935            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6936                    perm.targetUid);
6937            if (perms != null) {
6938                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6939                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6940
6941                perms.remove(perm.uri);
6942                if (perms.isEmpty()) {
6943                    mGrantedUriPermissions.remove(perm.targetUid);
6944                }
6945            }
6946        }
6947    }
6948
6949    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6950        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6951
6952        final IPackageManager pm = AppGlobals.getPackageManager();
6953        final String authority = grantUri.uri.getAuthority();
6954        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6955        if (pi == null) {
6956            Slog.w(TAG, "No content provider found for permission revoke: "
6957                    + grantUri.toSafeString());
6958            return;
6959        }
6960
6961        // Does the caller have this permission on the URI?
6962        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6963            // Right now, if you are not the original owner of the permission,
6964            // you are not allowed to revoke it.
6965            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6966                throw new SecurityException("Uid " + callingUid
6967                        + " does not have permission to uri " + grantUri);
6968            //}
6969        }
6970
6971        boolean persistChanged = false;
6972
6973        // Go through all of the permissions and remove any that match.
6974        int N = mGrantedUriPermissions.size();
6975        for (int i = 0; i < N; i++) {
6976            final int targetUid = mGrantedUriPermissions.keyAt(i);
6977            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6978
6979            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6980                final UriPermission perm = it.next();
6981                if (perm.uri.sourceUserId == grantUri.sourceUserId
6982                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6983                    if (DEBUG_URI_PERMISSION)
6984                        Slog.v(TAG,
6985                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6986                    persistChanged |= perm.revokeModes(
6987                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6988                    if (perm.modeFlags == 0) {
6989                        it.remove();
6990                    }
6991                }
6992            }
6993
6994            if (perms.isEmpty()) {
6995                mGrantedUriPermissions.remove(targetUid);
6996                N--;
6997                i--;
6998            }
6999        }
7000
7001        if (persistChanged) {
7002            schedulePersistUriGrants();
7003        }
7004    }
7005
7006    @Override
7007    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7008            int userId) {
7009        enforceNotIsolatedCaller("revokeUriPermission");
7010        synchronized(this) {
7011            final ProcessRecord r = getRecordForAppLocked(caller);
7012            if (r == null) {
7013                throw new SecurityException("Unable to find app for caller "
7014                        + caller
7015                        + " when revoking permission to uri " + uri);
7016            }
7017            if (uri == null) {
7018                Slog.w(TAG, "revokeUriPermission: null uri");
7019                return;
7020            }
7021
7022            if (!Intent.isAccessUriMode(modeFlags)) {
7023                return;
7024            }
7025
7026            final IPackageManager pm = AppGlobals.getPackageManager();
7027            final String authority = uri.getAuthority();
7028            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7029            if (pi == null) {
7030                Slog.w(TAG, "No content provider found for permission revoke: "
7031                        + uri.toSafeString());
7032                return;
7033            }
7034
7035            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7036        }
7037    }
7038
7039    /**
7040     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7041     * given package.
7042     *
7043     * @param packageName Package name to match, or {@code null} to apply to all
7044     *            packages.
7045     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7046     *            to all users.
7047     * @param persistable If persistable grants should be removed.
7048     */
7049    private void removeUriPermissionsForPackageLocked(
7050            String packageName, int userHandle, boolean persistable) {
7051        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7052            throw new IllegalArgumentException("Must narrow by either package or user");
7053        }
7054
7055        boolean persistChanged = false;
7056
7057        int N = mGrantedUriPermissions.size();
7058        for (int i = 0; i < N; i++) {
7059            final int targetUid = mGrantedUriPermissions.keyAt(i);
7060            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7061
7062            // Only inspect grants matching user
7063            if (userHandle == UserHandle.USER_ALL
7064                    || userHandle == UserHandle.getUserId(targetUid)) {
7065                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7066                    final UriPermission perm = it.next();
7067
7068                    // Only inspect grants matching package
7069                    if (packageName == null || perm.sourcePkg.equals(packageName)
7070                            || perm.targetPkg.equals(packageName)) {
7071                        persistChanged |= perm.revokeModes(
7072                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7073
7074                        // Only remove when no modes remain; any persisted grants
7075                        // will keep this alive.
7076                        if (perm.modeFlags == 0) {
7077                            it.remove();
7078                        }
7079                    }
7080                }
7081
7082                if (perms.isEmpty()) {
7083                    mGrantedUriPermissions.remove(targetUid);
7084                    N--;
7085                    i--;
7086                }
7087            }
7088        }
7089
7090        if (persistChanged) {
7091            schedulePersistUriGrants();
7092        }
7093    }
7094
7095    @Override
7096    public IBinder newUriPermissionOwner(String name) {
7097        enforceNotIsolatedCaller("newUriPermissionOwner");
7098        synchronized(this) {
7099            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7100            return owner.getExternalTokenLocked();
7101        }
7102    }
7103
7104    @Override
7105    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7106            final int modeFlags, int sourceUserId, int targetUserId) {
7107        synchronized(this) {
7108            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7109            if (owner == null) {
7110                throw new IllegalArgumentException("Unknown owner: " + token);
7111            }
7112            if (fromUid != Binder.getCallingUid()) {
7113                if (Binder.getCallingUid() != Process.myUid()) {
7114                    // Only system code can grant URI permissions on behalf
7115                    // of other users.
7116                    throw new SecurityException("nice try");
7117                }
7118            }
7119            if (targetPkg == null) {
7120                throw new IllegalArgumentException("null target");
7121            }
7122            if (uri == null) {
7123                throw new IllegalArgumentException("null uri");
7124            }
7125
7126            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7127                    modeFlags, owner, targetUserId);
7128        }
7129    }
7130
7131    @Override
7132    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7133        synchronized(this) {
7134            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7135            if (owner == null) {
7136                throw new IllegalArgumentException("Unknown owner: " + token);
7137            }
7138
7139            if (uri == null) {
7140                owner.removeUriPermissionsLocked(mode);
7141            } else {
7142                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7143            }
7144        }
7145    }
7146
7147    private void schedulePersistUriGrants() {
7148        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7149            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7150                    10 * DateUtils.SECOND_IN_MILLIS);
7151        }
7152    }
7153
7154    private void writeGrantedUriPermissions() {
7155        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7156
7157        // Snapshot permissions so we can persist without lock
7158        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7159        synchronized (this) {
7160            final int size = mGrantedUriPermissions.size();
7161            for (int i = 0; i < size; i++) {
7162                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7163                for (UriPermission perm : perms.values()) {
7164                    if (perm.persistedModeFlags != 0) {
7165                        persist.add(perm.snapshot());
7166                    }
7167                }
7168            }
7169        }
7170
7171        FileOutputStream fos = null;
7172        try {
7173            fos = mGrantFile.startWrite();
7174
7175            XmlSerializer out = new FastXmlSerializer();
7176            out.setOutput(fos, "utf-8");
7177            out.startDocument(null, true);
7178            out.startTag(null, TAG_URI_GRANTS);
7179            for (UriPermission.Snapshot perm : persist) {
7180                out.startTag(null, TAG_URI_GRANT);
7181                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7182                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7183                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7184                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7185                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7186                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7187                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7188                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7189                out.endTag(null, TAG_URI_GRANT);
7190            }
7191            out.endTag(null, TAG_URI_GRANTS);
7192            out.endDocument();
7193
7194            mGrantFile.finishWrite(fos);
7195        } catch (IOException e) {
7196            if (fos != null) {
7197                mGrantFile.failWrite(fos);
7198            }
7199        }
7200    }
7201
7202    private void readGrantedUriPermissionsLocked() {
7203        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7204
7205        final long now = System.currentTimeMillis();
7206
7207        FileInputStream fis = null;
7208        try {
7209            fis = mGrantFile.openRead();
7210            final XmlPullParser in = Xml.newPullParser();
7211            in.setInput(fis, null);
7212
7213            int type;
7214            while ((type = in.next()) != END_DOCUMENT) {
7215                final String tag = in.getName();
7216                if (type == START_TAG) {
7217                    if (TAG_URI_GRANT.equals(tag)) {
7218                        final int sourceUserId;
7219                        final int targetUserId;
7220                        final int userHandle = readIntAttribute(in,
7221                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7222                        if (userHandle != UserHandle.USER_NULL) {
7223                            // For backwards compatibility.
7224                            sourceUserId = userHandle;
7225                            targetUserId = userHandle;
7226                        } else {
7227                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7228                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7229                        }
7230                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7231                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7232                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7233                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7234                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7235                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7236
7237                        // Sanity check that provider still belongs to source package
7238                        final ProviderInfo pi = getProviderInfoLocked(
7239                                uri.getAuthority(), sourceUserId);
7240                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7241                            int targetUid = -1;
7242                            try {
7243                                targetUid = AppGlobals.getPackageManager()
7244                                        .getPackageUid(targetPkg, targetUserId);
7245                            } catch (RemoteException e) {
7246                            }
7247                            if (targetUid != -1) {
7248                                final UriPermission perm = findOrCreateUriPermissionLocked(
7249                                        sourcePkg, targetPkg, targetUid,
7250                                        new GrantUri(sourceUserId, uri, prefix));
7251                                perm.initPersistedModes(modeFlags, createdTime);
7252                            }
7253                        } else {
7254                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7255                                    + " but instead found " + pi);
7256                        }
7257                    }
7258                }
7259            }
7260        } catch (FileNotFoundException e) {
7261            // Missing grants is okay
7262        } catch (IOException e) {
7263            Log.wtf(TAG, "Failed reading Uri grants", e);
7264        } catch (XmlPullParserException e) {
7265            Log.wtf(TAG, "Failed reading Uri grants", e);
7266        } finally {
7267            IoUtils.closeQuietly(fis);
7268        }
7269    }
7270
7271    @Override
7272    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7273        enforceNotIsolatedCaller("takePersistableUriPermission");
7274
7275        Preconditions.checkFlagsArgument(modeFlags,
7276                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7277
7278        synchronized (this) {
7279            final int callingUid = Binder.getCallingUid();
7280            boolean persistChanged = false;
7281            GrantUri grantUri = new GrantUri(userId, uri, false);
7282
7283            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7284                    new GrantUri(userId, uri, false));
7285            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7286                    new GrantUri(userId, uri, true));
7287
7288            final boolean exactValid = (exactPerm != null)
7289                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7290            final boolean prefixValid = (prefixPerm != null)
7291                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7292
7293            if (!(exactValid || prefixValid)) {
7294                throw new SecurityException("No persistable permission grants found for UID "
7295                        + callingUid + " and Uri " + grantUri.toSafeString());
7296            }
7297
7298            if (exactValid) {
7299                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7300            }
7301            if (prefixValid) {
7302                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7303            }
7304
7305            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7306
7307            if (persistChanged) {
7308                schedulePersistUriGrants();
7309            }
7310        }
7311    }
7312
7313    @Override
7314    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7315        enforceNotIsolatedCaller("releasePersistableUriPermission");
7316
7317        Preconditions.checkFlagsArgument(modeFlags,
7318                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7319
7320        synchronized (this) {
7321            final int callingUid = Binder.getCallingUid();
7322            boolean persistChanged = false;
7323
7324            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7325                    new GrantUri(userId, uri, false));
7326            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7327                    new GrantUri(userId, uri, true));
7328            if (exactPerm == null && prefixPerm == null) {
7329                throw new SecurityException("No permission grants found for UID " + callingUid
7330                        + " and Uri " + uri.toSafeString());
7331            }
7332
7333            if (exactPerm != null) {
7334                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7335                removeUriPermissionIfNeededLocked(exactPerm);
7336            }
7337            if (prefixPerm != null) {
7338                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7339                removeUriPermissionIfNeededLocked(prefixPerm);
7340            }
7341
7342            if (persistChanged) {
7343                schedulePersistUriGrants();
7344            }
7345        }
7346    }
7347
7348    /**
7349     * Prune any older {@link UriPermission} for the given UID until outstanding
7350     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7351     *
7352     * @return if any mutations occured that require persisting.
7353     */
7354    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7355        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7356        if (perms == null) return false;
7357        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7358
7359        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7360        for (UriPermission perm : perms.values()) {
7361            if (perm.persistedModeFlags != 0) {
7362                persisted.add(perm);
7363            }
7364        }
7365
7366        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7367        if (trimCount <= 0) return false;
7368
7369        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7370        for (int i = 0; i < trimCount; i++) {
7371            final UriPermission perm = persisted.get(i);
7372
7373            if (DEBUG_URI_PERMISSION) {
7374                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7375            }
7376
7377            perm.releasePersistableModes(~0);
7378            removeUriPermissionIfNeededLocked(perm);
7379        }
7380
7381        return true;
7382    }
7383
7384    @Override
7385    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7386            String packageName, boolean incoming) {
7387        enforceNotIsolatedCaller("getPersistedUriPermissions");
7388        Preconditions.checkNotNull(packageName, "packageName");
7389
7390        final int callingUid = Binder.getCallingUid();
7391        final IPackageManager pm = AppGlobals.getPackageManager();
7392        try {
7393            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7394            if (packageUid != callingUid) {
7395                throw new SecurityException(
7396                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7397            }
7398        } catch (RemoteException e) {
7399            throw new SecurityException("Failed to verify package name ownership");
7400        }
7401
7402        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7403        synchronized (this) {
7404            if (incoming) {
7405                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7406                        callingUid);
7407                if (perms == null) {
7408                    Slog.w(TAG, "No permission grants found for " + packageName);
7409                } else {
7410                    for (UriPermission perm : perms.values()) {
7411                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7412                            result.add(perm.buildPersistedPublicApiObject());
7413                        }
7414                    }
7415                }
7416            } else {
7417                final int size = mGrantedUriPermissions.size();
7418                for (int i = 0; i < size; i++) {
7419                    final ArrayMap<GrantUri, UriPermission> perms =
7420                            mGrantedUriPermissions.valueAt(i);
7421                    for (UriPermission perm : perms.values()) {
7422                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7423                            result.add(perm.buildPersistedPublicApiObject());
7424                        }
7425                    }
7426                }
7427            }
7428        }
7429        return new ParceledListSlice<android.content.UriPermission>(result);
7430    }
7431
7432    @Override
7433    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7434        synchronized (this) {
7435            ProcessRecord app =
7436                who != null ? getRecordForAppLocked(who) : null;
7437            if (app == null) return;
7438
7439            Message msg = Message.obtain();
7440            msg.what = WAIT_FOR_DEBUGGER_MSG;
7441            msg.obj = app;
7442            msg.arg1 = waiting ? 1 : 0;
7443            mHandler.sendMessage(msg);
7444        }
7445    }
7446
7447    @Override
7448    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7449        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7450        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7451        outInfo.availMem = Process.getFreeMemory();
7452        outInfo.totalMem = Process.getTotalMemory();
7453        outInfo.threshold = homeAppMem;
7454        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7455        outInfo.hiddenAppThreshold = cachedAppMem;
7456        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7457                ProcessList.SERVICE_ADJ);
7458        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7459                ProcessList.VISIBLE_APP_ADJ);
7460        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7461                ProcessList.FOREGROUND_APP_ADJ);
7462    }
7463
7464    // =========================================================
7465    // TASK MANAGEMENT
7466    // =========================================================
7467
7468    @Override
7469    public List<IAppTask> getAppTasks() {
7470        final PackageManager pm = mContext.getPackageManager();
7471        int callingUid = Binder.getCallingUid();
7472        long ident = Binder.clearCallingIdentity();
7473
7474        // Compose the list of packages for this id to test against
7475        HashSet<String> packages = new HashSet<String>();
7476        String[] uidPackages = pm.getPackagesForUid(callingUid);
7477        for (int i = 0; i < uidPackages.length; i++) {
7478            packages.add(uidPackages[i]);
7479        }
7480
7481        synchronized(this) {
7482            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7483            try {
7484                if (localLOGV) Slog.v(TAG, "getAppTasks");
7485
7486                final int N = mRecentTasks.size();
7487                for (int i = 0; i < N; i++) {
7488                    TaskRecord tr = mRecentTasks.get(i);
7489                    // Skip tasks that do not match the package name
7490                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7491                        ActivityManager.RecentTaskInfo taskInfo =
7492                                createRecentTaskInfoFromTaskRecord(tr);
7493                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7494                        list.add(taskImpl);
7495                    }
7496                }
7497            } finally {
7498                Binder.restoreCallingIdentity(ident);
7499            }
7500            return list;
7501        }
7502    }
7503
7504    @Override
7505    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7506        final int callingUid = Binder.getCallingUid();
7507        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7508
7509        synchronized(this) {
7510            if (localLOGV) Slog.v(
7511                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7512
7513            final boolean allowed = checkCallingPermission(
7514                    android.Manifest.permission.GET_TASKS)
7515                    == PackageManager.PERMISSION_GRANTED;
7516            if (!allowed) {
7517                Slog.w(TAG, "getTasks: caller " + callingUid
7518                        + " does not hold GET_TASKS; limiting output");
7519            }
7520
7521            // TODO: Improve with MRU list from all ActivityStacks.
7522            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7523        }
7524
7525        return list;
7526    }
7527
7528    TaskRecord getMostRecentTask() {
7529        return mRecentTasks.get(0);
7530    }
7531
7532    /**
7533     * Creates a new RecentTaskInfo from a TaskRecord.
7534     */
7535    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7536        // Update the task description to reflect any changes in the task stack
7537        tr.updateTaskDescription();
7538
7539        // Compose the recent task info
7540        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7541        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7542        rti.persistentId = tr.taskId;
7543        rti.baseIntent = new Intent(tr.getBaseIntent());
7544        rti.origActivity = tr.origActivity;
7545        rti.description = tr.lastDescription;
7546        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7547        rti.userId = tr.userId;
7548        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7549        rti.firstActiveTime = tr.firstActiveTime;
7550        rti.lastActiveTime = tr.lastActiveTime;
7551        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7552        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
7553        return rti;
7554    }
7555
7556    @Override
7557    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7558        final int callingUid = Binder.getCallingUid();
7559        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7560                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7561
7562        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7563        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7564        synchronized (this) {
7565            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7566                    == PackageManager.PERMISSION_GRANTED;
7567            if (!allowed) {
7568                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7569                        + " does not hold GET_TASKS; limiting output");
7570            }
7571            final boolean detailed = checkCallingPermission(
7572                    android.Manifest.permission.GET_DETAILED_TASKS)
7573                    == PackageManager.PERMISSION_GRANTED;
7574
7575            IPackageManager pm = AppGlobals.getPackageManager();
7576
7577            final int N = mRecentTasks.size();
7578            ArrayList<ActivityManager.RecentTaskInfo> res
7579                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7580                            maxNum < N ? maxNum : N);
7581
7582            final Set<Integer> includedUsers;
7583            if (includeProfiles) {
7584                includedUsers = getProfileIdsLocked(userId);
7585            } else {
7586                includedUsers = new HashSet<Integer>();
7587            }
7588            includedUsers.add(Integer.valueOf(userId));
7589
7590            // Regroup affiliated tasks together.
7591            for (int i = 0; i < N; ) {
7592                TaskRecord task = mRecentTasks.remove(i);
7593                if (mTmpRecents.contains(task)) {
7594                    continue;
7595                }
7596                int affiliatedTaskId = task.mAffiliatedTaskId;
7597                while (true) {
7598                    TaskRecord next = task.mNextAffiliate;
7599                    if (next == null) {
7600                        break;
7601                    }
7602                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7603                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7604                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7605                        task.setNextAffiliate(null);
7606                        if (next.mPrevAffiliate == task) {
7607                            next.setPrevAffiliate(null);
7608                        }
7609                        break;
7610                    }
7611                    if (next.mPrevAffiliate != task) {
7612                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7613                                next.mPrevAffiliate + " task=" + task);
7614                        next.setPrevAffiliate(null);
7615                        break;
7616                    }
7617                    if (!mRecentTasks.contains(next)) {
7618                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7619                        task.setNextAffiliate(null);
7620                        if (next.mPrevAffiliate == task) {
7621                            next.setPrevAffiliate(null);
7622                        }
7623                        break;
7624                    }
7625                    task = next;
7626                }
7627                // task is now the end of the list
7628                do {
7629                    mRecentTasks.remove(task);
7630                    mRecentTasks.add(i++, task);
7631                    mTmpRecents.add(task);
7632                } while ((task = task.mPrevAffiliate) != null);
7633            }
7634            mTmpRecents.clear();
7635            // mRecentTasks is now in sorted, affiliated order.
7636
7637            for (int i=0; i<N && maxNum > 0; i++) {
7638                TaskRecord tr = mRecentTasks.get(i);
7639                // Only add calling user or related users recent tasks
7640                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7641
7642                // Return the entry if desired by the caller.  We always return
7643                // the first entry, because callers always expect this to be the
7644                // foreground app.  We may filter others if the caller has
7645                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7646                // we should exclude the entry.
7647
7648                if (i == 0
7649                        || withExcluded
7650                        || (tr.intent == null)
7651                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7652                                == 0)) {
7653                    if (!allowed) {
7654                        // If the caller doesn't have the GET_TASKS permission, then only
7655                        // allow them to see a small subset of tasks -- their own and home.
7656                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7657                            continue;
7658                        }
7659                    }
7660                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7661                        // Don't include auto remove tasks that are finished or finishing.
7662                        continue;
7663                    }
7664
7665                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7666                    if (!detailed) {
7667                        rti.baseIntent.replaceExtras((Bundle)null);
7668                    }
7669
7670                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7671                        // Check whether this activity is currently available.
7672                        try {
7673                            if (rti.origActivity != null) {
7674                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7675                                        == null) {
7676                                    continue;
7677                                }
7678                            } else if (rti.baseIntent != null) {
7679                                if (pm.queryIntentActivities(rti.baseIntent,
7680                                        null, 0, userId) == null) {
7681                                    continue;
7682                                }
7683                            }
7684                        } catch (RemoteException e) {
7685                            // Will never happen.
7686                        }
7687                    }
7688
7689                    res.add(rti);
7690                    maxNum--;
7691                }
7692            }
7693            return res;
7694        }
7695    }
7696
7697    private TaskRecord recentTaskForIdLocked(int id) {
7698        final int N = mRecentTasks.size();
7699            for (int i=0; i<N; i++) {
7700                TaskRecord tr = mRecentTasks.get(i);
7701                if (tr.taskId == id) {
7702                    return tr;
7703                }
7704            }
7705            return null;
7706    }
7707
7708    @Override
7709    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7710        synchronized (this) {
7711            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7712                    "getTaskThumbnail()");
7713            TaskRecord tr = recentTaskForIdLocked(id);
7714            if (tr != null) {
7715                return tr.getTaskThumbnailLocked();
7716            }
7717        }
7718        return null;
7719    }
7720
7721    @Override
7722    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7723        synchronized (this) {
7724            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7725            if (r != null) {
7726                r.taskDescription = td;
7727                r.task.updateTaskDescription();
7728            }
7729        }
7730    }
7731
7732    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7733        if (!pr.killedByAm) {
7734            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7735            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7736                    pr.processName, pr.setAdj, reason);
7737            pr.killedByAm = true;
7738            Process.killProcessQuiet(pr.pid);
7739            Process.killProcessGroup(pr.info.uid, pr.pid);
7740        }
7741    }
7742
7743    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7744        tr.disposeThumbnail();
7745        mRecentTasks.remove(tr);
7746        tr.closeRecentsChain();
7747        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7748        Intent baseIntent = new Intent(
7749                tr.intent != null ? tr.intent : tr.affinityIntent);
7750        ComponentName component = baseIntent.getComponent();
7751        if (component == null) {
7752            Slog.w(TAG, "Now component for base intent of task: " + tr);
7753            return;
7754        }
7755
7756        // Find any running services associated with this app.
7757        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7758
7759        if (killProcesses) {
7760            // Find any running processes associated with this app.
7761            final String pkg = component.getPackageName();
7762            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7763            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7764            for (int i=0; i<pmap.size(); i++) {
7765                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7766                for (int j=0; j<uids.size(); j++) {
7767                    ProcessRecord proc = uids.valueAt(j);
7768                    if (proc.userId != tr.userId) {
7769                        continue;
7770                    }
7771                    if (!proc.pkgList.containsKey(pkg)) {
7772                        continue;
7773                    }
7774                    procs.add(proc);
7775                }
7776            }
7777
7778            // Kill the running processes.
7779            for (int i=0; i<procs.size(); i++) {
7780                ProcessRecord pr = procs.get(i);
7781                if (pr == mHomeProcess) {
7782                    // Don't kill the home process along with tasks from the same package.
7783                    continue;
7784                }
7785                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7786                    killUnneededProcessLocked(pr, "remove task");
7787                } else {
7788                    pr.waitingToKill = "remove task";
7789                }
7790            }
7791        }
7792    }
7793
7794    /**
7795     * Removes the task with the specified task id.
7796     *
7797     * @param taskId Identifier of the task to be removed.
7798     * @param flags Additional operational flags.  May be 0 or
7799     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7800     * @return Returns true if the given task was found and removed.
7801     */
7802    private boolean removeTaskByIdLocked(int taskId, int flags) {
7803        TaskRecord tr = recentTaskForIdLocked(taskId);
7804        if (tr != null) {
7805            tr.removeTaskActivitiesLocked();
7806            cleanUpRemovedTaskLocked(tr, flags);
7807            if (tr.isPersistable) {
7808                notifyTaskPersisterLocked(null, true);
7809            }
7810            return true;
7811        }
7812        return false;
7813    }
7814
7815    @Override
7816    public boolean removeTask(int taskId, int flags) {
7817        synchronized (this) {
7818            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7819                    "removeTask()");
7820            long ident = Binder.clearCallingIdentity();
7821            try {
7822                return removeTaskByIdLocked(taskId, flags);
7823            } finally {
7824                Binder.restoreCallingIdentity(ident);
7825            }
7826        }
7827    }
7828
7829    /**
7830     * TODO: Add mController hook
7831     */
7832    @Override
7833    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7834        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7835                "moveTaskToFront()");
7836
7837        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7838        synchronized(this) {
7839            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7840                    Binder.getCallingUid(), "Task to front")) {
7841                ActivityOptions.abort(options);
7842                return;
7843            }
7844            final long origId = Binder.clearCallingIdentity();
7845            try {
7846                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7847                if (task == null) {
7848                    return;
7849                }
7850                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7851                    mStackSupervisor.showLockTaskToast();
7852                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7853                    return;
7854                }
7855                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7856                if (prev != null && prev.isRecentsActivity()) {
7857                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7858                }
7859                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7860            } finally {
7861                Binder.restoreCallingIdentity(origId);
7862            }
7863            ActivityOptions.abort(options);
7864        }
7865    }
7866
7867    @Override
7868    public void moveTaskToBack(int taskId) {
7869        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7870                "moveTaskToBack()");
7871
7872        synchronized(this) {
7873            TaskRecord tr = recentTaskForIdLocked(taskId);
7874            if (tr != null) {
7875                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7876                ActivityStack stack = tr.stack;
7877                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7878                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7879                            Binder.getCallingUid(), "Task to back")) {
7880                        return;
7881                    }
7882                }
7883                final long origId = Binder.clearCallingIdentity();
7884                try {
7885                    stack.moveTaskToBackLocked(taskId, null);
7886                } finally {
7887                    Binder.restoreCallingIdentity(origId);
7888                }
7889            }
7890        }
7891    }
7892
7893    /**
7894     * Moves an activity, and all of the other activities within the same task, to the bottom
7895     * of the history stack.  The activity's order within the task is unchanged.
7896     *
7897     * @param token A reference to the activity we wish to move
7898     * @param nonRoot If false then this only works if the activity is the root
7899     *                of a task; if true it will work for any activity in a task.
7900     * @return Returns true if the move completed, false if not.
7901     */
7902    @Override
7903    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7904        enforceNotIsolatedCaller("moveActivityTaskToBack");
7905        synchronized(this) {
7906            final long origId = Binder.clearCallingIdentity();
7907            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7908            if (taskId >= 0) {
7909                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7910            }
7911            Binder.restoreCallingIdentity(origId);
7912        }
7913        return false;
7914    }
7915
7916    @Override
7917    public void moveTaskBackwards(int task) {
7918        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7919                "moveTaskBackwards()");
7920
7921        synchronized(this) {
7922            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7923                    Binder.getCallingUid(), "Task backwards")) {
7924                return;
7925            }
7926            final long origId = Binder.clearCallingIdentity();
7927            moveTaskBackwardsLocked(task);
7928            Binder.restoreCallingIdentity(origId);
7929        }
7930    }
7931
7932    private final void moveTaskBackwardsLocked(int task) {
7933        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7934    }
7935
7936    @Override
7937    public IBinder getHomeActivityToken() throws RemoteException {
7938        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7939                "getHomeActivityToken()");
7940        synchronized (this) {
7941            return mStackSupervisor.getHomeActivityToken();
7942        }
7943    }
7944
7945    @Override
7946    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7947            IActivityContainerCallback callback) throws RemoteException {
7948        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7949                "createActivityContainer()");
7950        synchronized (this) {
7951            if (parentActivityToken == null) {
7952                throw new IllegalArgumentException("parent token must not be null");
7953            }
7954            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7955            if (r == null) {
7956                return null;
7957            }
7958            if (callback == null) {
7959                throw new IllegalArgumentException("callback must not be null");
7960            }
7961            return mStackSupervisor.createActivityContainer(r, callback);
7962        }
7963    }
7964
7965    @Override
7966    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7967        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7968                "deleteActivityContainer()");
7969        synchronized (this) {
7970            mStackSupervisor.deleteActivityContainer(container);
7971        }
7972    }
7973
7974    @Override
7975    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7976            throws RemoteException {
7977        synchronized (this) {
7978            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7979            if (stack != null) {
7980                return stack.mActivityContainer;
7981            }
7982            return null;
7983        }
7984    }
7985
7986    @Override
7987    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7988        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7989                "moveTaskToStack()");
7990        if (stackId == HOME_STACK_ID) {
7991            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7992                    new RuntimeException("here").fillInStackTrace());
7993        }
7994        synchronized (this) {
7995            long ident = Binder.clearCallingIdentity();
7996            try {
7997                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7998                        + stackId + " toTop=" + toTop);
7999                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8000            } finally {
8001                Binder.restoreCallingIdentity(ident);
8002            }
8003        }
8004    }
8005
8006    @Override
8007    public void resizeStack(int stackBoxId, Rect bounds) {
8008        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8009                "resizeStackBox()");
8010        long ident = Binder.clearCallingIdentity();
8011        try {
8012            mWindowManager.resizeStack(stackBoxId, bounds);
8013        } finally {
8014            Binder.restoreCallingIdentity(ident);
8015        }
8016    }
8017
8018    @Override
8019    public List<StackInfo> getAllStackInfos() {
8020        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8021                "getAllStackInfos()");
8022        long ident = Binder.clearCallingIdentity();
8023        try {
8024            synchronized (this) {
8025                return mStackSupervisor.getAllStackInfosLocked();
8026            }
8027        } finally {
8028            Binder.restoreCallingIdentity(ident);
8029        }
8030    }
8031
8032    @Override
8033    public StackInfo getStackInfo(int stackId) {
8034        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8035                "getStackInfo()");
8036        long ident = Binder.clearCallingIdentity();
8037        try {
8038            synchronized (this) {
8039                return mStackSupervisor.getStackInfoLocked(stackId);
8040            }
8041        } finally {
8042            Binder.restoreCallingIdentity(ident);
8043        }
8044    }
8045
8046    @Override
8047    public boolean isInHomeStack(int taskId) {
8048        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8049                "getStackInfo()");
8050        long ident = Binder.clearCallingIdentity();
8051        try {
8052            synchronized (this) {
8053                TaskRecord tr = recentTaskForIdLocked(taskId);
8054                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8055            }
8056        } finally {
8057            Binder.restoreCallingIdentity(ident);
8058        }
8059    }
8060
8061    @Override
8062    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8063        synchronized(this) {
8064            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8065        }
8066    }
8067
8068    private boolean isLockTaskAuthorized(String pkg) {
8069        final DevicePolicyManager dpm = (DevicePolicyManager)
8070                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8071        try {
8072            int uid = mContext.getPackageManager().getPackageUid(pkg,
8073                    Binder.getCallingUserHandle().getIdentifier());
8074            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8075        } catch (NameNotFoundException e) {
8076            return false;
8077        }
8078    }
8079
8080    void startLockTaskMode(TaskRecord task) {
8081        final String pkg;
8082        synchronized (this) {
8083            pkg = task.intent.getComponent().getPackageName();
8084        }
8085        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8086        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8087            final TaskRecord taskRecord = task;
8088            mHandler.post(new Runnable() {
8089                @Override
8090                public void run() {
8091                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8092                }
8093            });
8094            return;
8095        }
8096        long ident = Binder.clearCallingIdentity();
8097        try {
8098            synchronized (this) {
8099                // Since we lost lock on task, make sure it is still there.
8100                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8101                if (task != null) {
8102                    if (!isSystemInitiated
8103                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8104                        throw new IllegalArgumentException("Invalid task, not in foreground");
8105                    }
8106                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8107                }
8108            }
8109        } finally {
8110            Binder.restoreCallingIdentity(ident);
8111        }
8112    }
8113
8114    @Override
8115    public void startLockTaskMode(int taskId) {
8116        final TaskRecord task;
8117        long ident = Binder.clearCallingIdentity();
8118        try {
8119            synchronized (this) {
8120                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8121            }
8122        } finally {
8123            Binder.restoreCallingIdentity(ident);
8124        }
8125        if (task != null) {
8126            startLockTaskMode(task);
8127        }
8128    }
8129
8130    @Override
8131    public void startLockTaskMode(IBinder token) {
8132        final TaskRecord task;
8133        long ident = Binder.clearCallingIdentity();
8134        try {
8135            synchronized (this) {
8136                final ActivityRecord r = ActivityRecord.forToken(token);
8137                if (r == null) {
8138                    return;
8139                }
8140                task = r.task;
8141            }
8142        } finally {
8143            Binder.restoreCallingIdentity(ident);
8144        }
8145        if (task != null) {
8146            startLockTaskMode(task);
8147        }
8148    }
8149
8150    @Override
8151    public void startLockTaskModeOnCurrent() throws RemoteException {
8152        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8153        ActivityRecord r = null;
8154        synchronized (this) {
8155            r = mStackSupervisor.topRunningActivityLocked();
8156        }
8157        startLockTaskMode(r.task);
8158    }
8159
8160    @Override
8161    public void stopLockTaskMode() {
8162        // Verify that the user matches the package of the intent for the TaskRecord
8163        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8164        // and stopLockTaskMode.
8165        final int callingUid = Binder.getCallingUid();
8166        if (callingUid != Process.SYSTEM_UID) {
8167            try {
8168                String pkg =
8169                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8170                int uid = mContext.getPackageManager().getPackageUid(pkg,
8171                        Binder.getCallingUserHandle().getIdentifier());
8172                if (uid != callingUid) {
8173                    throw new SecurityException("Invalid uid, expected " + uid);
8174                }
8175            } catch (NameNotFoundException e) {
8176                Log.d(TAG, "stopLockTaskMode " + e);
8177                return;
8178            }
8179        }
8180        long ident = Binder.clearCallingIdentity();
8181        try {
8182            Log.d(TAG, "stopLockTaskMode");
8183            // Stop lock task
8184            synchronized (this) {
8185                mStackSupervisor.setLockTaskModeLocked(null, false);
8186            }
8187        } finally {
8188            Binder.restoreCallingIdentity(ident);
8189        }
8190    }
8191
8192    @Override
8193    public void stopLockTaskModeOnCurrent() throws RemoteException {
8194        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8195        long ident = Binder.clearCallingIdentity();
8196        try {
8197            stopLockTaskMode();
8198        } finally {
8199            Binder.restoreCallingIdentity(ident);
8200        }
8201    }
8202
8203    @Override
8204    public boolean isInLockTaskMode() {
8205        synchronized (this) {
8206            return mStackSupervisor.isInLockTaskMode();
8207        }
8208    }
8209
8210    // =========================================================
8211    // CONTENT PROVIDERS
8212    // =========================================================
8213
8214    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8215        List<ProviderInfo> providers = null;
8216        try {
8217            providers = AppGlobals.getPackageManager().
8218                queryContentProviders(app.processName, app.uid,
8219                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8220        } catch (RemoteException ex) {
8221        }
8222        if (DEBUG_MU)
8223            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8224        int userId = app.userId;
8225        if (providers != null) {
8226            int N = providers.size();
8227            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8228            for (int i=0; i<N; i++) {
8229                ProviderInfo cpi =
8230                    (ProviderInfo)providers.get(i);
8231                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8232                        cpi.name, cpi.flags);
8233                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8234                    // This is a singleton provider, but a user besides the
8235                    // default user is asking to initialize a process it runs
8236                    // in...  well, no, it doesn't actually run in this process,
8237                    // it runs in the process of the default user.  Get rid of it.
8238                    providers.remove(i);
8239                    N--;
8240                    i--;
8241                    continue;
8242                }
8243
8244                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8245                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8246                if (cpr == null) {
8247                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8248                    mProviderMap.putProviderByClass(comp, cpr);
8249                }
8250                if (DEBUG_MU)
8251                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8252                app.pubProviders.put(cpi.name, cpr);
8253                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8254                    // Don't add this if it is a platform component that is marked
8255                    // to run in multiple processes, because this is actually
8256                    // part of the framework so doesn't make sense to track as a
8257                    // separate apk in the process.
8258                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8259                            mProcessStats);
8260                }
8261                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8262            }
8263        }
8264        return providers;
8265    }
8266
8267    /**
8268     * Check if {@link ProcessRecord} has a possible chance at accessing the
8269     * given {@link ProviderInfo}. Final permission checking is always done
8270     * in {@link ContentProvider}.
8271     */
8272    private final String checkContentProviderPermissionLocked(
8273            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8274        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8275        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8276        boolean checkedGrants = false;
8277        if (checkUser) {
8278            // Looking for cross-user grants before enforcing the typical cross-users permissions
8279            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8280            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8281                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8282                    return null;
8283                }
8284                checkedGrants = true;
8285            }
8286            userId = handleIncomingUser(callingPid, callingUid, userId,
8287                    false, ALLOW_NON_FULL,
8288                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8289            if (userId != tmpTargetUserId) {
8290                // When we actually went to determine the final targer user ID, this ended
8291                // up different than our initial check for the authority.  This is because
8292                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8293                // SELF.  So we need to re-check the grants again.
8294                checkedGrants = false;
8295            }
8296        }
8297        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8298                cpi.applicationInfo.uid, cpi.exported)
8299                == PackageManager.PERMISSION_GRANTED) {
8300            return null;
8301        }
8302        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8303                cpi.applicationInfo.uid, cpi.exported)
8304                == PackageManager.PERMISSION_GRANTED) {
8305            return null;
8306        }
8307
8308        PathPermission[] pps = cpi.pathPermissions;
8309        if (pps != null) {
8310            int i = pps.length;
8311            while (i > 0) {
8312                i--;
8313                PathPermission pp = pps[i];
8314                String pprperm = pp.getReadPermission();
8315                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8316                        cpi.applicationInfo.uid, cpi.exported)
8317                        == PackageManager.PERMISSION_GRANTED) {
8318                    return null;
8319                }
8320                String ppwperm = pp.getWritePermission();
8321                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8322                        cpi.applicationInfo.uid, cpi.exported)
8323                        == PackageManager.PERMISSION_GRANTED) {
8324                    return null;
8325                }
8326            }
8327        }
8328        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8329            return null;
8330        }
8331
8332        String msg;
8333        if (!cpi.exported) {
8334            msg = "Permission Denial: opening provider " + cpi.name
8335                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8336                    + ", uid=" + callingUid + ") that is not exported from uid "
8337                    + cpi.applicationInfo.uid;
8338        } else {
8339            msg = "Permission Denial: opening provider " + cpi.name
8340                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8341                    + ", uid=" + callingUid + ") requires "
8342                    + cpi.readPermission + " or " + cpi.writePermission;
8343        }
8344        Slog.w(TAG, msg);
8345        return msg;
8346    }
8347
8348    /**
8349     * Returns if the ContentProvider has granted a uri to callingUid
8350     */
8351    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8352        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8353        if (perms != null) {
8354            for (int i=perms.size()-1; i>=0; i--) {
8355                GrantUri grantUri = perms.keyAt(i);
8356                if (grantUri.sourceUserId == userId || !checkUser) {
8357                    if (matchesProvider(grantUri.uri, cpi)) {
8358                        return true;
8359                    }
8360                }
8361            }
8362        }
8363        return false;
8364    }
8365
8366    /**
8367     * Returns true if the uri authority is one of the authorities specified in the provider.
8368     */
8369    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8370        String uriAuth = uri.getAuthority();
8371        String cpiAuth = cpi.authority;
8372        if (cpiAuth.indexOf(';') == -1) {
8373            return cpiAuth.equals(uriAuth);
8374        }
8375        String[] cpiAuths = cpiAuth.split(";");
8376        int length = cpiAuths.length;
8377        for (int i = 0; i < length; i++) {
8378            if (cpiAuths[i].equals(uriAuth)) return true;
8379        }
8380        return false;
8381    }
8382
8383    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8384            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8385        if (r != null) {
8386            for (int i=0; i<r.conProviders.size(); i++) {
8387                ContentProviderConnection conn = r.conProviders.get(i);
8388                if (conn.provider == cpr) {
8389                    if (DEBUG_PROVIDER) Slog.v(TAG,
8390                            "Adding provider requested by "
8391                            + r.processName + " from process "
8392                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8393                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8394                    if (stable) {
8395                        conn.stableCount++;
8396                        conn.numStableIncs++;
8397                    } else {
8398                        conn.unstableCount++;
8399                        conn.numUnstableIncs++;
8400                    }
8401                    return conn;
8402                }
8403            }
8404            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8405            if (stable) {
8406                conn.stableCount = 1;
8407                conn.numStableIncs = 1;
8408            } else {
8409                conn.unstableCount = 1;
8410                conn.numUnstableIncs = 1;
8411            }
8412            cpr.connections.add(conn);
8413            r.conProviders.add(conn);
8414            return conn;
8415        }
8416        cpr.addExternalProcessHandleLocked(externalProcessToken);
8417        return null;
8418    }
8419
8420    boolean decProviderCountLocked(ContentProviderConnection conn,
8421            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8422        if (conn != null) {
8423            cpr = conn.provider;
8424            if (DEBUG_PROVIDER) Slog.v(TAG,
8425                    "Removing provider requested by "
8426                    + conn.client.processName + " from process "
8427                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8428                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8429            if (stable) {
8430                conn.stableCount--;
8431            } else {
8432                conn.unstableCount--;
8433            }
8434            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8435                cpr.connections.remove(conn);
8436                conn.client.conProviders.remove(conn);
8437                return true;
8438            }
8439            return false;
8440        }
8441        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8442        return false;
8443    }
8444
8445    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8446            String name, IBinder token, boolean stable, int userId) {
8447        ContentProviderRecord cpr;
8448        ContentProviderConnection conn = null;
8449        ProviderInfo cpi = null;
8450
8451        synchronized(this) {
8452            ProcessRecord r = null;
8453            if (caller != null) {
8454                r = getRecordForAppLocked(caller);
8455                if (r == null) {
8456                    throw new SecurityException(
8457                            "Unable to find app for caller " + caller
8458                          + " (pid=" + Binder.getCallingPid()
8459                          + ") when getting content provider " + name);
8460                }
8461            }
8462
8463            boolean checkCrossUser = true;
8464
8465            // First check if this content provider has been published...
8466            cpr = mProviderMap.getProviderByName(name, userId);
8467            // If that didn't work, check if it exists for user 0 and then
8468            // verify that it's a singleton provider before using it.
8469            if (cpr == null && userId != UserHandle.USER_OWNER) {
8470                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8471                if (cpr != null) {
8472                    cpi = cpr.info;
8473                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8474                            cpi.name, cpi.flags)
8475                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8476                        userId = UserHandle.USER_OWNER;
8477                        checkCrossUser = false;
8478                    } else {
8479                        cpr = null;
8480                        cpi = null;
8481                    }
8482                }
8483            }
8484
8485            boolean providerRunning = cpr != null;
8486            if (providerRunning) {
8487                cpi = cpr.info;
8488                String msg;
8489                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8490                        != null) {
8491                    throw new SecurityException(msg);
8492                }
8493
8494                if (r != null && cpr.canRunHere(r)) {
8495                    // This provider has been published or is in the process
8496                    // of being published...  but it is also allowed to run
8497                    // in the caller's process, so don't make a connection
8498                    // and just let the caller instantiate its own instance.
8499                    ContentProviderHolder holder = cpr.newHolder(null);
8500                    // don't give caller the provider object, it needs
8501                    // to make its own.
8502                    holder.provider = null;
8503                    return holder;
8504                }
8505
8506                final long origId = Binder.clearCallingIdentity();
8507
8508                // In this case the provider instance already exists, so we can
8509                // return it right away.
8510                conn = incProviderCountLocked(r, cpr, token, stable);
8511                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8512                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8513                        // If this is a perceptible app accessing the provider,
8514                        // make sure to count it as being accessed and thus
8515                        // back up on the LRU list.  This is good because
8516                        // content providers are often expensive to start.
8517                        updateLruProcessLocked(cpr.proc, false, null);
8518                    }
8519                }
8520
8521                if (cpr.proc != null) {
8522                    if (false) {
8523                        if (cpr.name.flattenToShortString().equals(
8524                                "com.android.providers.calendar/.CalendarProvider2")) {
8525                            Slog.v(TAG, "****************** KILLING "
8526                                + cpr.name.flattenToShortString());
8527                            Process.killProcess(cpr.proc.pid);
8528                        }
8529                    }
8530                    boolean success = updateOomAdjLocked(cpr.proc);
8531                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8532                    // NOTE: there is still a race here where a signal could be
8533                    // pending on the process even though we managed to update its
8534                    // adj level.  Not sure what to do about this, but at least
8535                    // the race is now smaller.
8536                    if (!success) {
8537                        // Uh oh...  it looks like the provider's process
8538                        // has been killed on us.  We need to wait for a new
8539                        // process to be started, and make sure its death
8540                        // doesn't kill our process.
8541                        Slog.i(TAG,
8542                                "Existing provider " + cpr.name.flattenToShortString()
8543                                + " is crashing; detaching " + r);
8544                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8545                        appDiedLocked(cpr.proc);
8546                        if (!lastRef) {
8547                            // This wasn't the last ref our process had on
8548                            // the provider...  we have now been killed, bail.
8549                            return null;
8550                        }
8551                        providerRunning = false;
8552                        conn = null;
8553                    }
8554                }
8555
8556                Binder.restoreCallingIdentity(origId);
8557            }
8558
8559            boolean singleton;
8560            if (!providerRunning) {
8561                try {
8562                    cpi = AppGlobals.getPackageManager().
8563                        resolveContentProvider(name,
8564                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8565                } catch (RemoteException ex) {
8566                }
8567                if (cpi == null) {
8568                    return null;
8569                }
8570                // If the provider is a singleton AND
8571                // (it's a call within the same user || the provider is a
8572                // privileged app)
8573                // Then allow connecting to the singleton provider
8574                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8575                        cpi.name, cpi.flags)
8576                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8577                if (singleton) {
8578                    userId = UserHandle.USER_OWNER;
8579                }
8580                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8581
8582                String msg;
8583                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8584                        != null) {
8585                    throw new SecurityException(msg);
8586                }
8587
8588                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8589                        && !cpi.processName.equals("system")) {
8590                    // If this content provider does not run in the system
8591                    // process, and the system is not yet ready to run other
8592                    // processes, then fail fast instead of hanging.
8593                    throw new IllegalArgumentException(
8594                            "Attempt to launch content provider before system ready");
8595                }
8596
8597                // Make sure that the user who owns this provider is started.  If not,
8598                // we don't want to allow it to run.
8599                if (mStartedUsers.get(userId) == null) {
8600                    Slog.w(TAG, "Unable to launch app "
8601                            + cpi.applicationInfo.packageName + "/"
8602                            + cpi.applicationInfo.uid + " for provider "
8603                            + name + ": user " + userId + " is stopped");
8604                    return null;
8605                }
8606
8607                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8608                cpr = mProviderMap.getProviderByClass(comp, userId);
8609                final boolean firstClass = cpr == null;
8610                if (firstClass) {
8611                    try {
8612                        ApplicationInfo ai =
8613                            AppGlobals.getPackageManager().
8614                                getApplicationInfo(
8615                                        cpi.applicationInfo.packageName,
8616                                        STOCK_PM_FLAGS, userId);
8617                        if (ai == null) {
8618                            Slog.w(TAG, "No package info for content provider "
8619                                    + cpi.name);
8620                            return null;
8621                        }
8622                        ai = getAppInfoForUser(ai, userId);
8623                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8624                    } catch (RemoteException ex) {
8625                        // pm is in same process, this will never happen.
8626                    }
8627                }
8628
8629                if (r != null && cpr.canRunHere(r)) {
8630                    // If this is a multiprocess provider, then just return its
8631                    // info and allow the caller to instantiate it.  Only do
8632                    // this if the provider is the same user as the caller's
8633                    // process, or can run as root (so can be in any process).
8634                    return cpr.newHolder(null);
8635                }
8636
8637                if (DEBUG_PROVIDER) {
8638                    RuntimeException e = new RuntimeException("here");
8639                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8640                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8641                }
8642
8643                // This is single process, and our app is now connecting to it.
8644                // See if we are already in the process of launching this
8645                // provider.
8646                final int N = mLaunchingProviders.size();
8647                int i;
8648                for (i=0; i<N; i++) {
8649                    if (mLaunchingProviders.get(i) == cpr) {
8650                        break;
8651                    }
8652                }
8653
8654                // If the provider is not already being launched, then get it
8655                // started.
8656                if (i >= N) {
8657                    final long origId = Binder.clearCallingIdentity();
8658
8659                    try {
8660                        // Content provider is now in use, its package can't be stopped.
8661                        try {
8662                            AppGlobals.getPackageManager().setPackageStoppedState(
8663                                    cpr.appInfo.packageName, false, userId);
8664                        } catch (RemoteException e) {
8665                        } catch (IllegalArgumentException e) {
8666                            Slog.w(TAG, "Failed trying to unstop package "
8667                                    + cpr.appInfo.packageName + ": " + e);
8668                        }
8669
8670                        // Use existing process if already started
8671                        ProcessRecord proc = getProcessRecordLocked(
8672                                cpi.processName, cpr.appInfo.uid, false);
8673                        if (proc != null && proc.thread != null) {
8674                            if (DEBUG_PROVIDER) {
8675                                Slog.d(TAG, "Installing in existing process " + proc);
8676                            }
8677                            proc.pubProviders.put(cpi.name, cpr);
8678                            try {
8679                                proc.thread.scheduleInstallProvider(cpi);
8680                            } catch (RemoteException e) {
8681                            }
8682                        } else {
8683                            proc = startProcessLocked(cpi.processName,
8684                                    cpr.appInfo, false, 0, "content provider",
8685                                    new ComponentName(cpi.applicationInfo.packageName,
8686                                            cpi.name), false, false, false);
8687                            if (proc == null) {
8688                                Slog.w(TAG, "Unable to launch app "
8689                                        + cpi.applicationInfo.packageName + "/"
8690                                        + cpi.applicationInfo.uid + " for provider "
8691                                        + name + ": process is bad");
8692                                return null;
8693                            }
8694                        }
8695                        cpr.launchingApp = proc;
8696                        mLaunchingProviders.add(cpr);
8697                    } finally {
8698                        Binder.restoreCallingIdentity(origId);
8699                    }
8700                }
8701
8702                // Make sure the provider is published (the same provider class
8703                // may be published under multiple names).
8704                if (firstClass) {
8705                    mProviderMap.putProviderByClass(comp, cpr);
8706                }
8707
8708                mProviderMap.putProviderByName(name, cpr);
8709                conn = incProviderCountLocked(r, cpr, token, stable);
8710                if (conn != null) {
8711                    conn.waiting = true;
8712                }
8713            }
8714        }
8715
8716        // Wait for the provider to be published...
8717        synchronized (cpr) {
8718            while (cpr.provider == null) {
8719                if (cpr.launchingApp == null) {
8720                    Slog.w(TAG, "Unable to launch app "
8721                            + cpi.applicationInfo.packageName + "/"
8722                            + cpi.applicationInfo.uid + " for provider "
8723                            + name + ": launching app became null");
8724                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8725                            UserHandle.getUserId(cpi.applicationInfo.uid),
8726                            cpi.applicationInfo.packageName,
8727                            cpi.applicationInfo.uid, name);
8728                    return null;
8729                }
8730                try {
8731                    if (DEBUG_MU) {
8732                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8733                                + cpr.launchingApp);
8734                    }
8735                    if (conn != null) {
8736                        conn.waiting = true;
8737                    }
8738                    cpr.wait();
8739                } catch (InterruptedException ex) {
8740                } finally {
8741                    if (conn != null) {
8742                        conn.waiting = false;
8743                    }
8744                }
8745            }
8746        }
8747        return cpr != null ? cpr.newHolder(conn) : null;
8748    }
8749
8750    @Override
8751    public final ContentProviderHolder getContentProvider(
8752            IApplicationThread caller, String name, int userId, boolean stable) {
8753        enforceNotIsolatedCaller("getContentProvider");
8754        if (caller == null) {
8755            String msg = "null IApplicationThread when getting content provider "
8756                    + name;
8757            Slog.w(TAG, msg);
8758            throw new SecurityException(msg);
8759        }
8760        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8761        // with cross-user grant.
8762        return getContentProviderImpl(caller, name, null, stable, userId);
8763    }
8764
8765    public ContentProviderHolder getContentProviderExternal(
8766            String name, int userId, IBinder token) {
8767        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8768            "Do not have permission in call getContentProviderExternal()");
8769        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8770                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8771        return getContentProviderExternalUnchecked(name, token, userId);
8772    }
8773
8774    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8775            IBinder token, int userId) {
8776        return getContentProviderImpl(null, name, token, true, userId);
8777    }
8778
8779    /**
8780     * Drop a content provider from a ProcessRecord's bookkeeping
8781     */
8782    public void removeContentProvider(IBinder connection, boolean stable) {
8783        enforceNotIsolatedCaller("removeContentProvider");
8784        long ident = Binder.clearCallingIdentity();
8785        try {
8786            synchronized (this) {
8787                ContentProviderConnection conn;
8788                try {
8789                    conn = (ContentProviderConnection)connection;
8790                } catch (ClassCastException e) {
8791                    String msg ="removeContentProvider: " + connection
8792                            + " not a ContentProviderConnection";
8793                    Slog.w(TAG, msg);
8794                    throw new IllegalArgumentException(msg);
8795                }
8796                if (conn == null) {
8797                    throw new NullPointerException("connection is null");
8798                }
8799                if (decProviderCountLocked(conn, null, null, stable)) {
8800                    updateOomAdjLocked();
8801                }
8802            }
8803        } finally {
8804            Binder.restoreCallingIdentity(ident);
8805        }
8806    }
8807
8808    public void removeContentProviderExternal(String name, IBinder token) {
8809        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8810            "Do not have permission in call removeContentProviderExternal()");
8811        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8812    }
8813
8814    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8815        synchronized (this) {
8816            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8817            if(cpr == null) {
8818                //remove from mProvidersByClass
8819                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8820                return;
8821            }
8822
8823            //update content provider record entry info
8824            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8825            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8826            if (localCpr.hasExternalProcessHandles()) {
8827                if (localCpr.removeExternalProcessHandleLocked(token)) {
8828                    updateOomAdjLocked();
8829                } else {
8830                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8831                            + " with no external reference for token: "
8832                            + token + ".");
8833                }
8834            } else {
8835                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8836                        + " with no external references.");
8837            }
8838        }
8839    }
8840
8841    public final void publishContentProviders(IApplicationThread caller,
8842            List<ContentProviderHolder> providers) {
8843        if (providers == null) {
8844            return;
8845        }
8846
8847        enforceNotIsolatedCaller("publishContentProviders");
8848        synchronized (this) {
8849            final ProcessRecord r = getRecordForAppLocked(caller);
8850            if (DEBUG_MU)
8851                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8852            if (r == null) {
8853                throw new SecurityException(
8854                        "Unable to find app for caller " + caller
8855                      + " (pid=" + Binder.getCallingPid()
8856                      + ") when publishing content providers");
8857            }
8858
8859            final long origId = Binder.clearCallingIdentity();
8860
8861            final int N = providers.size();
8862            for (int i=0; i<N; i++) {
8863                ContentProviderHolder src = providers.get(i);
8864                if (src == null || src.info == null || src.provider == null) {
8865                    continue;
8866                }
8867                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8868                if (DEBUG_MU)
8869                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8870                if (dst != null) {
8871                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8872                    mProviderMap.putProviderByClass(comp, dst);
8873                    String names[] = dst.info.authority.split(";");
8874                    for (int j = 0; j < names.length; j++) {
8875                        mProviderMap.putProviderByName(names[j], dst);
8876                    }
8877
8878                    int NL = mLaunchingProviders.size();
8879                    int j;
8880                    for (j=0; j<NL; j++) {
8881                        if (mLaunchingProviders.get(j) == dst) {
8882                            mLaunchingProviders.remove(j);
8883                            j--;
8884                            NL--;
8885                        }
8886                    }
8887                    synchronized (dst) {
8888                        dst.provider = src.provider;
8889                        dst.proc = r;
8890                        dst.notifyAll();
8891                    }
8892                    updateOomAdjLocked(r);
8893                }
8894            }
8895
8896            Binder.restoreCallingIdentity(origId);
8897        }
8898    }
8899
8900    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8901        ContentProviderConnection conn;
8902        try {
8903            conn = (ContentProviderConnection)connection;
8904        } catch (ClassCastException e) {
8905            String msg ="refContentProvider: " + connection
8906                    + " not a ContentProviderConnection";
8907            Slog.w(TAG, msg);
8908            throw new IllegalArgumentException(msg);
8909        }
8910        if (conn == null) {
8911            throw new NullPointerException("connection is null");
8912        }
8913
8914        synchronized (this) {
8915            if (stable > 0) {
8916                conn.numStableIncs += stable;
8917            }
8918            stable = conn.stableCount + stable;
8919            if (stable < 0) {
8920                throw new IllegalStateException("stableCount < 0: " + stable);
8921            }
8922
8923            if (unstable > 0) {
8924                conn.numUnstableIncs += unstable;
8925            }
8926            unstable = conn.unstableCount + unstable;
8927            if (unstable < 0) {
8928                throw new IllegalStateException("unstableCount < 0: " + unstable);
8929            }
8930
8931            if ((stable+unstable) <= 0) {
8932                throw new IllegalStateException("ref counts can't go to zero here: stable="
8933                        + stable + " unstable=" + unstable);
8934            }
8935            conn.stableCount = stable;
8936            conn.unstableCount = unstable;
8937            return !conn.dead;
8938        }
8939    }
8940
8941    public void unstableProviderDied(IBinder connection) {
8942        ContentProviderConnection conn;
8943        try {
8944            conn = (ContentProviderConnection)connection;
8945        } catch (ClassCastException e) {
8946            String msg ="refContentProvider: " + connection
8947                    + " not a ContentProviderConnection";
8948            Slog.w(TAG, msg);
8949            throw new IllegalArgumentException(msg);
8950        }
8951        if (conn == null) {
8952            throw new NullPointerException("connection is null");
8953        }
8954
8955        // Safely retrieve the content provider associated with the connection.
8956        IContentProvider provider;
8957        synchronized (this) {
8958            provider = conn.provider.provider;
8959        }
8960
8961        if (provider == null) {
8962            // Um, yeah, we're way ahead of you.
8963            return;
8964        }
8965
8966        // Make sure the caller is being honest with us.
8967        if (provider.asBinder().pingBinder()) {
8968            // Er, no, still looks good to us.
8969            synchronized (this) {
8970                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8971                        + " says " + conn + " died, but we don't agree");
8972                return;
8973            }
8974        }
8975
8976        // Well look at that!  It's dead!
8977        synchronized (this) {
8978            if (conn.provider.provider != provider) {
8979                // But something changed...  good enough.
8980                return;
8981            }
8982
8983            ProcessRecord proc = conn.provider.proc;
8984            if (proc == null || proc.thread == null) {
8985                // Seems like the process is already cleaned up.
8986                return;
8987            }
8988
8989            // As far as we're concerned, this is just like receiving a
8990            // death notification...  just a bit prematurely.
8991            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8992                    + ") early provider death");
8993            final long ident = Binder.clearCallingIdentity();
8994            try {
8995                appDiedLocked(proc);
8996            } finally {
8997                Binder.restoreCallingIdentity(ident);
8998            }
8999        }
9000    }
9001
9002    @Override
9003    public void appNotRespondingViaProvider(IBinder connection) {
9004        enforceCallingPermission(
9005                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9006
9007        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9008        if (conn == null) {
9009            Slog.w(TAG, "ContentProviderConnection is null");
9010            return;
9011        }
9012
9013        final ProcessRecord host = conn.provider.proc;
9014        if (host == null) {
9015            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9016            return;
9017        }
9018
9019        final long token = Binder.clearCallingIdentity();
9020        try {
9021            appNotResponding(host, null, null, false, "ContentProvider not responding");
9022        } finally {
9023            Binder.restoreCallingIdentity(token);
9024        }
9025    }
9026
9027    public final void installSystemProviders() {
9028        List<ProviderInfo> providers;
9029        synchronized (this) {
9030            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9031            providers = generateApplicationProvidersLocked(app);
9032            if (providers != null) {
9033                for (int i=providers.size()-1; i>=0; i--) {
9034                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9035                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9036                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9037                                + ": not system .apk");
9038                        providers.remove(i);
9039                    }
9040                }
9041            }
9042        }
9043        if (providers != null) {
9044            mSystemThread.installSystemProviders(providers);
9045        }
9046
9047        mCoreSettingsObserver = new CoreSettingsObserver(this);
9048
9049        //mUsageStatsService.monitorPackages();
9050    }
9051
9052    /**
9053     * Allows apps to retrieve the MIME type of a URI.
9054     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9055     * users, then it does not need permission to access the ContentProvider.
9056     * Either, it needs cross-user uri grants.
9057     *
9058     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9059     *
9060     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9061     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9062     */
9063    public String getProviderMimeType(Uri uri, int userId) {
9064        enforceNotIsolatedCaller("getProviderMimeType");
9065        final String name = uri.getAuthority();
9066        int callingUid = Binder.getCallingUid();
9067        int callingPid = Binder.getCallingPid();
9068        long ident = 0;
9069        boolean clearedIdentity = false;
9070        userId = unsafeConvertIncomingUser(userId);
9071        if (UserHandle.getUserId(callingUid) != userId) {
9072            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9073                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9074                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9075                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9076                clearedIdentity = true;
9077                ident = Binder.clearCallingIdentity();
9078            }
9079        }
9080        ContentProviderHolder holder = null;
9081        try {
9082            holder = getContentProviderExternalUnchecked(name, null, userId);
9083            if (holder != null) {
9084                return holder.provider.getType(uri);
9085            }
9086        } catch (RemoteException e) {
9087            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9088            return null;
9089        } finally {
9090            // We need to clear the identity to call removeContentProviderExternalUnchecked
9091            if (!clearedIdentity) {
9092                ident = Binder.clearCallingIdentity();
9093            }
9094            try {
9095                if (holder != null) {
9096                    removeContentProviderExternalUnchecked(name, null, userId);
9097                }
9098            } finally {
9099                Binder.restoreCallingIdentity(ident);
9100            }
9101        }
9102
9103        return null;
9104    }
9105
9106    // =========================================================
9107    // GLOBAL MANAGEMENT
9108    // =========================================================
9109
9110    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9111            boolean isolated, int isolatedUid) {
9112        String proc = customProcess != null ? customProcess : info.processName;
9113        BatteryStatsImpl.Uid.Proc ps = null;
9114        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9115        int uid = info.uid;
9116        if (isolated) {
9117            if (isolatedUid == 0) {
9118                int userId = UserHandle.getUserId(uid);
9119                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9120                while (true) {
9121                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9122                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9123                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9124                    }
9125                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9126                    mNextIsolatedProcessUid++;
9127                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9128                        // No process for this uid, use it.
9129                        break;
9130                    }
9131                    stepsLeft--;
9132                    if (stepsLeft <= 0) {
9133                        return null;
9134                    }
9135                }
9136            } else {
9137                // Special case for startIsolatedProcess (internal only), where
9138                // the uid of the isolated process is specified by the caller.
9139                uid = isolatedUid;
9140            }
9141        }
9142        return new ProcessRecord(stats, info, proc, uid);
9143    }
9144
9145    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9146            String abiOverride) {
9147        ProcessRecord app;
9148        if (!isolated) {
9149            app = getProcessRecordLocked(info.processName, info.uid, true);
9150        } else {
9151            app = null;
9152        }
9153
9154        if (app == null) {
9155            app = newProcessRecordLocked(info, null, isolated, 0);
9156            mProcessNames.put(info.processName, app.uid, app);
9157            if (isolated) {
9158                mIsolatedProcesses.put(app.uid, app);
9159            }
9160            updateLruProcessLocked(app, false, null);
9161            updateOomAdjLocked();
9162        }
9163
9164        // This package really, really can not be stopped.
9165        try {
9166            AppGlobals.getPackageManager().setPackageStoppedState(
9167                    info.packageName, false, UserHandle.getUserId(app.uid));
9168        } catch (RemoteException e) {
9169        } catch (IllegalArgumentException e) {
9170            Slog.w(TAG, "Failed trying to unstop package "
9171                    + info.packageName + ": " + e);
9172        }
9173
9174        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9175                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9176            app.persistent = true;
9177            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9178        }
9179        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9180            mPersistentStartingProcesses.add(app);
9181            startProcessLocked(app, "added application", app.processName, abiOverride,
9182                    null /* entryPoint */, null /* entryPointArgs */);
9183        }
9184
9185        return app;
9186    }
9187
9188    public void unhandledBack() {
9189        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9190                "unhandledBack()");
9191
9192        synchronized(this) {
9193            final long origId = Binder.clearCallingIdentity();
9194            try {
9195                getFocusedStack().unhandledBackLocked();
9196            } finally {
9197                Binder.restoreCallingIdentity(origId);
9198            }
9199        }
9200    }
9201
9202    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9203        enforceNotIsolatedCaller("openContentUri");
9204        final int userId = UserHandle.getCallingUserId();
9205        String name = uri.getAuthority();
9206        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9207        ParcelFileDescriptor pfd = null;
9208        if (cph != null) {
9209            // We record the binder invoker's uid in thread-local storage before
9210            // going to the content provider to open the file.  Later, in the code
9211            // that handles all permissions checks, we look for this uid and use
9212            // that rather than the Activity Manager's own uid.  The effect is that
9213            // we do the check against the caller's permissions even though it looks
9214            // to the content provider like the Activity Manager itself is making
9215            // the request.
9216            sCallerIdentity.set(new Identity(
9217                    Binder.getCallingPid(), Binder.getCallingUid()));
9218            try {
9219                pfd = cph.provider.openFile(null, uri, "r", null);
9220            } catch (FileNotFoundException e) {
9221                // do nothing; pfd will be returned null
9222            } finally {
9223                // Ensure that whatever happens, we clean up the identity state
9224                sCallerIdentity.remove();
9225            }
9226
9227            // We've got the fd now, so we're done with the provider.
9228            removeContentProviderExternalUnchecked(name, null, userId);
9229        } else {
9230            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9231        }
9232        return pfd;
9233    }
9234
9235    // Actually is sleeping or shutting down or whatever else in the future
9236    // is an inactive state.
9237    public boolean isSleepingOrShuttingDown() {
9238        return mSleeping || mShuttingDown;
9239    }
9240
9241    public boolean isSleeping() {
9242        return mSleeping;
9243    }
9244
9245    void goingToSleep() {
9246        synchronized(this) {
9247            mWentToSleep = true;
9248            updateEventDispatchingLocked();
9249            goToSleepIfNeededLocked();
9250        }
9251    }
9252
9253    void finishRunningVoiceLocked() {
9254        if (mRunningVoice) {
9255            mRunningVoice = false;
9256            goToSleepIfNeededLocked();
9257        }
9258    }
9259
9260    void goToSleepIfNeededLocked() {
9261        if (mWentToSleep && !mRunningVoice) {
9262            if (!mSleeping) {
9263                mSleeping = true;
9264                mStackSupervisor.goingToSleepLocked();
9265
9266                // Initialize the wake times of all processes.
9267                checkExcessivePowerUsageLocked(false);
9268                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9269                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9270                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9271            }
9272        }
9273    }
9274
9275    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9276        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9277            // Never persist the home stack.
9278            return;
9279        }
9280        mTaskPersister.wakeup(task, flush);
9281    }
9282
9283    @Override
9284    public boolean shutdown(int timeout) {
9285        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9286                != PackageManager.PERMISSION_GRANTED) {
9287            throw new SecurityException("Requires permission "
9288                    + android.Manifest.permission.SHUTDOWN);
9289        }
9290
9291        boolean timedout = false;
9292
9293        synchronized(this) {
9294            mShuttingDown = true;
9295            updateEventDispatchingLocked();
9296            timedout = mStackSupervisor.shutdownLocked(timeout);
9297        }
9298
9299        mAppOpsService.shutdown();
9300        if (mUsageStatsService != null) {
9301            mUsageStatsService.prepareShutdown();
9302        }
9303        mBatteryStatsService.shutdown();
9304        synchronized (this) {
9305            mProcessStats.shutdownLocked();
9306        }
9307        notifyTaskPersisterLocked(null, true);
9308
9309        return timedout;
9310    }
9311
9312    public final void activitySlept(IBinder token) {
9313        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9314
9315        final long origId = Binder.clearCallingIdentity();
9316
9317        synchronized (this) {
9318            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9319            if (r != null) {
9320                mStackSupervisor.activitySleptLocked(r);
9321            }
9322        }
9323
9324        Binder.restoreCallingIdentity(origId);
9325    }
9326
9327    void logLockScreen(String msg) {
9328        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9329                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9330                mWentToSleep + " mSleeping=" + mSleeping);
9331    }
9332
9333    private void comeOutOfSleepIfNeededLocked() {
9334        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9335            if (mSleeping) {
9336                mSleeping = false;
9337                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9338            }
9339        }
9340    }
9341
9342    void wakingUp() {
9343        synchronized(this) {
9344            mWentToSleep = false;
9345            updateEventDispatchingLocked();
9346            comeOutOfSleepIfNeededLocked();
9347        }
9348    }
9349
9350    void startRunningVoiceLocked() {
9351        if (!mRunningVoice) {
9352            mRunningVoice = true;
9353            comeOutOfSleepIfNeededLocked();
9354        }
9355    }
9356
9357    private void updateEventDispatchingLocked() {
9358        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9359    }
9360
9361    public void setLockScreenShown(boolean shown) {
9362        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9363                != PackageManager.PERMISSION_GRANTED) {
9364            throw new SecurityException("Requires permission "
9365                    + android.Manifest.permission.DEVICE_POWER);
9366        }
9367
9368        synchronized(this) {
9369            long ident = Binder.clearCallingIdentity();
9370            try {
9371                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9372                mLockScreenShown = shown;
9373                comeOutOfSleepIfNeededLocked();
9374            } finally {
9375                Binder.restoreCallingIdentity(ident);
9376            }
9377        }
9378    }
9379
9380    @Override
9381    public void stopAppSwitches() {
9382        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9383                != PackageManager.PERMISSION_GRANTED) {
9384            throw new SecurityException("Requires permission "
9385                    + android.Manifest.permission.STOP_APP_SWITCHES);
9386        }
9387
9388        synchronized(this) {
9389            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9390                    + APP_SWITCH_DELAY_TIME;
9391            mDidAppSwitch = false;
9392            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9393            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9394            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9395        }
9396    }
9397
9398    public void resumeAppSwitches() {
9399        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9400                != PackageManager.PERMISSION_GRANTED) {
9401            throw new SecurityException("Requires permission "
9402                    + android.Manifest.permission.STOP_APP_SWITCHES);
9403        }
9404
9405        synchronized(this) {
9406            // Note that we don't execute any pending app switches... we will
9407            // let those wait until either the timeout, or the next start
9408            // activity request.
9409            mAppSwitchesAllowedTime = 0;
9410        }
9411    }
9412
9413    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9414            String name) {
9415        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9416            return true;
9417        }
9418
9419        final int perm = checkComponentPermission(
9420                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9421                callingUid, -1, true);
9422        if (perm == PackageManager.PERMISSION_GRANTED) {
9423            return true;
9424        }
9425
9426        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9427        return false;
9428    }
9429
9430    public void setDebugApp(String packageName, boolean waitForDebugger,
9431            boolean persistent) {
9432        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9433                "setDebugApp()");
9434
9435        long ident = Binder.clearCallingIdentity();
9436        try {
9437            // Note that this is not really thread safe if there are multiple
9438            // callers into it at the same time, but that's not a situation we
9439            // care about.
9440            if (persistent) {
9441                final ContentResolver resolver = mContext.getContentResolver();
9442                Settings.Global.putString(
9443                    resolver, Settings.Global.DEBUG_APP,
9444                    packageName);
9445                Settings.Global.putInt(
9446                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9447                    waitForDebugger ? 1 : 0);
9448            }
9449
9450            synchronized (this) {
9451                if (!persistent) {
9452                    mOrigDebugApp = mDebugApp;
9453                    mOrigWaitForDebugger = mWaitForDebugger;
9454                }
9455                mDebugApp = packageName;
9456                mWaitForDebugger = waitForDebugger;
9457                mDebugTransient = !persistent;
9458                if (packageName != null) {
9459                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9460                            false, UserHandle.USER_ALL, "set debug app");
9461                }
9462            }
9463        } finally {
9464            Binder.restoreCallingIdentity(ident);
9465        }
9466    }
9467
9468    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9469        synchronized (this) {
9470            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9471            if (!isDebuggable) {
9472                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9473                    throw new SecurityException("Process not debuggable: " + app.packageName);
9474                }
9475            }
9476
9477            mOpenGlTraceApp = processName;
9478        }
9479    }
9480
9481    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9482            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9483        synchronized (this) {
9484            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9485            if (!isDebuggable) {
9486                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9487                    throw new SecurityException("Process not debuggable: " + app.packageName);
9488                }
9489            }
9490            mProfileApp = processName;
9491            mProfileFile = profileFile;
9492            if (mProfileFd != null) {
9493                try {
9494                    mProfileFd.close();
9495                } catch (IOException e) {
9496                }
9497                mProfileFd = null;
9498            }
9499            mProfileFd = profileFd;
9500            mProfileType = 0;
9501            mAutoStopProfiler = autoStopProfiler;
9502        }
9503    }
9504
9505    @Override
9506    public void setAlwaysFinish(boolean enabled) {
9507        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9508                "setAlwaysFinish()");
9509
9510        Settings.Global.putInt(
9511                mContext.getContentResolver(),
9512                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9513
9514        synchronized (this) {
9515            mAlwaysFinishActivities = enabled;
9516        }
9517    }
9518
9519    @Override
9520    public void setActivityController(IActivityController controller) {
9521        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9522                "setActivityController()");
9523        synchronized (this) {
9524            mController = controller;
9525            Watchdog.getInstance().setActivityController(controller);
9526        }
9527    }
9528
9529    @Override
9530    public void setUserIsMonkey(boolean userIsMonkey) {
9531        synchronized (this) {
9532            synchronized (mPidsSelfLocked) {
9533                final int callingPid = Binder.getCallingPid();
9534                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9535                if (precessRecord == null) {
9536                    throw new SecurityException("Unknown process: " + callingPid);
9537                }
9538                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9539                    throw new SecurityException("Only an instrumentation process "
9540                            + "with a UiAutomation can call setUserIsMonkey");
9541                }
9542            }
9543            mUserIsMonkey = userIsMonkey;
9544        }
9545    }
9546
9547    @Override
9548    public boolean isUserAMonkey() {
9549        synchronized (this) {
9550            // If there is a controller also implies the user is a monkey.
9551            return (mUserIsMonkey || mController != null);
9552        }
9553    }
9554
9555    public void requestBugReport() {
9556        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9557        SystemProperties.set("ctl.start", "bugreport");
9558    }
9559
9560    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9561        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9562    }
9563
9564    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9565        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9566            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9567        }
9568        return KEY_DISPATCHING_TIMEOUT;
9569    }
9570
9571    @Override
9572    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9573        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9574                != PackageManager.PERMISSION_GRANTED) {
9575            throw new SecurityException("Requires permission "
9576                    + android.Manifest.permission.FILTER_EVENTS);
9577        }
9578        ProcessRecord proc;
9579        long timeout;
9580        synchronized (this) {
9581            synchronized (mPidsSelfLocked) {
9582                proc = mPidsSelfLocked.get(pid);
9583            }
9584            timeout = getInputDispatchingTimeoutLocked(proc);
9585        }
9586
9587        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9588            return -1;
9589        }
9590
9591        return timeout;
9592    }
9593
9594    /**
9595     * Handle input dispatching timeouts.
9596     * Returns whether input dispatching should be aborted or not.
9597     */
9598    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9599            final ActivityRecord activity, final ActivityRecord parent,
9600            final boolean aboveSystem, String reason) {
9601        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9602                != PackageManager.PERMISSION_GRANTED) {
9603            throw new SecurityException("Requires permission "
9604                    + android.Manifest.permission.FILTER_EVENTS);
9605        }
9606
9607        final String annotation;
9608        if (reason == null) {
9609            annotation = "Input dispatching timed out";
9610        } else {
9611            annotation = "Input dispatching timed out (" + reason + ")";
9612        }
9613
9614        if (proc != null) {
9615            synchronized (this) {
9616                if (proc.debugging) {
9617                    return false;
9618                }
9619
9620                if (mDidDexOpt) {
9621                    // Give more time since we were dexopting.
9622                    mDidDexOpt = false;
9623                    return false;
9624                }
9625
9626                if (proc.instrumentationClass != null) {
9627                    Bundle info = new Bundle();
9628                    info.putString("shortMsg", "keyDispatchingTimedOut");
9629                    info.putString("longMsg", annotation);
9630                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9631                    return true;
9632                }
9633            }
9634            mHandler.post(new Runnable() {
9635                @Override
9636                public void run() {
9637                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9638                }
9639            });
9640        }
9641
9642        return true;
9643    }
9644
9645    public Bundle getAssistContextExtras(int requestType) {
9646        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9647                "getAssistContextExtras()");
9648        PendingAssistExtras pae;
9649        Bundle extras = new Bundle();
9650        synchronized (this) {
9651            ActivityRecord activity = getFocusedStack().mResumedActivity;
9652            if (activity == null) {
9653                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9654                return null;
9655            }
9656            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9657            if (activity.app == null || activity.app.thread == null) {
9658                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9659                return extras;
9660            }
9661            if (activity.app.pid == Binder.getCallingPid()) {
9662                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9663                return extras;
9664            }
9665            pae = new PendingAssistExtras(activity);
9666            try {
9667                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9668                        requestType);
9669                mPendingAssistExtras.add(pae);
9670                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9671            } catch (RemoteException e) {
9672                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9673                return extras;
9674            }
9675        }
9676        synchronized (pae) {
9677            while (!pae.haveResult) {
9678                try {
9679                    pae.wait();
9680                } catch (InterruptedException e) {
9681                }
9682            }
9683            if (pae.result != null) {
9684                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9685            }
9686        }
9687        synchronized (this) {
9688            mPendingAssistExtras.remove(pae);
9689            mHandler.removeCallbacks(pae);
9690        }
9691        return extras;
9692    }
9693
9694    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9695        PendingAssistExtras pae = (PendingAssistExtras)token;
9696        synchronized (pae) {
9697            pae.result = extras;
9698            pae.haveResult = true;
9699            pae.notifyAll();
9700        }
9701    }
9702
9703    public void registerProcessObserver(IProcessObserver observer) {
9704        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9705                "registerProcessObserver()");
9706        synchronized (this) {
9707            mProcessObservers.register(observer);
9708        }
9709    }
9710
9711    @Override
9712    public void unregisterProcessObserver(IProcessObserver observer) {
9713        synchronized (this) {
9714            mProcessObservers.unregister(observer);
9715        }
9716    }
9717
9718    @Override
9719    public boolean convertFromTranslucent(IBinder token) {
9720        final long origId = Binder.clearCallingIdentity();
9721        try {
9722            synchronized (this) {
9723                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9724                if (r == null) {
9725                    return false;
9726                }
9727                if (r.changeWindowTranslucency(true)) {
9728                    mWindowManager.setAppFullscreen(token, true);
9729                    r.task.stack.releaseBackgroundResources();
9730                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9731                    return true;
9732                }
9733                return false;
9734            }
9735        } finally {
9736            Binder.restoreCallingIdentity(origId);
9737        }
9738    }
9739
9740    @Override
9741    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9742        final long origId = Binder.clearCallingIdentity();
9743        try {
9744            synchronized (this) {
9745                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9746                if (r == null) {
9747                    return false;
9748                }
9749                int index = r.task.mActivities.lastIndexOf(r);
9750                if (index > 0) {
9751                    ActivityRecord under = r.task.mActivities.get(index - 1);
9752                    under.returningOptions = options;
9753                }
9754                if (r.changeWindowTranslucency(false)) {
9755                    r.task.stack.convertToTranslucent(r);
9756                    mWindowManager.setAppFullscreen(token, false);
9757                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9758                    return true;
9759                } else {
9760                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9761                    return false;
9762                }
9763            }
9764        } finally {
9765            Binder.restoreCallingIdentity(origId);
9766        }
9767    }
9768
9769    @Override
9770    public boolean requestVisibleBehind(IBinder token, boolean visible) {
9771        final long origId = Binder.clearCallingIdentity();
9772        try {
9773            synchronized (this) {
9774                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9775                if (r != null) {
9776                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
9777                }
9778            }
9779            return false;
9780        } finally {
9781            Binder.restoreCallingIdentity(origId);
9782        }
9783    }
9784
9785    @Override
9786    public boolean isBackgroundVisibleBehind(IBinder token) {
9787        final long origId = Binder.clearCallingIdentity();
9788        try {
9789            synchronized (this) {
9790                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9791                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
9792                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
9793                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
9794                return visible;
9795            }
9796        } finally {
9797            Binder.restoreCallingIdentity(origId);
9798        }
9799    }
9800
9801    @Override
9802    public ActivityOptions getActivityOptions(IBinder token) {
9803        final long origId = Binder.clearCallingIdentity();
9804        try {
9805            synchronized (this) {
9806                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9807                if (r != null) {
9808                    final ActivityOptions activityOptions = r.pendingOptions;
9809                    r.pendingOptions = null;
9810                    return activityOptions;
9811                }
9812                return null;
9813            }
9814        } finally {
9815            Binder.restoreCallingIdentity(origId);
9816        }
9817    }
9818
9819    @Override
9820    public void setImmersive(IBinder token, boolean immersive) {
9821        synchronized(this) {
9822            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9823            if (r == null) {
9824                throw new IllegalArgumentException();
9825            }
9826            r.immersive = immersive;
9827
9828            // update associated state if we're frontmost
9829            if (r == mFocusedActivity) {
9830                if (DEBUG_IMMERSIVE) {
9831                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9832                }
9833                applyUpdateLockStateLocked(r);
9834            }
9835        }
9836    }
9837
9838    @Override
9839    public boolean isImmersive(IBinder token) {
9840        synchronized (this) {
9841            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9842            if (r == null) {
9843                throw new IllegalArgumentException();
9844            }
9845            return r.immersive;
9846        }
9847    }
9848
9849    public boolean isTopActivityImmersive() {
9850        enforceNotIsolatedCaller("startActivity");
9851        synchronized (this) {
9852            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9853            return (r != null) ? r.immersive : false;
9854        }
9855    }
9856
9857    @Override
9858    public boolean isTopOfTask(IBinder token) {
9859        synchronized (this) {
9860            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9861            if (r == null) {
9862                throw new IllegalArgumentException();
9863            }
9864            return r.task.getTopActivity() == r;
9865        }
9866    }
9867
9868    public final void enterSafeMode() {
9869        synchronized(this) {
9870            // It only makes sense to do this before the system is ready
9871            // and started launching other packages.
9872            if (!mSystemReady) {
9873                try {
9874                    AppGlobals.getPackageManager().enterSafeMode();
9875                } catch (RemoteException e) {
9876                }
9877            }
9878
9879            mSafeMode = true;
9880        }
9881    }
9882
9883    public final void showSafeModeOverlay() {
9884        View v = LayoutInflater.from(mContext).inflate(
9885                com.android.internal.R.layout.safe_mode, null);
9886        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9887        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9888        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9889        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9890        lp.gravity = Gravity.BOTTOM | Gravity.START;
9891        lp.format = v.getBackground().getOpacity();
9892        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9893                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9894        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9895        ((WindowManager)mContext.getSystemService(
9896                Context.WINDOW_SERVICE)).addView(v, lp);
9897    }
9898
9899    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9900        if (!(sender instanceof PendingIntentRecord)) {
9901            return;
9902        }
9903        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9904        synchronized (stats) {
9905            if (mBatteryStatsService.isOnBattery()) {
9906                mBatteryStatsService.enforceCallingPermission();
9907                PendingIntentRecord rec = (PendingIntentRecord)sender;
9908                int MY_UID = Binder.getCallingUid();
9909                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9910                BatteryStatsImpl.Uid.Pkg pkg =
9911                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9912                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9913                pkg.incWakeupsLocked();
9914            }
9915        }
9916    }
9917
9918    public boolean killPids(int[] pids, String pReason, boolean secure) {
9919        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9920            throw new SecurityException("killPids only available to the system");
9921        }
9922        String reason = (pReason == null) ? "Unknown" : pReason;
9923        // XXX Note: don't acquire main activity lock here, because the window
9924        // manager calls in with its locks held.
9925
9926        boolean killed = false;
9927        synchronized (mPidsSelfLocked) {
9928            int[] types = new int[pids.length];
9929            int worstType = 0;
9930            for (int i=0; i<pids.length; i++) {
9931                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9932                if (proc != null) {
9933                    int type = proc.setAdj;
9934                    types[i] = type;
9935                    if (type > worstType) {
9936                        worstType = type;
9937                    }
9938                }
9939            }
9940
9941            // If the worst oom_adj is somewhere in the cached proc LRU range,
9942            // then constrain it so we will kill all cached procs.
9943            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9944                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9945                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9946            }
9947
9948            // If this is not a secure call, don't let it kill processes that
9949            // are important.
9950            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9951                worstType = ProcessList.SERVICE_ADJ;
9952            }
9953
9954            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9955            for (int i=0; i<pids.length; i++) {
9956                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9957                if (proc == null) {
9958                    continue;
9959                }
9960                int adj = proc.setAdj;
9961                if (adj >= worstType && !proc.killedByAm) {
9962                    killUnneededProcessLocked(proc, reason);
9963                    killed = true;
9964                }
9965            }
9966        }
9967        return killed;
9968    }
9969
9970    @Override
9971    public void killUid(int uid, String reason) {
9972        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9973            throw new SecurityException("killUid only available to the system");
9974        }
9975        synchronized (this) {
9976            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9977                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9978                    reason != null ? reason : "kill uid");
9979        }
9980    }
9981
9982    @Override
9983    public boolean killProcessesBelowForeground(String reason) {
9984        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9985            throw new SecurityException("killProcessesBelowForeground() only available to system");
9986        }
9987
9988        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9989    }
9990
9991    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9992        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9993            throw new SecurityException("killProcessesBelowAdj() only available to system");
9994        }
9995
9996        boolean killed = false;
9997        synchronized (mPidsSelfLocked) {
9998            final int size = mPidsSelfLocked.size();
9999            for (int i = 0; i < size; i++) {
10000                final int pid = mPidsSelfLocked.keyAt(i);
10001                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10002                if (proc == null) continue;
10003
10004                final int adj = proc.setAdj;
10005                if (adj > belowAdj && !proc.killedByAm) {
10006                    killUnneededProcessLocked(proc, reason);
10007                    killed = true;
10008                }
10009            }
10010        }
10011        return killed;
10012    }
10013
10014    @Override
10015    public void hang(final IBinder who, boolean allowRestart) {
10016        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10017                != PackageManager.PERMISSION_GRANTED) {
10018            throw new SecurityException("Requires permission "
10019                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10020        }
10021
10022        final IBinder.DeathRecipient death = new DeathRecipient() {
10023            @Override
10024            public void binderDied() {
10025                synchronized (this) {
10026                    notifyAll();
10027                }
10028            }
10029        };
10030
10031        try {
10032            who.linkToDeath(death, 0);
10033        } catch (RemoteException e) {
10034            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10035            return;
10036        }
10037
10038        synchronized (this) {
10039            Watchdog.getInstance().setAllowRestart(allowRestart);
10040            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10041            synchronized (death) {
10042                while (who.isBinderAlive()) {
10043                    try {
10044                        death.wait();
10045                    } catch (InterruptedException e) {
10046                    }
10047                }
10048            }
10049            Watchdog.getInstance().setAllowRestart(true);
10050        }
10051    }
10052
10053    @Override
10054    public void restart() {
10055        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10056                != PackageManager.PERMISSION_GRANTED) {
10057            throw new SecurityException("Requires permission "
10058                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10059        }
10060
10061        Log.i(TAG, "Sending shutdown broadcast...");
10062
10063        BroadcastReceiver br = new BroadcastReceiver() {
10064            @Override public void onReceive(Context context, Intent intent) {
10065                // Now the broadcast is done, finish up the low-level shutdown.
10066                Log.i(TAG, "Shutting down activity manager...");
10067                shutdown(10000);
10068                Log.i(TAG, "Shutdown complete, restarting!");
10069                Process.killProcess(Process.myPid());
10070                System.exit(10);
10071            }
10072        };
10073
10074        // First send the high-level shut down broadcast.
10075        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10076        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10077        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10078        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10079        mContext.sendOrderedBroadcastAsUser(intent,
10080                UserHandle.ALL, null, br, mHandler, 0, null, null);
10081        */
10082        br.onReceive(mContext, intent);
10083    }
10084
10085    private long getLowRamTimeSinceIdle(long now) {
10086        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10087    }
10088
10089    @Override
10090    public void performIdleMaintenance() {
10091        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10092                != PackageManager.PERMISSION_GRANTED) {
10093            throw new SecurityException("Requires permission "
10094                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10095        }
10096
10097        synchronized (this) {
10098            final long now = SystemClock.uptimeMillis();
10099            final long timeSinceLastIdle = now - mLastIdleTime;
10100            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10101            mLastIdleTime = now;
10102            mLowRamTimeSinceLastIdle = 0;
10103            if (mLowRamStartTime != 0) {
10104                mLowRamStartTime = now;
10105            }
10106
10107            StringBuilder sb = new StringBuilder(128);
10108            sb.append("Idle maintenance over ");
10109            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10110            sb.append(" low RAM for ");
10111            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10112            Slog.i(TAG, sb.toString());
10113
10114            // If at least 1/3 of our time since the last idle period has been spent
10115            // with RAM low, then we want to kill processes.
10116            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10117
10118            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10119                ProcessRecord proc = mLruProcesses.get(i);
10120                if (proc.notCachedSinceIdle) {
10121                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10122                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10123                        if (doKilling && proc.initialIdlePss != 0
10124                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10125                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
10126                                    + " from " + proc.initialIdlePss + ")");
10127                        }
10128                    }
10129                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10130                    proc.notCachedSinceIdle = true;
10131                    proc.initialIdlePss = 0;
10132                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10133                            isSleeping(), now);
10134                }
10135            }
10136
10137            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10138            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10139        }
10140    }
10141
10142    private void retrieveSettings() {
10143        final ContentResolver resolver = mContext.getContentResolver();
10144        String debugApp = Settings.Global.getString(
10145            resolver, Settings.Global.DEBUG_APP);
10146        boolean waitForDebugger = Settings.Global.getInt(
10147            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10148        boolean alwaysFinishActivities = Settings.Global.getInt(
10149            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10150        boolean forceRtl = Settings.Global.getInt(
10151                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10152        // Transfer any global setting for forcing RTL layout, into a System Property
10153        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10154
10155        Configuration configuration = new Configuration();
10156        Settings.System.getConfiguration(resolver, configuration);
10157        if (forceRtl) {
10158            // This will take care of setting the correct layout direction flags
10159            configuration.setLayoutDirection(configuration.locale);
10160        }
10161
10162        synchronized (this) {
10163            mDebugApp = mOrigDebugApp = debugApp;
10164            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10165            mAlwaysFinishActivities = alwaysFinishActivities;
10166            // This happens before any activities are started, so we can
10167            // change mConfiguration in-place.
10168            updateConfigurationLocked(configuration, null, false, true);
10169            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10170        }
10171    }
10172
10173    public boolean testIsSystemReady() {
10174        // no need to synchronize(this) just to read & return the value
10175        return mSystemReady;
10176    }
10177
10178    private static File getCalledPreBootReceiversFile() {
10179        File dataDir = Environment.getDataDirectory();
10180        File systemDir = new File(dataDir, "system");
10181        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10182        return fname;
10183    }
10184
10185    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10186        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10187        File file = getCalledPreBootReceiversFile();
10188        FileInputStream fis = null;
10189        try {
10190            fis = new FileInputStream(file);
10191            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10192            int fvers = dis.readInt();
10193            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10194                String vers = dis.readUTF();
10195                String codename = dis.readUTF();
10196                String build = dis.readUTF();
10197                if (android.os.Build.VERSION.RELEASE.equals(vers)
10198                        && android.os.Build.VERSION.CODENAME.equals(codename)
10199                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10200                    int num = dis.readInt();
10201                    while (num > 0) {
10202                        num--;
10203                        String pkg = dis.readUTF();
10204                        String cls = dis.readUTF();
10205                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10206                    }
10207                }
10208            }
10209        } catch (FileNotFoundException e) {
10210        } catch (IOException e) {
10211            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10212        } finally {
10213            if (fis != null) {
10214                try {
10215                    fis.close();
10216                } catch (IOException e) {
10217                }
10218            }
10219        }
10220        return lastDoneReceivers;
10221    }
10222
10223    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10224        File file = getCalledPreBootReceiversFile();
10225        FileOutputStream fos = null;
10226        DataOutputStream dos = null;
10227        try {
10228            fos = new FileOutputStream(file);
10229            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10230            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10231            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10232            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10233            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10234            dos.writeInt(list.size());
10235            for (int i=0; i<list.size(); i++) {
10236                dos.writeUTF(list.get(i).getPackageName());
10237                dos.writeUTF(list.get(i).getClassName());
10238            }
10239        } catch (IOException e) {
10240            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10241            file.delete();
10242        } finally {
10243            FileUtils.sync(fos);
10244            if (dos != null) {
10245                try {
10246                    dos.close();
10247                } catch (IOException e) {
10248                    // TODO Auto-generated catch block
10249                    e.printStackTrace();
10250                }
10251            }
10252        }
10253    }
10254
10255    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10256            ArrayList<ComponentName> doneReceivers, int userId) {
10257        boolean waitingUpdate = false;
10258        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10259        List<ResolveInfo> ris = null;
10260        try {
10261            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10262                    intent, null, 0, userId);
10263        } catch (RemoteException e) {
10264        }
10265        if (ris != null) {
10266            for (int i=ris.size()-1; i>=0; i--) {
10267                if ((ris.get(i).activityInfo.applicationInfo.flags
10268                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10269                    ris.remove(i);
10270                }
10271            }
10272            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10273
10274            // For User 0, load the version number. When delivering to a new user, deliver
10275            // to all receivers.
10276            if (userId == UserHandle.USER_OWNER) {
10277                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10278                for (int i=0; i<ris.size(); i++) {
10279                    ActivityInfo ai = ris.get(i).activityInfo;
10280                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10281                    if (lastDoneReceivers.contains(comp)) {
10282                        // We already did the pre boot receiver for this app with the current
10283                        // platform version, so don't do it again...
10284                        ris.remove(i);
10285                        i--;
10286                        // ...however, do keep it as one that has been done, so we don't
10287                        // forget about it when rewriting the file of last done receivers.
10288                        doneReceivers.add(comp);
10289                    }
10290                }
10291            }
10292
10293            // If primary user, send broadcast to all available users, else just to userId
10294            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10295                    : new int[] { userId };
10296            for (int i = 0; i < ris.size(); i++) {
10297                ActivityInfo ai = ris.get(i).activityInfo;
10298                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10299                doneReceivers.add(comp);
10300                intent.setComponent(comp);
10301                for (int j=0; j<users.length; j++) {
10302                    IIntentReceiver finisher = null;
10303                    // On last receiver and user, set up a completion callback
10304                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10305                        finisher = new IIntentReceiver.Stub() {
10306                            public void performReceive(Intent intent, int resultCode,
10307                                    String data, Bundle extras, boolean ordered,
10308                                    boolean sticky, int sendingUser) {
10309                                // The raw IIntentReceiver interface is called
10310                                // with the AM lock held, so redispatch to
10311                                // execute our code without the lock.
10312                                mHandler.post(onFinishCallback);
10313                            }
10314                        };
10315                    }
10316                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10317                            + " for user " + users[j]);
10318                    broadcastIntentLocked(null, null, intent, null, finisher,
10319                            0, null, null, null, AppOpsManager.OP_NONE,
10320                            true, false, MY_PID, Process.SYSTEM_UID,
10321                            users[j]);
10322                    if (finisher != null) {
10323                        waitingUpdate = true;
10324                    }
10325                }
10326            }
10327        }
10328
10329        return waitingUpdate;
10330    }
10331
10332    public void systemReady(final Runnable goingCallback) {
10333        synchronized(this) {
10334            if (mSystemReady) {
10335                // If we're done calling all the receivers, run the next "boot phase" passed in
10336                // by the SystemServer
10337                if (goingCallback != null) {
10338                    goingCallback.run();
10339                }
10340                return;
10341            }
10342
10343            // Make sure we have the current profile info, since it is needed for
10344            // security checks.
10345            updateCurrentProfileIdsLocked();
10346
10347            if (mRecentTasks == null) {
10348                mRecentTasks = mTaskPersister.restoreTasksLocked();
10349                if (!mRecentTasks.isEmpty()) {
10350                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10351                }
10352                mTaskPersister.startPersisting();
10353            }
10354
10355            // Check to see if there are any update receivers to run.
10356            if (!mDidUpdate) {
10357                if (mWaitingUpdate) {
10358                    return;
10359                }
10360                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10361                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10362                    public void run() {
10363                        synchronized (ActivityManagerService.this) {
10364                            mDidUpdate = true;
10365                        }
10366                        writeLastDonePreBootReceivers(doneReceivers);
10367                        showBootMessage(mContext.getText(
10368                                R.string.android_upgrading_complete),
10369                                false);
10370                        systemReady(goingCallback);
10371                    }
10372                }, doneReceivers, UserHandle.USER_OWNER);
10373
10374                if (mWaitingUpdate) {
10375                    return;
10376                }
10377                mDidUpdate = true;
10378            }
10379
10380            mAppOpsService.systemReady();
10381            mSystemReady = true;
10382        }
10383
10384        ArrayList<ProcessRecord> procsToKill = null;
10385        synchronized(mPidsSelfLocked) {
10386            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10387                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10388                if (!isAllowedWhileBooting(proc.info)){
10389                    if (procsToKill == null) {
10390                        procsToKill = new ArrayList<ProcessRecord>();
10391                    }
10392                    procsToKill.add(proc);
10393                }
10394            }
10395        }
10396
10397        synchronized(this) {
10398            if (procsToKill != null) {
10399                for (int i=procsToKill.size()-1; i>=0; i--) {
10400                    ProcessRecord proc = procsToKill.get(i);
10401                    Slog.i(TAG, "Removing system update proc: " + proc);
10402                    removeProcessLocked(proc, true, false, "system update done");
10403                }
10404            }
10405
10406            // Now that we have cleaned up any update processes, we
10407            // are ready to start launching real processes and know that
10408            // we won't trample on them any more.
10409            mProcessesReady = true;
10410        }
10411
10412        Slog.i(TAG, "System now ready");
10413        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10414            SystemClock.uptimeMillis());
10415
10416        synchronized(this) {
10417            // Make sure we have no pre-ready processes sitting around.
10418
10419            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10420                ResolveInfo ri = mContext.getPackageManager()
10421                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10422                                STOCK_PM_FLAGS);
10423                CharSequence errorMsg = null;
10424                if (ri != null) {
10425                    ActivityInfo ai = ri.activityInfo;
10426                    ApplicationInfo app = ai.applicationInfo;
10427                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10428                        mTopAction = Intent.ACTION_FACTORY_TEST;
10429                        mTopData = null;
10430                        mTopComponent = new ComponentName(app.packageName,
10431                                ai.name);
10432                    } else {
10433                        errorMsg = mContext.getResources().getText(
10434                                com.android.internal.R.string.factorytest_not_system);
10435                    }
10436                } else {
10437                    errorMsg = mContext.getResources().getText(
10438                            com.android.internal.R.string.factorytest_no_action);
10439                }
10440                if (errorMsg != null) {
10441                    mTopAction = null;
10442                    mTopData = null;
10443                    mTopComponent = null;
10444                    Message msg = Message.obtain();
10445                    msg.what = SHOW_FACTORY_ERROR_MSG;
10446                    msg.getData().putCharSequence("msg", errorMsg);
10447                    mHandler.sendMessage(msg);
10448                }
10449            }
10450        }
10451
10452        retrieveSettings();
10453
10454        synchronized (this) {
10455            readGrantedUriPermissionsLocked();
10456        }
10457
10458        if (goingCallback != null) goingCallback.run();
10459
10460        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10461                Integer.toString(mCurrentUserId), mCurrentUserId);
10462        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10463                Integer.toString(mCurrentUserId), mCurrentUserId);
10464        mSystemServiceManager.startUser(mCurrentUserId);
10465
10466        synchronized (this) {
10467            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10468                try {
10469                    List apps = AppGlobals.getPackageManager().
10470                        getPersistentApplications(STOCK_PM_FLAGS);
10471                    if (apps != null) {
10472                        int N = apps.size();
10473                        int i;
10474                        for (i=0; i<N; i++) {
10475                            ApplicationInfo info
10476                                = (ApplicationInfo)apps.get(i);
10477                            if (info != null &&
10478                                    !info.packageName.equals("android")) {
10479                                addAppLocked(info, false, null /* ABI override */);
10480                            }
10481                        }
10482                    }
10483                } catch (RemoteException ex) {
10484                    // pm is in same process, this will never happen.
10485                }
10486            }
10487
10488            // Start up initial activity.
10489            mBooting = true;
10490
10491            try {
10492                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10493                    Message msg = Message.obtain();
10494                    msg.what = SHOW_UID_ERROR_MSG;
10495                    mHandler.sendMessage(msg);
10496                }
10497            } catch (RemoteException e) {
10498            }
10499
10500            long ident = Binder.clearCallingIdentity();
10501            try {
10502                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10503                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10504                        | Intent.FLAG_RECEIVER_FOREGROUND);
10505                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10506                broadcastIntentLocked(null, null, intent,
10507                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10508                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10509                intent = new Intent(Intent.ACTION_USER_STARTING);
10510                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10511                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10512                broadcastIntentLocked(null, null, intent,
10513                        null, new IIntentReceiver.Stub() {
10514                            @Override
10515                            public void performReceive(Intent intent, int resultCode, String data,
10516                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10517                                    throws RemoteException {
10518                            }
10519                        }, 0, null, null,
10520                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10521                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10522            } catch (Throwable t) {
10523                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10524            } finally {
10525                Binder.restoreCallingIdentity(ident);
10526            }
10527            mStackSupervisor.resumeTopActivitiesLocked();
10528            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10529        }
10530    }
10531
10532    private boolean makeAppCrashingLocked(ProcessRecord app,
10533            String shortMsg, String longMsg, String stackTrace) {
10534        app.crashing = true;
10535        app.crashingReport = generateProcessError(app,
10536                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10537        startAppProblemLocked(app);
10538        app.stopFreezingAllLocked();
10539        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10540    }
10541
10542    private void makeAppNotRespondingLocked(ProcessRecord app,
10543            String activity, String shortMsg, String longMsg) {
10544        app.notResponding = true;
10545        app.notRespondingReport = generateProcessError(app,
10546                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10547                activity, shortMsg, longMsg, null);
10548        startAppProblemLocked(app);
10549        app.stopFreezingAllLocked();
10550    }
10551
10552    /**
10553     * Generate a process error record, suitable for attachment to a ProcessRecord.
10554     *
10555     * @param app The ProcessRecord in which the error occurred.
10556     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10557     *                      ActivityManager.AppErrorStateInfo
10558     * @param activity The activity associated with the crash, if known.
10559     * @param shortMsg Short message describing the crash.
10560     * @param longMsg Long message describing the crash.
10561     * @param stackTrace Full crash stack trace, may be null.
10562     *
10563     * @return Returns a fully-formed AppErrorStateInfo record.
10564     */
10565    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10566            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10567        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10568
10569        report.condition = condition;
10570        report.processName = app.processName;
10571        report.pid = app.pid;
10572        report.uid = app.info.uid;
10573        report.tag = activity;
10574        report.shortMsg = shortMsg;
10575        report.longMsg = longMsg;
10576        report.stackTrace = stackTrace;
10577
10578        return report;
10579    }
10580
10581    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10582        synchronized (this) {
10583            app.crashing = false;
10584            app.crashingReport = null;
10585            app.notResponding = false;
10586            app.notRespondingReport = null;
10587            if (app.anrDialog == fromDialog) {
10588                app.anrDialog = null;
10589            }
10590            if (app.waitDialog == fromDialog) {
10591                app.waitDialog = null;
10592            }
10593            if (app.pid > 0 && app.pid != MY_PID) {
10594                handleAppCrashLocked(app, null, null, null);
10595                killUnneededProcessLocked(app, "user request after error");
10596            }
10597        }
10598    }
10599
10600    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10601            String stackTrace) {
10602        long now = SystemClock.uptimeMillis();
10603
10604        Long crashTime;
10605        if (!app.isolated) {
10606            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10607        } else {
10608            crashTime = null;
10609        }
10610        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10611            // This process loses!
10612            Slog.w(TAG, "Process " + app.info.processName
10613                    + " has crashed too many times: killing!");
10614            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10615                    app.userId, app.info.processName, app.uid);
10616            mStackSupervisor.handleAppCrashLocked(app);
10617            if (!app.persistent) {
10618                // We don't want to start this process again until the user
10619                // explicitly does so...  but for persistent process, we really
10620                // need to keep it running.  If a persistent process is actually
10621                // repeatedly crashing, then badness for everyone.
10622                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10623                        app.info.processName);
10624                if (!app.isolated) {
10625                    // XXX We don't have a way to mark isolated processes
10626                    // as bad, since they don't have a peristent identity.
10627                    mBadProcesses.put(app.info.processName, app.uid,
10628                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10629                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10630                }
10631                app.bad = true;
10632                app.removed = true;
10633                // Don't let services in this process be restarted and potentially
10634                // annoy the user repeatedly.  Unless it is persistent, since those
10635                // processes run critical code.
10636                removeProcessLocked(app, false, false, "crash");
10637                mStackSupervisor.resumeTopActivitiesLocked();
10638                return false;
10639            }
10640            mStackSupervisor.resumeTopActivitiesLocked();
10641        } else {
10642            mStackSupervisor.finishTopRunningActivityLocked(app);
10643        }
10644
10645        // Bump up the crash count of any services currently running in the proc.
10646        for (int i=app.services.size()-1; i>=0; i--) {
10647            // Any services running in the application need to be placed
10648            // back in the pending list.
10649            ServiceRecord sr = app.services.valueAt(i);
10650            sr.crashCount++;
10651        }
10652
10653        // If the crashing process is what we consider to be the "home process" and it has been
10654        // replaced by a third-party app, clear the package preferred activities from packages
10655        // with a home activity running in the process to prevent a repeatedly crashing app
10656        // from blocking the user to manually clear the list.
10657        final ArrayList<ActivityRecord> activities = app.activities;
10658        if (app == mHomeProcess && activities.size() > 0
10659                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10660            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10661                final ActivityRecord r = activities.get(activityNdx);
10662                if (r.isHomeActivity()) {
10663                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10664                    try {
10665                        ActivityThread.getPackageManager()
10666                                .clearPackagePreferredActivities(r.packageName);
10667                    } catch (RemoteException c) {
10668                        // pm is in same process, this will never happen.
10669                    }
10670                }
10671            }
10672        }
10673
10674        if (!app.isolated) {
10675            // XXX Can't keep track of crash times for isolated processes,
10676            // because they don't have a perisistent identity.
10677            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10678        }
10679
10680        if (app.crashHandler != null) mHandler.post(app.crashHandler);
10681        return true;
10682    }
10683
10684    void startAppProblemLocked(ProcessRecord app) {
10685        // If this app is not running under the current user, then we
10686        // can't give it a report button because that would require
10687        // launching the report UI under a different user.
10688        app.errorReportReceiver = null;
10689
10690        for (int userId : mCurrentProfileIds) {
10691            if (app.userId == userId) {
10692                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10693                        mContext, app.info.packageName, app.info.flags);
10694            }
10695        }
10696        skipCurrentReceiverLocked(app);
10697    }
10698
10699    void skipCurrentReceiverLocked(ProcessRecord app) {
10700        for (BroadcastQueue queue : mBroadcastQueues) {
10701            queue.skipCurrentReceiverLocked(app);
10702        }
10703    }
10704
10705    /**
10706     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10707     * The application process will exit immediately after this call returns.
10708     * @param app object of the crashing app, null for the system server
10709     * @param crashInfo describing the exception
10710     */
10711    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10712        ProcessRecord r = findAppProcess(app, "Crash");
10713        final String processName = app == null ? "system_server"
10714                : (r == null ? "unknown" : r.processName);
10715
10716        handleApplicationCrashInner("crash", r, processName, crashInfo);
10717    }
10718
10719    /* Native crash reporting uses this inner version because it needs to be somewhat
10720     * decoupled from the AM-managed cleanup lifecycle
10721     */
10722    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10723            ApplicationErrorReport.CrashInfo crashInfo) {
10724        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10725                UserHandle.getUserId(Binder.getCallingUid()), processName,
10726                r == null ? -1 : r.info.flags,
10727                crashInfo.exceptionClassName,
10728                crashInfo.exceptionMessage,
10729                crashInfo.throwFileName,
10730                crashInfo.throwLineNumber);
10731
10732        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10733
10734        crashApplication(r, crashInfo);
10735    }
10736
10737    public void handleApplicationStrictModeViolation(
10738            IBinder app,
10739            int violationMask,
10740            StrictMode.ViolationInfo info) {
10741        ProcessRecord r = findAppProcess(app, "StrictMode");
10742        if (r == null) {
10743            return;
10744        }
10745
10746        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10747            Integer stackFingerprint = info.hashCode();
10748            boolean logIt = true;
10749            synchronized (mAlreadyLoggedViolatedStacks) {
10750                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10751                    logIt = false;
10752                    // TODO: sub-sample into EventLog for these, with
10753                    // the info.durationMillis?  Then we'd get
10754                    // the relative pain numbers, without logging all
10755                    // the stack traces repeatedly.  We'd want to do
10756                    // likewise in the client code, which also does
10757                    // dup suppression, before the Binder call.
10758                } else {
10759                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10760                        mAlreadyLoggedViolatedStacks.clear();
10761                    }
10762                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10763                }
10764            }
10765            if (logIt) {
10766                logStrictModeViolationToDropBox(r, info);
10767            }
10768        }
10769
10770        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10771            AppErrorResult result = new AppErrorResult();
10772            synchronized (this) {
10773                final long origId = Binder.clearCallingIdentity();
10774
10775                Message msg = Message.obtain();
10776                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10777                HashMap<String, Object> data = new HashMap<String, Object>();
10778                data.put("result", result);
10779                data.put("app", r);
10780                data.put("violationMask", violationMask);
10781                data.put("info", info);
10782                msg.obj = data;
10783                mHandler.sendMessage(msg);
10784
10785                Binder.restoreCallingIdentity(origId);
10786            }
10787            int res = result.get();
10788            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10789        }
10790    }
10791
10792    // Depending on the policy in effect, there could be a bunch of
10793    // these in quick succession so we try to batch these together to
10794    // minimize disk writes, number of dropbox entries, and maximize
10795    // compression, by having more fewer, larger records.
10796    private void logStrictModeViolationToDropBox(
10797            ProcessRecord process,
10798            StrictMode.ViolationInfo info) {
10799        if (info == null) {
10800            return;
10801        }
10802        final boolean isSystemApp = process == null ||
10803                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10804                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10805        final String processName = process == null ? "unknown" : process.processName;
10806        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10807        final DropBoxManager dbox = (DropBoxManager)
10808                mContext.getSystemService(Context.DROPBOX_SERVICE);
10809
10810        // Exit early if the dropbox isn't configured to accept this report type.
10811        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10812
10813        boolean bufferWasEmpty;
10814        boolean needsFlush;
10815        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10816        synchronized (sb) {
10817            bufferWasEmpty = sb.length() == 0;
10818            appendDropBoxProcessHeaders(process, processName, sb);
10819            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10820            sb.append("System-App: ").append(isSystemApp).append("\n");
10821            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10822            if (info.violationNumThisLoop != 0) {
10823                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10824            }
10825            if (info.numAnimationsRunning != 0) {
10826                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10827            }
10828            if (info.broadcastIntentAction != null) {
10829                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10830            }
10831            if (info.durationMillis != -1) {
10832                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10833            }
10834            if (info.numInstances != -1) {
10835                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10836            }
10837            if (info.tags != null) {
10838                for (String tag : info.tags) {
10839                    sb.append("Span-Tag: ").append(tag).append("\n");
10840                }
10841            }
10842            sb.append("\n");
10843            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10844                sb.append(info.crashInfo.stackTrace);
10845            }
10846            sb.append("\n");
10847
10848            // Only buffer up to ~64k.  Various logging bits truncate
10849            // things at 128k.
10850            needsFlush = (sb.length() > 64 * 1024);
10851        }
10852
10853        // Flush immediately if the buffer's grown too large, or this
10854        // is a non-system app.  Non-system apps are isolated with a
10855        // different tag & policy and not batched.
10856        //
10857        // Batching is useful during internal testing with
10858        // StrictMode settings turned up high.  Without batching,
10859        // thousands of separate files could be created on boot.
10860        if (!isSystemApp || needsFlush) {
10861            new Thread("Error dump: " + dropboxTag) {
10862                @Override
10863                public void run() {
10864                    String report;
10865                    synchronized (sb) {
10866                        report = sb.toString();
10867                        sb.delete(0, sb.length());
10868                        sb.trimToSize();
10869                    }
10870                    if (report.length() != 0) {
10871                        dbox.addText(dropboxTag, report);
10872                    }
10873                }
10874            }.start();
10875            return;
10876        }
10877
10878        // System app batching:
10879        if (!bufferWasEmpty) {
10880            // An existing dropbox-writing thread is outstanding, so
10881            // we don't need to start it up.  The existing thread will
10882            // catch the buffer appends we just did.
10883            return;
10884        }
10885
10886        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10887        // (After this point, we shouldn't access AMS internal data structures.)
10888        new Thread("Error dump: " + dropboxTag) {
10889            @Override
10890            public void run() {
10891                // 5 second sleep to let stacks arrive and be batched together
10892                try {
10893                    Thread.sleep(5000);  // 5 seconds
10894                } catch (InterruptedException e) {}
10895
10896                String errorReport;
10897                synchronized (mStrictModeBuffer) {
10898                    errorReport = mStrictModeBuffer.toString();
10899                    if (errorReport.length() == 0) {
10900                        return;
10901                    }
10902                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10903                    mStrictModeBuffer.trimToSize();
10904                }
10905                dbox.addText(dropboxTag, errorReport);
10906            }
10907        }.start();
10908    }
10909
10910    /**
10911     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10912     * @param app object of the crashing app, null for the system server
10913     * @param tag reported by the caller
10914     * @param crashInfo describing the context of the error
10915     * @return true if the process should exit immediately (WTF is fatal)
10916     */
10917    public boolean handleApplicationWtf(IBinder app, String tag,
10918            ApplicationErrorReport.CrashInfo crashInfo) {
10919        ProcessRecord r = findAppProcess(app, "WTF");
10920        final String processName = app == null ? "system_server"
10921                : (r == null ? "unknown" : r.processName);
10922
10923        EventLog.writeEvent(EventLogTags.AM_WTF,
10924                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10925                processName,
10926                r == null ? -1 : r.info.flags,
10927                tag, crashInfo.exceptionMessage);
10928
10929        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10930
10931        if (r != null && r.pid != Process.myPid() &&
10932                Settings.Global.getInt(mContext.getContentResolver(),
10933                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10934            crashApplication(r, crashInfo);
10935            return true;
10936        } else {
10937            return false;
10938        }
10939    }
10940
10941    /**
10942     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10943     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10944     */
10945    private ProcessRecord findAppProcess(IBinder app, String reason) {
10946        if (app == null) {
10947            return null;
10948        }
10949
10950        synchronized (this) {
10951            final int NP = mProcessNames.getMap().size();
10952            for (int ip=0; ip<NP; ip++) {
10953                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10954                final int NA = apps.size();
10955                for (int ia=0; ia<NA; ia++) {
10956                    ProcessRecord p = apps.valueAt(ia);
10957                    if (p.thread != null && p.thread.asBinder() == app) {
10958                        return p;
10959                    }
10960                }
10961            }
10962
10963            Slog.w(TAG, "Can't find mystery application for " + reason
10964                    + " from pid=" + Binder.getCallingPid()
10965                    + " uid=" + Binder.getCallingUid() + ": " + app);
10966            return null;
10967        }
10968    }
10969
10970    /**
10971     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10972     * to append various headers to the dropbox log text.
10973     */
10974    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10975            StringBuilder sb) {
10976        // Watchdog thread ends up invoking this function (with
10977        // a null ProcessRecord) to add the stack file to dropbox.
10978        // Do not acquire a lock on this (am) in such cases, as it
10979        // could cause a potential deadlock, if and when watchdog
10980        // is invoked due to unavailability of lock on am and it
10981        // would prevent watchdog from killing system_server.
10982        if (process == null) {
10983            sb.append("Process: ").append(processName).append("\n");
10984            return;
10985        }
10986        // Note: ProcessRecord 'process' is guarded by the service
10987        // instance.  (notably process.pkgList, which could otherwise change
10988        // concurrently during execution of this method)
10989        synchronized (this) {
10990            sb.append("Process: ").append(processName).append("\n");
10991            int flags = process.info.flags;
10992            IPackageManager pm = AppGlobals.getPackageManager();
10993            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10994            for (int ip=0; ip<process.pkgList.size(); ip++) {
10995                String pkg = process.pkgList.keyAt(ip);
10996                sb.append("Package: ").append(pkg);
10997                try {
10998                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10999                    if (pi != null) {
11000                        sb.append(" v").append(pi.versionCode);
11001                        if (pi.versionName != null) {
11002                            sb.append(" (").append(pi.versionName).append(")");
11003                        }
11004                    }
11005                } catch (RemoteException e) {
11006                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11007                }
11008                sb.append("\n");
11009            }
11010        }
11011    }
11012
11013    private static String processClass(ProcessRecord process) {
11014        if (process == null || process.pid == MY_PID) {
11015            return "system_server";
11016        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11017            return "system_app";
11018        } else {
11019            return "data_app";
11020        }
11021    }
11022
11023    /**
11024     * Write a description of an error (crash, WTF, ANR) to the drop box.
11025     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11026     * @param process which caused the error, null means the system server
11027     * @param activity which triggered the error, null if unknown
11028     * @param parent activity related to the error, null if unknown
11029     * @param subject line related to the error, null if absent
11030     * @param report in long form describing the error, null if absent
11031     * @param logFile to include in the report, null if none
11032     * @param crashInfo giving an application stack trace, null if absent
11033     */
11034    public void addErrorToDropBox(String eventType,
11035            ProcessRecord process, String processName, ActivityRecord activity,
11036            ActivityRecord parent, String subject,
11037            final String report, final File logFile,
11038            final ApplicationErrorReport.CrashInfo crashInfo) {
11039        // NOTE -- this must never acquire the ActivityManagerService lock,
11040        // otherwise the watchdog may be prevented from resetting the system.
11041
11042        final String dropboxTag = processClass(process) + "_" + eventType;
11043        final DropBoxManager dbox = (DropBoxManager)
11044                mContext.getSystemService(Context.DROPBOX_SERVICE);
11045
11046        // Exit early if the dropbox isn't configured to accept this report type.
11047        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11048
11049        final StringBuilder sb = new StringBuilder(1024);
11050        appendDropBoxProcessHeaders(process, processName, sb);
11051        if (activity != null) {
11052            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11053        }
11054        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11055            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11056        }
11057        if (parent != null && parent != activity) {
11058            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11059        }
11060        if (subject != null) {
11061            sb.append("Subject: ").append(subject).append("\n");
11062        }
11063        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11064        if (Debug.isDebuggerConnected()) {
11065            sb.append("Debugger: Connected\n");
11066        }
11067        sb.append("\n");
11068
11069        // Do the rest in a worker thread to avoid blocking the caller on I/O
11070        // (After this point, we shouldn't access AMS internal data structures.)
11071        Thread worker = new Thread("Error dump: " + dropboxTag) {
11072            @Override
11073            public void run() {
11074                if (report != null) {
11075                    sb.append(report);
11076                }
11077                if (logFile != null) {
11078                    try {
11079                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11080                                    "\n\n[[TRUNCATED]]"));
11081                    } catch (IOException e) {
11082                        Slog.e(TAG, "Error reading " + logFile, e);
11083                    }
11084                }
11085                if (crashInfo != null && crashInfo.stackTrace != null) {
11086                    sb.append(crashInfo.stackTrace);
11087                }
11088
11089                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11090                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11091                if (lines > 0) {
11092                    sb.append("\n");
11093
11094                    // Merge several logcat streams, and take the last N lines
11095                    InputStreamReader input = null;
11096                    try {
11097                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11098                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11099                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11100
11101                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11102                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11103                        input = new InputStreamReader(logcat.getInputStream());
11104
11105                        int num;
11106                        char[] buf = new char[8192];
11107                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11108                    } catch (IOException e) {
11109                        Slog.e(TAG, "Error running logcat", e);
11110                    } finally {
11111                        if (input != null) try { input.close(); } catch (IOException e) {}
11112                    }
11113                }
11114
11115                dbox.addText(dropboxTag, sb.toString());
11116            }
11117        };
11118
11119        if (process == null) {
11120            // If process is null, we are being called from some internal code
11121            // and may be about to die -- run this synchronously.
11122            worker.run();
11123        } else {
11124            worker.start();
11125        }
11126    }
11127
11128    /**
11129     * Bring up the "unexpected error" dialog box for a crashing app.
11130     * Deal with edge cases (intercepts from instrumented applications,
11131     * ActivityController, error intent receivers, that sort of thing).
11132     * @param r the application crashing
11133     * @param crashInfo describing the failure
11134     */
11135    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11136        long timeMillis = System.currentTimeMillis();
11137        String shortMsg = crashInfo.exceptionClassName;
11138        String longMsg = crashInfo.exceptionMessage;
11139        String stackTrace = crashInfo.stackTrace;
11140        if (shortMsg != null && longMsg != null) {
11141            longMsg = shortMsg + ": " + longMsg;
11142        } else if (shortMsg != null) {
11143            longMsg = shortMsg;
11144        }
11145
11146        AppErrorResult result = new AppErrorResult();
11147        synchronized (this) {
11148            if (mController != null) {
11149                try {
11150                    String name = r != null ? r.processName : null;
11151                    int pid = r != null ? r.pid : Binder.getCallingPid();
11152                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11153                    if (!mController.appCrashed(name, pid,
11154                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11155                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11156                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11157                            Slog.w(TAG, "Skip killing native crashed app " + name
11158                                    + "(" + pid + ") during testing");
11159                        } else {
11160                            Slog.w(TAG, "Force-killing crashed app " + name
11161                                    + " at watcher's request");
11162                            Process.killProcess(pid);
11163                            if (r != null) {
11164                                Process.killProcessGroup(uid, pid);
11165                            }
11166                        }
11167                        return;
11168                    }
11169                } catch (RemoteException e) {
11170                    mController = null;
11171                    Watchdog.getInstance().setActivityController(null);
11172                }
11173            }
11174
11175            final long origId = Binder.clearCallingIdentity();
11176
11177            // If this process is running instrumentation, finish it.
11178            if (r != null && r.instrumentationClass != null) {
11179                Slog.w(TAG, "Error in app " + r.processName
11180                      + " running instrumentation " + r.instrumentationClass + ":");
11181                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11182                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11183                Bundle info = new Bundle();
11184                info.putString("shortMsg", shortMsg);
11185                info.putString("longMsg", longMsg);
11186                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11187                Binder.restoreCallingIdentity(origId);
11188                return;
11189            }
11190
11191            // If we can't identify the process or it's already exceeded its crash quota,
11192            // quit right away without showing a crash dialog.
11193            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11194                Binder.restoreCallingIdentity(origId);
11195                return;
11196            }
11197
11198            Message msg = Message.obtain();
11199            msg.what = SHOW_ERROR_MSG;
11200            HashMap data = new HashMap();
11201            data.put("result", result);
11202            data.put("app", r);
11203            msg.obj = data;
11204            mHandler.sendMessage(msg);
11205
11206            Binder.restoreCallingIdentity(origId);
11207        }
11208
11209        int res = result.get();
11210
11211        Intent appErrorIntent = null;
11212        synchronized (this) {
11213            if (r != null && !r.isolated) {
11214                // XXX Can't keep track of crash time for isolated processes,
11215                // since they don't have a persistent identity.
11216                mProcessCrashTimes.put(r.info.processName, r.uid,
11217                        SystemClock.uptimeMillis());
11218            }
11219            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11220                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11221            }
11222        }
11223
11224        if (appErrorIntent != null) {
11225            try {
11226                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11227            } catch (ActivityNotFoundException e) {
11228                Slog.w(TAG, "bug report receiver dissappeared", e);
11229            }
11230        }
11231    }
11232
11233    Intent createAppErrorIntentLocked(ProcessRecord r,
11234            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11235        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11236        if (report == null) {
11237            return null;
11238        }
11239        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11240        result.setComponent(r.errorReportReceiver);
11241        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11242        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11243        return result;
11244    }
11245
11246    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11247            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11248        if (r.errorReportReceiver == null) {
11249            return null;
11250        }
11251
11252        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11253            return null;
11254        }
11255
11256        ApplicationErrorReport report = new ApplicationErrorReport();
11257        report.packageName = r.info.packageName;
11258        report.installerPackageName = r.errorReportReceiver.getPackageName();
11259        report.processName = r.processName;
11260        report.time = timeMillis;
11261        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11262
11263        if (r.crashing || r.forceCrashReport) {
11264            report.type = ApplicationErrorReport.TYPE_CRASH;
11265            report.crashInfo = crashInfo;
11266        } else if (r.notResponding) {
11267            report.type = ApplicationErrorReport.TYPE_ANR;
11268            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11269
11270            report.anrInfo.activity = r.notRespondingReport.tag;
11271            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11272            report.anrInfo.info = r.notRespondingReport.longMsg;
11273        }
11274
11275        return report;
11276    }
11277
11278    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11279        enforceNotIsolatedCaller("getProcessesInErrorState");
11280        // assume our apps are happy - lazy create the list
11281        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11282
11283        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11284                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11285        int userId = UserHandle.getUserId(Binder.getCallingUid());
11286
11287        synchronized (this) {
11288
11289            // iterate across all processes
11290            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11291                ProcessRecord app = mLruProcesses.get(i);
11292                if (!allUsers && app.userId != userId) {
11293                    continue;
11294                }
11295                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11296                    // This one's in trouble, so we'll generate a report for it
11297                    // crashes are higher priority (in case there's a crash *and* an anr)
11298                    ActivityManager.ProcessErrorStateInfo report = null;
11299                    if (app.crashing) {
11300                        report = app.crashingReport;
11301                    } else if (app.notResponding) {
11302                        report = app.notRespondingReport;
11303                    }
11304
11305                    if (report != null) {
11306                        if (errList == null) {
11307                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11308                        }
11309                        errList.add(report);
11310                    } else {
11311                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11312                                " crashing = " + app.crashing +
11313                                " notResponding = " + app.notResponding);
11314                    }
11315                }
11316            }
11317        }
11318
11319        return errList;
11320    }
11321
11322    static int procStateToImportance(int procState, int memAdj,
11323            ActivityManager.RunningAppProcessInfo currApp) {
11324        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11325        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11326            currApp.lru = memAdj;
11327        } else {
11328            currApp.lru = 0;
11329        }
11330        return imp;
11331    }
11332
11333    private void fillInProcMemInfo(ProcessRecord app,
11334            ActivityManager.RunningAppProcessInfo outInfo) {
11335        outInfo.pid = app.pid;
11336        outInfo.uid = app.info.uid;
11337        if (mHeavyWeightProcess == app) {
11338            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11339        }
11340        if (app.persistent) {
11341            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11342        }
11343        if (app.activities.size() > 0) {
11344            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11345        }
11346        outInfo.lastTrimLevel = app.trimMemoryLevel;
11347        int adj = app.curAdj;
11348        int procState = app.curProcState;
11349        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11350        outInfo.importanceReasonCode = app.adjTypeCode;
11351        outInfo.processState = app.curProcState;
11352    }
11353
11354    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11355        enforceNotIsolatedCaller("getRunningAppProcesses");
11356        // Lazy instantiation of list
11357        List<ActivityManager.RunningAppProcessInfo> runList = null;
11358        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11359                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11360        int userId = UserHandle.getUserId(Binder.getCallingUid());
11361        synchronized (this) {
11362            // Iterate across all processes
11363            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11364                ProcessRecord app = mLruProcesses.get(i);
11365                if (!allUsers && app.userId != userId) {
11366                    continue;
11367                }
11368                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11369                    // Generate process state info for running application
11370                    ActivityManager.RunningAppProcessInfo currApp =
11371                        new ActivityManager.RunningAppProcessInfo(app.processName,
11372                                app.pid, app.getPackageList());
11373                    fillInProcMemInfo(app, currApp);
11374                    if (app.adjSource instanceof ProcessRecord) {
11375                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11376                        currApp.importanceReasonImportance =
11377                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11378                                        app.adjSourceProcState);
11379                    } else if (app.adjSource instanceof ActivityRecord) {
11380                        ActivityRecord r = (ActivityRecord)app.adjSource;
11381                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11382                    }
11383                    if (app.adjTarget instanceof ComponentName) {
11384                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11385                    }
11386                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11387                    //        + " lru=" + currApp.lru);
11388                    if (runList == null) {
11389                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11390                    }
11391                    runList.add(currApp);
11392                }
11393            }
11394        }
11395        return runList;
11396    }
11397
11398    public List<ApplicationInfo> getRunningExternalApplications() {
11399        enforceNotIsolatedCaller("getRunningExternalApplications");
11400        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11401        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11402        if (runningApps != null && runningApps.size() > 0) {
11403            Set<String> extList = new HashSet<String>();
11404            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11405                if (app.pkgList != null) {
11406                    for (String pkg : app.pkgList) {
11407                        extList.add(pkg);
11408                    }
11409                }
11410            }
11411            IPackageManager pm = AppGlobals.getPackageManager();
11412            for (String pkg : extList) {
11413                try {
11414                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11415                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11416                        retList.add(info);
11417                    }
11418                } catch (RemoteException e) {
11419                }
11420            }
11421        }
11422        return retList;
11423    }
11424
11425    @Override
11426    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11427        enforceNotIsolatedCaller("getMyMemoryState");
11428        synchronized (this) {
11429            ProcessRecord proc;
11430            synchronized (mPidsSelfLocked) {
11431                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11432            }
11433            fillInProcMemInfo(proc, outInfo);
11434        }
11435    }
11436
11437    @Override
11438    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11439        if (checkCallingPermission(android.Manifest.permission.DUMP)
11440                != PackageManager.PERMISSION_GRANTED) {
11441            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11442                    + Binder.getCallingPid()
11443                    + ", uid=" + Binder.getCallingUid()
11444                    + " without permission "
11445                    + android.Manifest.permission.DUMP);
11446            return;
11447        }
11448
11449        boolean dumpAll = false;
11450        boolean dumpClient = false;
11451        String dumpPackage = null;
11452
11453        int opti = 0;
11454        while (opti < args.length) {
11455            String opt = args[opti];
11456            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11457                break;
11458            }
11459            opti++;
11460            if ("-a".equals(opt)) {
11461                dumpAll = true;
11462            } else if ("-c".equals(opt)) {
11463                dumpClient = true;
11464            } else if ("-h".equals(opt)) {
11465                pw.println("Activity manager dump options:");
11466                pw.println("  [-a] [-c] [-h] [cmd] ...");
11467                pw.println("  cmd may be one of:");
11468                pw.println("    a[ctivities]: activity stack state");
11469                pw.println("    r[recents]: recent activities state");
11470                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11471                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11472                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11473                pw.println("    o[om]: out of memory management");
11474                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11475                pw.println("    provider [COMP_SPEC]: provider client-side state");
11476                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11477                pw.println("    service [COMP_SPEC]: service client-side state");
11478                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11479                pw.println("    all: dump all activities");
11480                pw.println("    top: dump the top activity");
11481                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11482                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11483                pw.println("    a partial substring in a component name, a");
11484                pw.println("    hex object identifier.");
11485                pw.println("  -a: include all available server state.");
11486                pw.println("  -c: include client state.");
11487                return;
11488            } else {
11489                pw.println("Unknown argument: " + opt + "; use -h for help");
11490            }
11491        }
11492
11493        long origId = Binder.clearCallingIdentity();
11494        boolean more = false;
11495        // Is the caller requesting to dump a particular piece of data?
11496        if (opti < args.length) {
11497            String cmd = args[opti];
11498            opti++;
11499            if ("activities".equals(cmd) || "a".equals(cmd)) {
11500                synchronized (this) {
11501                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11502                }
11503            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
11504                synchronized (this) {
11505                    dumpRecentsLocked(fd, pw, args, opti, true, null);
11506                }
11507            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11508                String[] newArgs;
11509                String name;
11510                if (opti >= args.length) {
11511                    name = null;
11512                    newArgs = EMPTY_STRING_ARRAY;
11513                } else {
11514                    name = args[opti];
11515                    opti++;
11516                    newArgs = new String[args.length - opti];
11517                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11518                            args.length - opti);
11519                }
11520                synchronized (this) {
11521                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11522                }
11523            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11524                String[] newArgs;
11525                String name;
11526                if (opti >= args.length) {
11527                    name = null;
11528                    newArgs = EMPTY_STRING_ARRAY;
11529                } else {
11530                    name = args[opti];
11531                    opti++;
11532                    newArgs = new String[args.length - opti];
11533                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11534                            args.length - opti);
11535                }
11536                synchronized (this) {
11537                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11538                }
11539            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11540                String[] newArgs;
11541                String name;
11542                if (opti >= args.length) {
11543                    name = null;
11544                    newArgs = EMPTY_STRING_ARRAY;
11545                } else {
11546                    name = args[opti];
11547                    opti++;
11548                    newArgs = new String[args.length - opti];
11549                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11550                            args.length - opti);
11551                }
11552                synchronized (this) {
11553                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11554                }
11555            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11556                synchronized (this) {
11557                    dumpOomLocked(fd, pw, args, opti, true);
11558                }
11559            } else if ("provider".equals(cmd)) {
11560                String[] newArgs;
11561                String name;
11562                if (opti >= args.length) {
11563                    name = null;
11564                    newArgs = EMPTY_STRING_ARRAY;
11565                } else {
11566                    name = args[opti];
11567                    opti++;
11568                    newArgs = new String[args.length - opti];
11569                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11570                }
11571                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11572                    pw.println("No providers match: " + name);
11573                    pw.println("Use -h for help.");
11574                }
11575            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11576                synchronized (this) {
11577                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11578                }
11579            } else if ("service".equals(cmd)) {
11580                String[] newArgs;
11581                String name;
11582                if (opti >= args.length) {
11583                    name = null;
11584                    newArgs = EMPTY_STRING_ARRAY;
11585                } else {
11586                    name = args[opti];
11587                    opti++;
11588                    newArgs = new String[args.length - opti];
11589                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11590                            args.length - opti);
11591                }
11592                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11593                    pw.println("No services match: " + name);
11594                    pw.println("Use -h for help.");
11595                }
11596            } else if ("package".equals(cmd)) {
11597                String[] newArgs;
11598                if (opti >= args.length) {
11599                    pw.println("package: no package name specified");
11600                    pw.println("Use -h for help.");
11601                } else {
11602                    dumpPackage = args[opti];
11603                    opti++;
11604                    newArgs = new String[args.length - opti];
11605                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11606                            args.length - opti);
11607                    args = newArgs;
11608                    opti = 0;
11609                    more = true;
11610                }
11611            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11612                synchronized (this) {
11613                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11614                }
11615            } else {
11616                // Dumping a single activity?
11617                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11618                    pw.println("Bad activity command, or no activities match: " + cmd);
11619                    pw.println("Use -h for help.");
11620                }
11621            }
11622            if (!more) {
11623                Binder.restoreCallingIdentity(origId);
11624                return;
11625            }
11626        }
11627
11628        // No piece of data specified, dump everything.
11629        synchronized (this) {
11630            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11631            pw.println();
11632            if (dumpAll) {
11633                pw.println("-------------------------------------------------------------------------------");
11634            }
11635            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11636            pw.println();
11637            if (dumpAll) {
11638                pw.println("-------------------------------------------------------------------------------");
11639            }
11640            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11641            pw.println();
11642            if (dumpAll) {
11643                pw.println("-------------------------------------------------------------------------------");
11644            }
11645            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11646            pw.println();
11647            if (dumpAll) {
11648                pw.println("-------------------------------------------------------------------------------");
11649            }
11650            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11651            pw.println();
11652            if (dumpAll) {
11653                pw.println("-------------------------------------------------------------------------------");
11654            }
11655            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11656            pw.println();
11657            if (dumpAll) {
11658                pw.println("-------------------------------------------------------------------------------");
11659            }
11660            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11661        }
11662        Binder.restoreCallingIdentity(origId);
11663    }
11664
11665    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11666            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11667        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11668
11669        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11670                dumpPackage);
11671        boolean needSep = printedAnything;
11672
11673        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11674                dumpPackage, needSep, "  mFocusedActivity: ");
11675        if (printed) {
11676            printedAnything = true;
11677            needSep = false;
11678        }
11679
11680        if (dumpPackage == null) {
11681            if (needSep) {
11682                pw.println();
11683            }
11684            needSep = true;
11685            printedAnything = true;
11686            mStackSupervisor.dump(pw, "  ");
11687        }
11688
11689        if (!printedAnything) {
11690            pw.println("  (nothing)");
11691        }
11692    }
11693
11694    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11695            int opti, boolean dumpAll, String dumpPackage) {
11696        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
11697
11698        boolean printedAnything = false;
11699
11700        if (mRecentTasks.size() > 0) {
11701            boolean printedHeader = false;
11702
11703            final int N = mRecentTasks.size();
11704            for (int i=0; i<N; i++) {
11705                TaskRecord tr = mRecentTasks.get(i);
11706                if (dumpPackage != null) {
11707                    if (tr.realActivity == null ||
11708                            !dumpPackage.equals(tr.realActivity)) {
11709                        continue;
11710                    }
11711                }
11712                if (!printedHeader) {
11713                    pw.println("  Recent tasks:");
11714                    printedHeader = true;
11715                    printedAnything = true;
11716                }
11717                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11718                        pw.println(tr);
11719                if (dumpAll) {
11720                    mRecentTasks.get(i).dump(pw, "    ");
11721                }
11722            }
11723        }
11724
11725        if (!printedAnything) {
11726            pw.println("  (nothing)");
11727        }
11728    }
11729
11730    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11731            int opti, boolean dumpAll, String dumpPackage) {
11732        boolean needSep = false;
11733        boolean printedAnything = false;
11734        int numPers = 0;
11735
11736        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11737
11738        if (dumpAll) {
11739            final int NP = mProcessNames.getMap().size();
11740            for (int ip=0; ip<NP; ip++) {
11741                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11742                final int NA = procs.size();
11743                for (int ia=0; ia<NA; ia++) {
11744                    ProcessRecord r = procs.valueAt(ia);
11745                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11746                        continue;
11747                    }
11748                    if (!needSep) {
11749                        pw.println("  All known processes:");
11750                        needSep = true;
11751                        printedAnything = true;
11752                    }
11753                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11754                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11755                        pw.print(" "); pw.println(r);
11756                    r.dump(pw, "    ");
11757                    if (r.persistent) {
11758                        numPers++;
11759                    }
11760                }
11761            }
11762        }
11763
11764        if (mIsolatedProcesses.size() > 0) {
11765            boolean printed = false;
11766            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11767                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11768                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11769                    continue;
11770                }
11771                if (!printed) {
11772                    if (needSep) {
11773                        pw.println();
11774                    }
11775                    pw.println("  Isolated process list (sorted by uid):");
11776                    printedAnything = true;
11777                    printed = true;
11778                    needSep = true;
11779                }
11780                pw.println(String.format("%sIsolated #%2d: %s",
11781                        "    ", i, r.toString()));
11782            }
11783        }
11784
11785        if (mLruProcesses.size() > 0) {
11786            if (needSep) {
11787                pw.println();
11788            }
11789            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11790                    pw.print(" total, non-act at ");
11791                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11792                    pw.print(", non-svc at ");
11793                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11794                    pw.println("):");
11795            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11796            needSep = true;
11797            printedAnything = true;
11798        }
11799
11800        if (dumpAll || dumpPackage != null) {
11801            synchronized (mPidsSelfLocked) {
11802                boolean printed = false;
11803                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11804                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11805                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11806                        continue;
11807                    }
11808                    if (!printed) {
11809                        if (needSep) pw.println();
11810                        needSep = true;
11811                        pw.println("  PID mappings:");
11812                        printed = true;
11813                        printedAnything = true;
11814                    }
11815                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11816                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11817                }
11818            }
11819        }
11820
11821        if (mForegroundProcesses.size() > 0) {
11822            synchronized (mPidsSelfLocked) {
11823                boolean printed = false;
11824                for (int i=0; i<mForegroundProcesses.size(); i++) {
11825                    ProcessRecord r = mPidsSelfLocked.get(
11826                            mForegroundProcesses.valueAt(i).pid);
11827                    if (dumpPackage != null && (r == null
11828                            || !r.pkgList.containsKey(dumpPackage))) {
11829                        continue;
11830                    }
11831                    if (!printed) {
11832                        if (needSep) pw.println();
11833                        needSep = true;
11834                        pw.println("  Foreground Processes:");
11835                        printed = true;
11836                        printedAnything = true;
11837                    }
11838                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11839                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11840                }
11841            }
11842        }
11843
11844        if (mPersistentStartingProcesses.size() > 0) {
11845            if (needSep) pw.println();
11846            needSep = true;
11847            printedAnything = true;
11848            pw.println("  Persisent processes that are starting:");
11849            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11850                    "Starting Norm", "Restarting PERS", dumpPackage);
11851        }
11852
11853        if (mRemovedProcesses.size() > 0) {
11854            if (needSep) pw.println();
11855            needSep = true;
11856            printedAnything = true;
11857            pw.println("  Processes that are being removed:");
11858            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11859                    "Removed Norm", "Removed PERS", dumpPackage);
11860        }
11861
11862        if (mProcessesOnHold.size() > 0) {
11863            if (needSep) pw.println();
11864            needSep = true;
11865            printedAnything = true;
11866            pw.println("  Processes that are on old until the system is ready:");
11867            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11868                    "OnHold Norm", "OnHold PERS", dumpPackage);
11869        }
11870
11871        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11872
11873        if (mProcessCrashTimes.getMap().size() > 0) {
11874            boolean printed = false;
11875            long now = SystemClock.uptimeMillis();
11876            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11877            final int NP = pmap.size();
11878            for (int ip=0; ip<NP; ip++) {
11879                String pname = pmap.keyAt(ip);
11880                SparseArray<Long> uids = pmap.valueAt(ip);
11881                final int N = uids.size();
11882                for (int i=0; i<N; i++) {
11883                    int puid = uids.keyAt(i);
11884                    ProcessRecord r = mProcessNames.get(pname, puid);
11885                    if (dumpPackage != null && (r == null
11886                            || !r.pkgList.containsKey(dumpPackage))) {
11887                        continue;
11888                    }
11889                    if (!printed) {
11890                        if (needSep) pw.println();
11891                        needSep = true;
11892                        pw.println("  Time since processes crashed:");
11893                        printed = true;
11894                        printedAnything = true;
11895                    }
11896                    pw.print("    Process "); pw.print(pname);
11897                            pw.print(" uid "); pw.print(puid);
11898                            pw.print(": last crashed ");
11899                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11900                            pw.println(" ago");
11901                }
11902            }
11903        }
11904
11905        if (mBadProcesses.getMap().size() > 0) {
11906            boolean printed = false;
11907            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11908            final int NP = pmap.size();
11909            for (int ip=0; ip<NP; ip++) {
11910                String pname = pmap.keyAt(ip);
11911                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11912                final int N = uids.size();
11913                for (int i=0; i<N; i++) {
11914                    int puid = uids.keyAt(i);
11915                    ProcessRecord r = mProcessNames.get(pname, puid);
11916                    if (dumpPackage != null && (r == null
11917                            || !r.pkgList.containsKey(dumpPackage))) {
11918                        continue;
11919                    }
11920                    if (!printed) {
11921                        if (needSep) pw.println();
11922                        needSep = true;
11923                        pw.println("  Bad processes:");
11924                        printedAnything = true;
11925                    }
11926                    BadProcessInfo info = uids.valueAt(i);
11927                    pw.print("    Bad process "); pw.print(pname);
11928                            pw.print(" uid "); pw.print(puid);
11929                            pw.print(": crashed at time "); pw.println(info.time);
11930                    if (info.shortMsg != null) {
11931                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11932                    }
11933                    if (info.longMsg != null) {
11934                        pw.print("      Long msg: "); pw.println(info.longMsg);
11935                    }
11936                    if (info.stack != null) {
11937                        pw.println("      Stack:");
11938                        int lastPos = 0;
11939                        for (int pos=0; pos<info.stack.length(); pos++) {
11940                            if (info.stack.charAt(pos) == '\n') {
11941                                pw.print("        ");
11942                                pw.write(info.stack, lastPos, pos-lastPos);
11943                                pw.println();
11944                                lastPos = pos+1;
11945                            }
11946                        }
11947                        if (lastPos < info.stack.length()) {
11948                            pw.print("        ");
11949                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11950                            pw.println();
11951                        }
11952                    }
11953                }
11954            }
11955        }
11956
11957        if (dumpPackage == null) {
11958            pw.println();
11959            needSep = false;
11960            pw.println("  mStartedUsers:");
11961            for (int i=0; i<mStartedUsers.size(); i++) {
11962                UserStartedState uss = mStartedUsers.valueAt(i);
11963                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11964                        pw.print(": "); uss.dump("", pw);
11965            }
11966            pw.print("  mStartedUserArray: [");
11967            for (int i=0; i<mStartedUserArray.length; i++) {
11968                if (i > 0) pw.print(", ");
11969                pw.print(mStartedUserArray[i]);
11970            }
11971            pw.println("]");
11972            pw.print("  mUserLru: [");
11973            for (int i=0; i<mUserLru.size(); i++) {
11974                if (i > 0) pw.print(", ");
11975                pw.print(mUserLru.get(i));
11976            }
11977            pw.println("]");
11978            if (dumpAll) {
11979                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11980            }
11981            synchronized (mUserProfileGroupIdsSelfLocked) {
11982                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11983                    pw.println("  mUserProfileGroupIds:");
11984                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11985                        pw.print("    User #");
11986                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11987                        pw.print(" -> profile #");
11988                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11989                    }
11990                }
11991            }
11992        }
11993        if (mHomeProcess != null && (dumpPackage == null
11994                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11995            if (needSep) {
11996                pw.println();
11997                needSep = false;
11998            }
11999            pw.println("  mHomeProcess: " + mHomeProcess);
12000        }
12001        if (mPreviousProcess != null && (dumpPackage == null
12002                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12003            if (needSep) {
12004                pw.println();
12005                needSep = false;
12006            }
12007            pw.println("  mPreviousProcess: " + mPreviousProcess);
12008        }
12009        if (dumpAll) {
12010            StringBuilder sb = new StringBuilder(128);
12011            sb.append("  mPreviousProcessVisibleTime: ");
12012            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12013            pw.println(sb);
12014        }
12015        if (mHeavyWeightProcess != null && (dumpPackage == null
12016                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12017            if (needSep) {
12018                pw.println();
12019                needSep = false;
12020            }
12021            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12022        }
12023        if (dumpPackage == null) {
12024            pw.println("  mConfiguration: " + mConfiguration);
12025        }
12026        if (dumpAll) {
12027            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12028            if (mCompatModePackages.getPackages().size() > 0) {
12029                boolean printed = false;
12030                for (Map.Entry<String, Integer> entry
12031                        : mCompatModePackages.getPackages().entrySet()) {
12032                    String pkg = entry.getKey();
12033                    int mode = entry.getValue();
12034                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12035                        continue;
12036                    }
12037                    if (!printed) {
12038                        pw.println("  mScreenCompatPackages:");
12039                        printed = true;
12040                    }
12041                    pw.print("    "); pw.print(pkg); pw.print(": ");
12042                            pw.print(mode); pw.println();
12043                }
12044            }
12045        }
12046        if (dumpPackage == null) {
12047            if (mSleeping || mWentToSleep || mLockScreenShown) {
12048                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12049                        + " mLockScreenShown " + mLockScreenShown);
12050            }
12051            if (mShuttingDown || mRunningVoice) {
12052                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12053            }
12054        }
12055        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12056                || mOrigWaitForDebugger) {
12057            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12058                    || dumpPackage.equals(mOrigDebugApp)) {
12059                if (needSep) {
12060                    pw.println();
12061                    needSep = false;
12062                }
12063                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12064                        + " mDebugTransient=" + mDebugTransient
12065                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12066            }
12067        }
12068        if (mOpenGlTraceApp != null) {
12069            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12070                if (needSep) {
12071                    pw.println();
12072                    needSep = false;
12073                }
12074                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12075            }
12076        }
12077        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12078                || mProfileFd != null) {
12079            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12080                if (needSep) {
12081                    pw.println();
12082                    needSep = false;
12083                }
12084                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12085                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12086                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
12087                        + mAutoStopProfiler);
12088            }
12089        }
12090        if (dumpPackage == null) {
12091            if (mAlwaysFinishActivities || mController != null) {
12092                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12093                        + " mController=" + mController);
12094            }
12095            if (dumpAll) {
12096                pw.println("  Total persistent processes: " + numPers);
12097                pw.println("  mProcessesReady=" + mProcessesReady
12098                        + " mSystemReady=" + mSystemReady);
12099                pw.println("  mBooting=" + mBooting
12100                        + " mBooted=" + mBooted
12101                        + " mFactoryTest=" + mFactoryTest);
12102                pw.print("  mLastPowerCheckRealtime=");
12103                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12104                        pw.println("");
12105                pw.print("  mLastPowerCheckUptime=");
12106                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12107                        pw.println("");
12108                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12109                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12110                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12111                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12112                        + " (" + mLruProcesses.size() + " total)"
12113                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12114                        + " mNumServiceProcs=" + mNumServiceProcs
12115                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12116                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12117                        + " mLastMemoryLevel" + mLastMemoryLevel
12118                        + " mLastNumProcesses" + mLastNumProcesses);
12119                long now = SystemClock.uptimeMillis();
12120                pw.print("  mLastIdleTime=");
12121                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12122                        pw.print(" mLowRamSinceLastIdle=");
12123                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12124                        pw.println();
12125            }
12126        }
12127
12128        if (!printedAnything) {
12129            pw.println("  (nothing)");
12130        }
12131    }
12132
12133    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12134            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12135        if (mProcessesToGc.size() > 0) {
12136            boolean printed = false;
12137            long now = SystemClock.uptimeMillis();
12138            for (int i=0; i<mProcessesToGc.size(); i++) {
12139                ProcessRecord proc = mProcessesToGc.get(i);
12140                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12141                    continue;
12142                }
12143                if (!printed) {
12144                    if (needSep) pw.println();
12145                    needSep = true;
12146                    pw.println("  Processes that are waiting to GC:");
12147                    printed = true;
12148                }
12149                pw.print("    Process "); pw.println(proc);
12150                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12151                        pw.print(", last gced=");
12152                        pw.print(now-proc.lastRequestedGc);
12153                        pw.print(" ms ago, last lowMem=");
12154                        pw.print(now-proc.lastLowMemory);
12155                        pw.println(" ms ago");
12156
12157            }
12158        }
12159        return needSep;
12160    }
12161
12162    void printOomLevel(PrintWriter pw, String name, int adj) {
12163        pw.print("    ");
12164        if (adj >= 0) {
12165            pw.print(' ');
12166            if (adj < 10) pw.print(' ');
12167        } else {
12168            if (adj > -10) pw.print(' ');
12169        }
12170        pw.print(adj);
12171        pw.print(": ");
12172        pw.print(name);
12173        pw.print(" (");
12174        pw.print(mProcessList.getMemLevel(adj)/1024);
12175        pw.println(" kB)");
12176    }
12177
12178    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12179            int opti, boolean dumpAll) {
12180        boolean needSep = false;
12181
12182        if (mLruProcesses.size() > 0) {
12183            if (needSep) pw.println();
12184            needSep = true;
12185            pw.println("  OOM levels:");
12186            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12187            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12188            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12189            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12190            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12191            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12192            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12193            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12194            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12195            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12196            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12197            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12198            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12199
12200            if (needSep) pw.println();
12201            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12202                    pw.print(" total, non-act at ");
12203                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12204                    pw.print(", non-svc at ");
12205                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12206                    pw.println("):");
12207            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12208            needSep = true;
12209        }
12210
12211        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12212
12213        pw.println();
12214        pw.println("  mHomeProcess: " + mHomeProcess);
12215        pw.println("  mPreviousProcess: " + mPreviousProcess);
12216        if (mHeavyWeightProcess != null) {
12217            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12218        }
12219
12220        return true;
12221    }
12222
12223    /**
12224     * There are three ways to call this:
12225     *  - no provider specified: dump all the providers
12226     *  - a flattened component name that matched an existing provider was specified as the
12227     *    first arg: dump that one provider
12228     *  - the first arg isn't the flattened component name of an existing provider:
12229     *    dump all providers whose component contains the first arg as a substring
12230     */
12231    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12232            int opti, boolean dumpAll) {
12233        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12234    }
12235
12236    static class ItemMatcher {
12237        ArrayList<ComponentName> components;
12238        ArrayList<String> strings;
12239        ArrayList<Integer> objects;
12240        boolean all;
12241
12242        ItemMatcher() {
12243            all = true;
12244        }
12245
12246        void build(String name) {
12247            ComponentName componentName = ComponentName.unflattenFromString(name);
12248            if (componentName != null) {
12249                if (components == null) {
12250                    components = new ArrayList<ComponentName>();
12251                }
12252                components.add(componentName);
12253                all = false;
12254            } else {
12255                int objectId = 0;
12256                // Not a '/' separated full component name; maybe an object ID?
12257                try {
12258                    objectId = Integer.parseInt(name, 16);
12259                    if (objects == null) {
12260                        objects = new ArrayList<Integer>();
12261                    }
12262                    objects.add(objectId);
12263                    all = false;
12264                } catch (RuntimeException e) {
12265                    // Not an integer; just do string match.
12266                    if (strings == null) {
12267                        strings = new ArrayList<String>();
12268                    }
12269                    strings.add(name);
12270                    all = false;
12271                }
12272            }
12273        }
12274
12275        int build(String[] args, int opti) {
12276            for (; opti<args.length; opti++) {
12277                String name = args[opti];
12278                if ("--".equals(name)) {
12279                    return opti+1;
12280                }
12281                build(name);
12282            }
12283            return opti;
12284        }
12285
12286        boolean match(Object object, ComponentName comp) {
12287            if (all) {
12288                return true;
12289            }
12290            if (components != null) {
12291                for (int i=0; i<components.size(); i++) {
12292                    if (components.get(i).equals(comp)) {
12293                        return true;
12294                    }
12295                }
12296            }
12297            if (objects != null) {
12298                for (int i=0; i<objects.size(); i++) {
12299                    if (System.identityHashCode(object) == objects.get(i)) {
12300                        return true;
12301                    }
12302                }
12303            }
12304            if (strings != null) {
12305                String flat = comp.flattenToString();
12306                for (int i=0; i<strings.size(); i++) {
12307                    if (flat.contains(strings.get(i))) {
12308                        return true;
12309                    }
12310                }
12311            }
12312            return false;
12313        }
12314    }
12315
12316    /**
12317     * There are three things that cmd can be:
12318     *  - a flattened component name that matches an existing activity
12319     *  - the cmd arg isn't the flattened component name of an existing activity:
12320     *    dump all activity whose component contains the cmd as a substring
12321     *  - A hex number of the ActivityRecord object instance.
12322     */
12323    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12324            int opti, boolean dumpAll) {
12325        ArrayList<ActivityRecord> activities;
12326
12327        synchronized (this) {
12328            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12329        }
12330
12331        if (activities.size() <= 0) {
12332            return false;
12333        }
12334
12335        String[] newArgs = new String[args.length - opti];
12336        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12337
12338        TaskRecord lastTask = null;
12339        boolean needSep = false;
12340        for (int i=activities.size()-1; i>=0; i--) {
12341            ActivityRecord r = activities.get(i);
12342            if (needSep) {
12343                pw.println();
12344            }
12345            needSep = true;
12346            synchronized (this) {
12347                if (lastTask != r.task) {
12348                    lastTask = r.task;
12349                    pw.print("TASK "); pw.print(lastTask.affinity);
12350                            pw.print(" id="); pw.println(lastTask.taskId);
12351                    if (dumpAll) {
12352                        lastTask.dump(pw, "  ");
12353                    }
12354                }
12355            }
12356            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12357        }
12358        return true;
12359    }
12360
12361    /**
12362     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12363     * there is a thread associated with the activity.
12364     */
12365    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12366            final ActivityRecord r, String[] args, boolean dumpAll) {
12367        String innerPrefix = prefix + "  ";
12368        synchronized (this) {
12369            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12370                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12371                    pw.print(" pid=");
12372                    if (r.app != null) pw.println(r.app.pid);
12373                    else pw.println("(not running)");
12374            if (dumpAll) {
12375                r.dump(pw, innerPrefix);
12376            }
12377        }
12378        if (r.app != null && r.app.thread != null) {
12379            // flush anything that is already in the PrintWriter since the thread is going
12380            // to write to the file descriptor directly
12381            pw.flush();
12382            try {
12383                TransferPipe tp = new TransferPipe();
12384                try {
12385                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12386                            r.appToken, innerPrefix, args);
12387                    tp.go(fd);
12388                } finally {
12389                    tp.kill();
12390                }
12391            } catch (IOException e) {
12392                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12393            } catch (RemoteException e) {
12394                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12395            }
12396        }
12397    }
12398
12399    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12400            int opti, boolean dumpAll, String dumpPackage) {
12401        boolean needSep = false;
12402        boolean onlyHistory = false;
12403        boolean printedAnything = false;
12404
12405        if ("history".equals(dumpPackage)) {
12406            if (opti < args.length && "-s".equals(args[opti])) {
12407                dumpAll = false;
12408            }
12409            onlyHistory = true;
12410            dumpPackage = null;
12411        }
12412
12413        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12414        if (!onlyHistory && dumpAll) {
12415            if (mRegisteredReceivers.size() > 0) {
12416                boolean printed = false;
12417                Iterator it = mRegisteredReceivers.values().iterator();
12418                while (it.hasNext()) {
12419                    ReceiverList r = (ReceiverList)it.next();
12420                    if (dumpPackage != null && (r.app == null ||
12421                            !dumpPackage.equals(r.app.info.packageName))) {
12422                        continue;
12423                    }
12424                    if (!printed) {
12425                        pw.println("  Registered Receivers:");
12426                        needSep = true;
12427                        printed = true;
12428                        printedAnything = true;
12429                    }
12430                    pw.print("  * "); pw.println(r);
12431                    r.dump(pw, "    ");
12432                }
12433            }
12434
12435            if (mReceiverResolver.dump(pw, needSep ?
12436                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12437                    "    ", dumpPackage, false)) {
12438                needSep = true;
12439                printedAnything = true;
12440            }
12441        }
12442
12443        for (BroadcastQueue q : mBroadcastQueues) {
12444            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12445            printedAnything |= needSep;
12446        }
12447
12448        needSep = true;
12449
12450        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12451            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12452                if (needSep) {
12453                    pw.println();
12454                }
12455                needSep = true;
12456                printedAnything = true;
12457                pw.print("  Sticky broadcasts for user ");
12458                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12459                StringBuilder sb = new StringBuilder(128);
12460                for (Map.Entry<String, ArrayList<Intent>> ent
12461                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12462                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12463                    if (dumpAll) {
12464                        pw.println(":");
12465                        ArrayList<Intent> intents = ent.getValue();
12466                        final int N = intents.size();
12467                        for (int i=0; i<N; i++) {
12468                            sb.setLength(0);
12469                            sb.append("    Intent: ");
12470                            intents.get(i).toShortString(sb, false, true, false, false);
12471                            pw.println(sb.toString());
12472                            Bundle bundle = intents.get(i).getExtras();
12473                            if (bundle != null) {
12474                                pw.print("      ");
12475                                pw.println(bundle.toString());
12476                            }
12477                        }
12478                    } else {
12479                        pw.println("");
12480                    }
12481                }
12482            }
12483        }
12484
12485        if (!onlyHistory && dumpAll) {
12486            pw.println();
12487            for (BroadcastQueue queue : mBroadcastQueues) {
12488                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12489                        + queue.mBroadcastsScheduled);
12490            }
12491            pw.println("  mHandler:");
12492            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12493            needSep = true;
12494            printedAnything = true;
12495        }
12496
12497        if (!printedAnything) {
12498            pw.println("  (nothing)");
12499        }
12500    }
12501
12502    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12503            int opti, boolean dumpAll, String dumpPackage) {
12504        boolean needSep;
12505        boolean printedAnything = false;
12506
12507        ItemMatcher matcher = new ItemMatcher();
12508        matcher.build(args, opti);
12509
12510        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12511
12512        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12513        printedAnything |= needSep;
12514
12515        if (mLaunchingProviders.size() > 0) {
12516            boolean printed = false;
12517            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12518                ContentProviderRecord r = mLaunchingProviders.get(i);
12519                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12520                    continue;
12521                }
12522                if (!printed) {
12523                    if (needSep) pw.println();
12524                    needSep = true;
12525                    pw.println("  Launching content providers:");
12526                    printed = true;
12527                    printedAnything = true;
12528                }
12529                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12530                        pw.println(r);
12531            }
12532        }
12533
12534        if (mGrantedUriPermissions.size() > 0) {
12535            boolean printed = false;
12536            int dumpUid = -2;
12537            if (dumpPackage != null) {
12538                try {
12539                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12540                } catch (NameNotFoundException e) {
12541                    dumpUid = -1;
12542                }
12543            }
12544            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12545                int uid = mGrantedUriPermissions.keyAt(i);
12546                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12547                    continue;
12548                }
12549                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12550                if (!printed) {
12551                    if (needSep) pw.println();
12552                    needSep = true;
12553                    pw.println("  Granted Uri Permissions:");
12554                    printed = true;
12555                    printedAnything = true;
12556                }
12557                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12558                for (UriPermission perm : perms.values()) {
12559                    pw.print("    "); pw.println(perm);
12560                    if (dumpAll) {
12561                        perm.dump(pw, "      ");
12562                    }
12563                }
12564            }
12565        }
12566
12567        if (!printedAnything) {
12568            pw.println("  (nothing)");
12569        }
12570    }
12571
12572    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12573            int opti, boolean dumpAll, String dumpPackage) {
12574        boolean printed = false;
12575
12576        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12577
12578        if (mIntentSenderRecords.size() > 0) {
12579            Iterator<WeakReference<PendingIntentRecord>> it
12580                    = mIntentSenderRecords.values().iterator();
12581            while (it.hasNext()) {
12582                WeakReference<PendingIntentRecord> ref = it.next();
12583                PendingIntentRecord rec = ref != null ? ref.get(): null;
12584                if (dumpPackage != null && (rec == null
12585                        || !dumpPackage.equals(rec.key.packageName))) {
12586                    continue;
12587                }
12588                printed = true;
12589                if (rec != null) {
12590                    pw.print("  * "); pw.println(rec);
12591                    if (dumpAll) {
12592                        rec.dump(pw, "    ");
12593                    }
12594                } else {
12595                    pw.print("  * "); pw.println(ref);
12596                }
12597            }
12598        }
12599
12600        if (!printed) {
12601            pw.println("  (nothing)");
12602        }
12603    }
12604
12605    private static final int dumpProcessList(PrintWriter pw,
12606            ActivityManagerService service, List list,
12607            String prefix, String normalLabel, String persistentLabel,
12608            String dumpPackage) {
12609        int numPers = 0;
12610        final int N = list.size()-1;
12611        for (int i=N; i>=0; i--) {
12612            ProcessRecord r = (ProcessRecord)list.get(i);
12613            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12614                continue;
12615            }
12616            pw.println(String.format("%s%s #%2d: %s",
12617                    prefix, (r.persistent ? persistentLabel : normalLabel),
12618                    i, r.toString()));
12619            if (r.persistent) {
12620                numPers++;
12621            }
12622        }
12623        return numPers;
12624    }
12625
12626    private static final boolean dumpProcessOomList(PrintWriter pw,
12627            ActivityManagerService service, List<ProcessRecord> origList,
12628            String prefix, String normalLabel, String persistentLabel,
12629            boolean inclDetails, String dumpPackage) {
12630
12631        ArrayList<Pair<ProcessRecord, Integer>> list
12632                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12633        for (int i=0; i<origList.size(); i++) {
12634            ProcessRecord r = origList.get(i);
12635            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12636                continue;
12637            }
12638            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12639        }
12640
12641        if (list.size() <= 0) {
12642            return false;
12643        }
12644
12645        Comparator<Pair<ProcessRecord, Integer>> comparator
12646                = new Comparator<Pair<ProcessRecord, Integer>>() {
12647            @Override
12648            public int compare(Pair<ProcessRecord, Integer> object1,
12649                    Pair<ProcessRecord, Integer> object2) {
12650                if (object1.first.setAdj != object2.first.setAdj) {
12651                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12652                }
12653                if (object1.second.intValue() != object2.second.intValue()) {
12654                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12655                }
12656                return 0;
12657            }
12658        };
12659
12660        Collections.sort(list, comparator);
12661
12662        final long curRealtime = SystemClock.elapsedRealtime();
12663        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12664        final long curUptime = SystemClock.uptimeMillis();
12665        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12666
12667        for (int i=list.size()-1; i>=0; i--) {
12668            ProcessRecord r = list.get(i).first;
12669            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12670            char schedGroup;
12671            switch (r.setSchedGroup) {
12672                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12673                    schedGroup = 'B';
12674                    break;
12675                case Process.THREAD_GROUP_DEFAULT:
12676                    schedGroup = 'F';
12677                    break;
12678                default:
12679                    schedGroup = '?';
12680                    break;
12681            }
12682            char foreground;
12683            if (r.foregroundActivities) {
12684                foreground = 'A';
12685            } else if (r.foregroundServices) {
12686                foreground = 'S';
12687            } else {
12688                foreground = ' ';
12689            }
12690            String procState = ProcessList.makeProcStateString(r.curProcState);
12691            pw.print(prefix);
12692            pw.print(r.persistent ? persistentLabel : normalLabel);
12693            pw.print(" #");
12694            int num = (origList.size()-1)-list.get(i).second;
12695            if (num < 10) pw.print(' ');
12696            pw.print(num);
12697            pw.print(": ");
12698            pw.print(oomAdj);
12699            pw.print(' ');
12700            pw.print(schedGroup);
12701            pw.print('/');
12702            pw.print(foreground);
12703            pw.print('/');
12704            pw.print(procState);
12705            pw.print(" trm:");
12706            if (r.trimMemoryLevel < 10) pw.print(' ');
12707            pw.print(r.trimMemoryLevel);
12708            pw.print(' ');
12709            pw.print(r.toShortString());
12710            pw.print(" (");
12711            pw.print(r.adjType);
12712            pw.println(')');
12713            if (r.adjSource != null || r.adjTarget != null) {
12714                pw.print(prefix);
12715                pw.print("    ");
12716                if (r.adjTarget instanceof ComponentName) {
12717                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12718                } else if (r.adjTarget != null) {
12719                    pw.print(r.adjTarget.toString());
12720                } else {
12721                    pw.print("{null}");
12722                }
12723                pw.print("<=");
12724                if (r.adjSource instanceof ProcessRecord) {
12725                    pw.print("Proc{");
12726                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12727                    pw.println("}");
12728                } else if (r.adjSource != null) {
12729                    pw.println(r.adjSource.toString());
12730                } else {
12731                    pw.println("{null}");
12732                }
12733            }
12734            if (inclDetails) {
12735                pw.print(prefix);
12736                pw.print("    ");
12737                pw.print("oom: max="); pw.print(r.maxAdj);
12738                pw.print(" curRaw="); pw.print(r.curRawAdj);
12739                pw.print(" setRaw="); pw.print(r.setRawAdj);
12740                pw.print(" cur="); pw.print(r.curAdj);
12741                pw.print(" set="); pw.println(r.setAdj);
12742                pw.print(prefix);
12743                pw.print("    ");
12744                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12745                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12746                pw.print(" lastPss="); pw.print(r.lastPss);
12747                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12748                pw.print(prefix);
12749                pw.print("    ");
12750                pw.print("cached="); pw.print(r.cached);
12751                pw.print(" empty="); pw.print(r.empty);
12752                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12753
12754                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12755                    if (r.lastWakeTime != 0) {
12756                        long wtime;
12757                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12758                        synchronized (stats) {
12759                            wtime = stats.getProcessWakeTime(r.info.uid,
12760                                    r.pid, curRealtime);
12761                        }
12762                        long timeUsed = wtime - r.lastWakeTime;
12763                        pw.print(prefix);
12764                        pw.print("    ");
12765                        pw.print("keep awake over ");
12766                        TimeUtils.formatDuration(realtimeSince, pw);
12767                        pw.print(" used ");
12768                        TimeUtils.formatDuration(timeUsed, pw);
12769                        pw.print(" (");
12770                        pw.print((timeUsed*100)/realtimeSince);
12771                        pw.println("%)");
12772                    }
12773                    if (r.lastCpuTime != 0) {
12774                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12775                        pw.print(prefix);
12776                        pw.print("    ");
12777                        pw.print("run cpu over ");
12778                        TimeUtils.formatDuration(uptimeSince, pw);
12779                        pw.print(" used ");
12780                        TimeUtils.formatDuration(timeUsed, pw);
12781                        pw.print(" (");
12782                        pw.print((timeUsed*100)/uptimeSince);
12783                        pw.println("%)");
12784                    }
12785                }
12786            }
12787        }
12788        return true;
12789    }
12790
12791    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12792        ArrayList<ProcessRecord> procs;
12793        synchronized (this) {
12794            if (args != null && args.length > start
12795                    && args[start].charAt(0) != '-') {
12796                procs = new ArrayList<ProcessRecord>();
12797                int pid = -1;
12798                try {
12799                    pid = Integer.parseInt(args[start]);
12800                } catch (NumberFormatException e) {
12801                }
12802                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12803                    ProcessRecord proc = mLruProcesses.get(i);
12804                    if (proc.pid == pid) {
12805                        procs.add(proc);
12806                    } else if (proc.processName.equals(args[start])) {
12807                        procs.add(proc);
12808                    }
12809                }
12810                if (procs.size() <= 0) {
12811                    return null;
12812                }
12813            } else {
12814                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12815            }
12816        }
12817        return procs;
12818    }
12819
12820    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12821            PrintWriter pw, String[] args) {
12822        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12823        if (procs == null) {
12824            pw.println("No process found for: " + args[0]);
12825            return;
12826        }
12827
12828        long uptime = SystemClock.uptimeMillis();
12829        long realtime = SystemClock.elapsedRealtime();
12830        pw.println("Applications Graphics Acceleration Info:");
12831        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12832
12833        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12834            ProcessRecord r = procs.get(i);
12835            if (r.thread != null) {
12836                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12837                pw.flush();
12838                try {
12839                    TransferPipe tp = new TransferPipe();
12840                    try {
12841                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12842                        tp.go(fd);
12843                    } finally {
12844                        tp.kill();
12845                    }
12846                } catch (IOException e) {
12847                    pw.println("Failure while dumping the app: " + r);
12848                    pw.flush();
12849                } catch (RemoteException e) {
12850                    pw.println("Got a RemoteException while dumping the app " + r);
12851                    pw.flush();
12852                }
12853            }
12854        }
12855    }
12856
12857    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12858        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12859        if (procs == null) {
12860            pw.println("No process found for: " + args[0]);
12861            return;
12862        }
12863
12864        pw.println("Applications Database Info:");
12865
12866        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12867            ProcessRecord r = procs.get(i);
12868            if (r.thread != null) {
12869                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12870                pw.flush();
12871                try {
12872                    TransferPipe tp = new TransferPipe();
12873                    try {
12874                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12875                        tp.go(fd);
12876                    } finally {
12877                        tp.kill();
12878                    }
12879                } catch (IOException e) {
12880                    pw.println("Failure while dumping the app: " + r);
12881                    pw.flush();
12882                } catch (RemoteException e) {
12883                    pw.println("Got a RemoteException while dumping the app " + r);
12884                    pw.flush();
12885                }
12886            }
12887        }
12888    }
12889
12890    final static class MemItem {
12891        final boolean isProc;
12892        final String label;
12893        final String shortLabel;
12894        final long pss;
12895        final int id;
12896        final boolean hasActivities;
12897        ArrayList<MemItem> subitems;
12898
12899        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12900                boolean _hasActivities) {
12901            isProc = true;
12902            label = _label;
12903            shortLabel = _shortLabel;
12904            pss = _pss;
12905            id = _id;
12906            hasActivities = _hasActivities;
12907        }
12908
12909        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12910            isProc = false;
12911            label = _label;
12912            shortLabel = _shortLabel;
12913            pss = _pss;
12914            id = _id;
12915            hasActivities = false;
12916        }
12917    }
12918
12919    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12920            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12921        if (sort && !isCompact) {
12922            Collections.sort(items, new Comparator<MemItem>() {
12923                @Override
12924                public int compare(MemItem lhs, MemItem rhs) {
12925                    if (lhs.pss < rhs.pss) {
12926                        return 1;
12927                    } else if (lhs.pss > rhs.pss) {
12928                        return -1;
12929                    }
12930                    return 0;
12931                }
12932            });
12933        }
12934
12935        for (int i=0; i<items.size(); i++) {
12936            MemItem mi = items.get(i);
12937            if (!isCompact) {
12938                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12939            } else if (mi.isProc) {
12940                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12941                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12942                pw.println(mi.hasActivities ? ",a" : ",e");
12943            } else {
12944                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12945                pw.println(mi.pss);
12946            }
12947            if (mi.subitems != null) {
12948                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12949                        true, isCompact);
12950            }
12951        }
12952    }
12953
12954    // These are in KB.
12955    static final long[] DUMP_MEM_BUCKETS = new long[] {
12956        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12957        120*1024, 160*1024, 200*1024,
12958        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12959        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12960    };
12961
12962    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12963            boolean stackLike) {
12964        int start = label.lastIndexOf('.');
12965        if (start >= 0) start++;
12966        else start = 0;
12967        int end = label.length();
12968        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12969            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12970                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12971                out.append(bucket);
12972                out.append(stackLike ? "MB." : "MB ");
12973                out.append(label, start, end);
12974                return;
12975            }
12976        }
12977        out.append(memKB/1024);
12978        out.append(stackLike ? "MB." : "MB ");
12979        out.append(label, start, end);
12980    }
12981
12982    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12983            ProcessList.NATIVE_ADJ,
12984            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12985            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12986            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12987            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12988            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12989    };
12990    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12991            "Native",
12992            "System", "Persistent", "Foreground",
12993            "Visible", "Perceptible",
12994            "Heavy Weight", "Backup",
12995            "A Services", "Home",
12996            "Previous", "B Services", "Cached"
12997    };
12998    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12999            "native",
13000            "sys", "pers", "fore",
13001            "vis", "percept",
13002            "heavy", "backup",
13003            "servicea", "home",
13004            "prev", "serviceb", "cached"
13005    };
13006
13007    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13008            long realtime, boolean isCheckinRequest, boolean isCompact) {
13009        if (isCheckinRequest || isCompact) {
13010            // short checkin version
13011            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13012        } else {
13013            pw.println("Applications Memory Usage (kB):");
13014            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13015        }
13016    }
13017
13018    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13019            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13020        boolean dumpDetails = false;
13021        boolean dumpFullDetails = false;
13022        boolean dumpDalvik = false;
13023        boolean oomOnly = false;
13024        boolean isCompact = false;
13025        boolean localOnly = false;
13026
13027        int opti = 0;
13028        while (opti < args.length) {
13029            String opt = args[opti];
13030            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13031                break;
13032            }
13033            opti++;
13034            if ("-a".equals(opt)) {
13035                dumpDetails = true;
13036                dumpFullDetails = true;
13037                dumpDalvik = true;
13038            } else if ("-d".equals(opt)) {
13039                dumpDalvik = true;
13040            } else if ("-c".equals(opt)) {
13041                isCompact = true;
13042            } else if ("--oom".equals(opt)) {
13043                oomOnly = true;
13044            } else if ("--local".equals(opt)) {
13045                localOnly = true;
13046            } else if ("-h".equals(opt)) {
13047                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13048                pw.println("  -a: include all available information for each process.");
13049                pw.println("  -d: include dalvik details when dumping process details.");
13050                pw.println("  -c: dump in a compact machine-parseable representation.");
13051                pw.println("  --oom: only show processes organized by oom adj.");
13052                pw.println("  --local: only collect details locally, don't call process.");
13053                pw.println("If [process] is specified it can be the name or ");
13054                pw.println("pid of a specific process to dump.");
13055                return;
13056            } else {
13057                pw.println("Unknown argument: " + opt + "; use -h for help");
13058            }
13059        }
13060
13061        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13062        long uptime = SystemClock.uptimeMillis();
13063        long realtime = SystemClock.elapsedRealtime();
13064        final long[] tmpLong = new long[1];
13065
13066        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13067        if (procs == null) {
13068            // No Java processes.  Maybe they want to print a native process.
13069            if (args != null && args.length > opti
13070                    && args[opti].charAt(0) != '-') {
13071                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13072                        = new ArrayList<ProcessCpuTracker.Stats>();
13073                updateCpuStatsNow();
13074                int findPid = -1;
13075                try {
13076                    findPid = Integer.parseInt(args[opti]);
13077                } catch (NumberFormatException e) {
13078                }
13079                synchronized (mProcessCpuThread) {
13080                    final int N = mProcessCpuTracker.countStats();
13081                    for (int i=0; i<N; i++) {
13082                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13083                        if (st.pid == findPid || (st.baseName != null
13084                                && st.baseName.equals(args[opti]))) {
13085                            nativeProcs.add(st);
13086                        }
13087                    }
13088                }
13089                if (nativeProcs.size() > 0) {
13090                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13091                            isCompact);
13092                    Debug.MemoryInfo mi = null;
13093                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13094                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13095                        final int pid = r.pid;
13096                        if (!isCheckinRequest && dumpDetails) {
13097                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13098                        }
13099                        if (mi == null) {
13100                            mi = new Debug.MemoryInfo();
13101                        }
13102                        if (dumpDetails || (!brief && !oomOnly)) {
13103                            Debug.getMemoryInfo(pid, mi);
13104                        } else {
13105                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13106                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13107                        }
13108                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13109                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13110                        if (isCheckinRequest) {
13111                            pw.println();
13112                        }
13113                    }
13114                    return;
13115                }
13116            }
13117            pw.println("No process found for: " + args[opti]);
13118            return;
13119        }
13120
13121        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13122            dumpDetails = true;
13123        }
13124
13125        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13126
13127        String[] innerArgs = new String[args.length-opti];
13128        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13129
13130        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13131        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13132        long nativePss=0, dalvikPss=0, otherPss=0;
13133        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13134
13135        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13136        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13137                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13138
13139        long totalPss = 0;
13140        long cachedPss = 0;
13141
13142        Debug.MemoryInfo mi = null;
13143        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13144            final ProcessRecord r = procs.get(i);
13145            final IApplicationThread thread;
13146            final int pid;
13147            final int oomAdj;
13148            final boolean hasActivities;
13149            synchronized (this) {
13150                thread = r.thread;
13151                pid = r.pid;
13152                oomAdj = r.getSetAdjWithServices();
13153                hasActivities = r.activities.size() > 0;
13154            }
13155            if (thread != null) {
13156                if (!isCheckinRequest && dumpDetails) {
13157                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13158                }
13159                if (mi == null) {
13160                    mi = new Debug.MemoryInfo();
13161                }
13162                if (dumpDetails || (!brief && !oomOnly)) {
13163                    Debug.getMemoryInfo(pid, mi);
13164                } else {
13165                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13166                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13167                }
13168                if (dumpDetails) {
13169                    if (localOnly) {
13170                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13171                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13172                        if (isCheckinRequest) {
13173                            pw.println();
13174                        }
13175                    } else {
13176                        try {
13177                            pw.flush();
13178                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13179                                    dumpDalvik, innerArgs);
13180                        } catch (RemoteException e) {
13181                            if (!isCheckinRequest) {
13182                                pw.println("Got RemoteException!");
13183                                pw.flush();
13184                            }
13185                        }
13186                    }
13187                }
13188
13189                final long myTotalPss = mi.getTotalPss();
13190                final long myTotalUss = mi.getTotalUss();
13191
13192                synchronized (this) {
13193                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13194                        // Record this for posterity if the process has been stable.
13195                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13196                    }
13197                }
13198
13199                if (!isCheckinRequest && mi != null) {
13200                    totalPss += myTotalPss;
13201                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13202                            (hasActivities ? " / activities)" : ")"),
13203                            r.processName, myTotalPss, pid, hasActivities);
13204                    procMems.add(pssItem);
13205                    procMemsMap.put(pid, pssItem);
13206
13207                    nativePss += mi.nativePss;
13208                    dalvikPss += mi.dalvikPss;
13209                    otherPss += mi.otherPss;
13210                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13211                        long mem = mi.getOtherPss(j);
13212                        miscPss[j] += mem;
13213                        otherPss -= mem;
13214                    }
13215
13216                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13217                        cachedPss += myTotalPss;
13218                    }
13219
13220                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13221                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13222                                || oomIndex == (oomPss.length-1)) {
13223                            oomPss[oomIndex] += myTotalPss;
13224                            if (oomProcs[oomIndex] == null) {
13225                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13226                            }
13227                            oomProcs[oomIndex].add(pssItem);
13228                            break;
13229                        }
13230                    }
13231                }
13232            }
13233        }
13234
13235        long nativeProcTotalPss = 0;
13236
13237        if (!isCheckinRequest && procs.size() > 1) {
13238            // If we are showing aggregations, also look for native processes to
13239            // include so that our aggregations are more accurate.
13240            updateCpuStatsNow();
13241            synchronized (mProcessCpuThread) {
13242                final int N = mProcessCpuTracker.countStats();
13243                for (int i=0; i<N; i++) {
13244                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13245                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13246                        if (mi == null) {
13247                            mi = new Debug.MemoryInfo();
13248                        }
13249                        if (!brief && !oomOnly) {
13250                            Debug.getMemoryInfo(st.pid, mi);
13251                        } else {
13252                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13253                            mi.nativePrivateDirty = (int)tmpLong[0];
13254                        }
13255
13256                        final long myTotalPss = mi.getTotalPss();
13257                        totalPss += myTotalPss;
13258                        nativeProcTotalPss += myTotalPss;
13259
13260                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13261                                st.name, myTotalPss, st.pid, false);
13262                        procMems.add(pssItem);
13263
13264                        nativePss += mi.nativePss;
13265                        dalvikPss += mi.dalvikPss;
13266                        otherPss += mi.otherPss;
13267                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13268                            long mem = mi.getOtherPss(j);
13269                            miscPss[j] += mem;
13270                            otherPss -= mem;
13271                        }
13272                        oomPss[0] += myTotalPss;
13273                        if (oomProcs[0] == null) {
13274                            oomProcs[0] = new ArrayList<MemItem>();
13275                        }
13276                        oomProcs[0].add(pssItem);
13277                    }
13278                }
13279            }
13280
13281            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13282
13283            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13284            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13285            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13286            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13287                String label = Debug.MemoryInfo.getOtherLabel(j);
13288                catMems.add(new MemItem(label, label, miscPss[j], j));
13289            }
13290
13291            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13292            for (int j=0; j<oomPss.length; j++) {
13293                if (oomPss[j] != 0) {
13294                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13295                            : DUMP_MEM_OOM_LABEL[j];
13296                    MemItem item = new MemItem(label, label, oomPss[j],
13297                            DUMP_MEM_OOM_ADJ[j]);
13298                    item.subitems = oomProcs[j];
13299                    oomMems.add(item);
13300                }
13301            }
13302
13303            if (!brief && !oomOnly && !isCompact) {
13304                pw.println();
13305                pw.println("Total PSS by process:");
13306                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13307                pw.println();
13308            }
13309            if (!isCompact) {
13310                pw.println("Total PSS by OOM adjustment:");
13311            }
13312            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13313            if (!brief && !oomOnly) {
13314                PrintWriter out = categoryPw != null ? categoryPw : pw;
13315                if (!isCompact) {
13316                    out.println();
13317                    out.println("Total PSS by category:");
13318                }
13319                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13320            }
13321            if (!isCompact) {
13322                pw.println();
13323            }
13324            MemInfoReader memInfo = new MemInfoReader();
13325            memInfo.readMemInfo();
13326            if (nativeProcTotalPss > 0) {
13327                synchronized (this) {
13328                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13329                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13330                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13331                            nativeProcTotalPss);
13332                }
13333            }
13334            if (!brief) {
13335                if (!isCompact) {
13336                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13337                    pw.print(" kB (status ");
13338                    switch (mLastMemoryLevel) {
13339                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13340                            pw.println("normal)");
13341                            break;
13342                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13343                            pw.println("moderate)");
13344                            break;
13345                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13346                            pw.println("low)");
13347                            break;
13348                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13349                            pw.println("critical)");
13350                            break;
13351                        default:
13352                            pw.print(mLastMemoryLevel);
13353                            pw.println(")");
13354                            break;
13355                    }
13356                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13357                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13358                            pw.print(cachedPss); pw.print(" cached pss + ");
13359                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13360                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13361                } else {
13362                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13363                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13364                            + memInfo.getFreeSizeKb()); pw.print(",");
13365                    pw.println(totalPss - cachedPss);
13366                }
13367            }
13368            if (!isCompact) {
13369                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13370                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13371                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13372                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13373                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13374                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13375                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13376                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13377                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13378                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13379                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13380            }
13381            if (!brief) {
13382                if (memInfo.getZramTotalSizeKb() != 0) {
13383                    if (!isCompact) {
13384                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13385                                pw.print(" kB physical used for ");
13386                                pw.print(memInfo.getSwapTotalSizeKb()
13387                                        - memInfo.getSwapFreeSizeKb());
13388                                pw.print(" kB in swap (");
13389                                pw.print(memInfo.getSwapTotalSizeKb());
13390                                pw.println(" kB total swap)");
13391                    } else {
13392                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13393                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13394                                pw.println(memInfo.getSwapFreeSizeKb());
13395                    }
13396                }
13397                final int[] SINGLE_LONG_FORMAT = new int[] {
13398                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13399                };
13400                long[] longOut = new long[1];
13401                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13402                        SINGLE_LONG_FORMAT, null, longOut, null);
13403                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13404                longOut[0] = 0;
13405                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13406                        SINGLE_LONG_FORMAT, null, longOut, null);
13407                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13408                longOut[0] = 0;
13409                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13410                        SINGLE_LONG_FORMAT, null, longOut, null);
13411                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13412                longOut[0] = 0;
13413                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13414                        SINGLE_LONG_FORMAT, null, longOut, null);
13415                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13416                if (!isCompact) {
13417                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13418                        pw.print("      KSM: "); pw.print(sharing);
13419                                pw.print(" kB saved from shared ");
13420                                pw.print(shared); pw.println(" kB");
13421                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13422                                pw.print(voltile); pw.println(" kB volatile");
13423                    }
13424                    pw.print("   Tuning: ");
13425                    pw.print(ActivityManager.staticGetMemoryClass());
13426                    pw.print(" (large ");
13427                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13428                    pw.print("), oom ");
13429                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13430                    pw.print(" kB");
13431                    pw.print(", restore limit ");
13432                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13433                    pw.print(" kB");
13434                    if (ActivityManager.isLowRamDeviceStatic()) {
13435                        pw.print(" (low-ram)");
13436                    }
13437                    if (ActivityManager.isHighEndGfx()) {
13438                        pw.print(" (high-end-gfx)");
13439                    }
13440                    pw.println();
13441                } else {
13442                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13443                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13444                    pw.println(voltile);
13445                    pw.print("tuning,");
13446                    pw.print(ActivityManager.staticGetMemoryClass());
13447                    pw.print(',');
13448                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13449                    pw.print(',');
13450                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13451                    if (ActivityManager.isLowRamDeviceStatic()) {
13452                        pw.print(",low-ram");
13453                    }
13454                    if (ActivityManager.isHighEndGfx()) {
13455                        pw.print(",high-end-gfx");
13456                    }
13457                    pw.println();
13458                }
13459            }
13460        }
13461    }
13462
13463    /**
13464     * Searches array of arguments for the specified string
13465     * @param args array of argument strings
13466     * @param value value to search for
13467     * @return true if the value is contained in the array
13468     */
13469    private static boolean scanArgs(String[] args, String value) {
13470        if (args != null) {
13471            for (String arg : args) {
13472                if (value.equals(arg)) {
13473                    return true;
13474                }
13475            }
13476        }
13477        return false;
13478    }
13479
13480    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13481            ContentProviderRecord cpr, boolean always) {
13482        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13483
13484        if (!inLaunching || always) {
13485            synchronized (cpr) {
13486                cpr.launchingApp = null;
13487                cpr.notifyAll();
13488            }
13489            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13490            String names[] = cpr.info.authority.split(";");
13491            for (int j = 0; j < names.length; j++) {
13492                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13493            }
13494        }
13495
13496        for (int i=0; i<cpr.connections.size(); i++) {
13497            ContentProviderConnection conn = cpr.connections.get(i);
13498            if (conn.waiting) {
13499                // If this connection is waiting for the provider, then we don't
13500                // need to mess with its process unless we are always removing
13501                // or for some reason the provider is not currently launching.
13502                if (inLaunching && !always) {
13503                    continue;
13504                }
13505            }
13506            ProcessRecord capp = conn.client;
13507            conn.dead = true;
13508            if (conn.stableCount > 0) {
13509                if (!capp.persistent && capp.thread != null
13510                        && capp.pid != 0
13511                        && capp.pid != MY_PID) {
13512                    killUnneededProcessLocked(capp, "depends on provider "
13513                            + cpr.name.flattenToShortString()
13514                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13515                }
13516            } else if (capp.thread != null && conn.provider.provider != null) {
13517                try {
13518                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13519                } catch (RemoteException e) {
13520                }
13521                // In the protocol here, we don't expect the client to correctly
13522                // clean up this connection, we'll just remove it.
13523                cpr.connections.remove(i);
13524                conn.client.conProviders.remove(conn);
13525            }
13526        }
13527
13528        if (inLaunching && always) {
13529            mLaunchingProviders.remove(cpr);
13530        }
13531        return inLaunching;
13532    }
13533
13534    /**
13535     * Main code for cleaning up a process when it has gone away.  This is
13536     * called both as a result of the process dying, or directly when stopping
13537     * a process when running in single process mode.
13538     */
13539    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13540            boolean restarting, boolean allowRestart, int index) {
13541        if (index >= 0) {
13542            removeLruProcessLocked(app);
13543            ProcessList.remove(app.pid);
13544        }
13545
13546        mProcessesToGc.remove(app);
13547        mPendingPssProcesses.remove(app);
13548
13549        // Dismiss any open dialogs.
13550        if (app.crashDialog != null && !app.forceCrashReport) {
13551            app.crashDialog.dismiss();
13552            app.crashDialog = null;
13553        }
13554        if (app.anrDialog != null) {
13555            app.anrDialog.dismiss();
13556            app.anrDialog = null;
13557        }
13558        if (app.waitDialog != null) {
13559            app.waitDialog.dismiss();
13560            app.waitDialog = null;
13561        }
13562
13563        app.crashing = false;
13564        app.notResponding = false;
13565
13566        app.resetPackageList(mProcessStats);
13567        app.unlinkDeathRecipient();
13568        app.makeInactive(mProcessStats);
13569        app.waitingToKill = null;
13570        app.forcingToForeground = null;
13571        updateProcessForegroundLocked(app, false, false);
13572        app.foregroundActivities = false;
13573        app.hasShownUi = false;
13574        app.treatLikeActivity = false;
13575        app.hasAboveClient = false;
13576        app.hasClientActivities = false;
13577
13578        mServices.killServicesLocked(app, allowRestart);
13579
13580        boolean restart = false;
13581
13582        // Remove published content providers.
13583        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13584            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13585            final boolean always = app.bad || !allowRestart;
13586            if (removeDyingProviderLocked(app, cpr, always) || always) {
13587                // We left the provider in the launching list, need to
13588                // restart it.
13589                restart = true;
13590            }
13591
13592            cpr.provider = null;
13593            cpr.proc = null;
13594        }
13595        app.pubProviders.clear();
13596
13597        // Take care of any launching providers waiting for this process.
13598        if (checkAppInLaunchingProvidersLocked(app, false)) {
13599            restart = true;
13600        }
13601
13602        // Unregister from connected content providers.
13603        if (!app.conProviders.isEmpty()) {
13604            for (int i=0; i<app.conProviders.size(); i++) {
13605                ContentProviderConnection conn = app.conProviders.get(i);
13606                conn.provider.connections.remove(conn);
13607            }
13608            app.conProviders.clear();
13609        }
13610
13611        // At this point there may be remaining entries in mLaunchingProviders
13612        // where we were the only one waiting, so they are no longer of use.
13613        // Look for these and clean up if found.
13614        // XXX Commented out for now.  Trying to figure out a way to reproduce
13615        // the actual situation to identify what is actually going on.
13616        if (false) {
13617            for (int i=0; i<mLaunchingProviders.size(); i++) {
13618                ContentProviderRecord cpr = (ContentProviderRecord)
13619                        mLaunchingProviders.get(i);
13620                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13621                    synchronized (cpr) {
13622                        cpr.launchingApp = null;
13623                        cpr.notifyAll();
13624                    }
13625                }
13626            }
13627        }
13628
13629        skipCurrentReceiverLocked(app);
13630
13631        // Unregister any receivers.
13632        for (int i=app.receivers.size()-1; i>=0; i--) {
13633            removeReceiverLocked(app.receivers.valueAt(i));
13634        }
13635        app.receivers.clear();
13636
13637        // If the app is undergoing backup, tell the backup manager about it
13638        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13639            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13640                    + mBackupTarget.appInfo + " died during backup");
13641            try {
13642                IBackupManager bm = IBackupManager.Stub.asInterface(
13643                        ServiceManager.getService(Context.BACKUP_SERVICE));
13644                bm.agentDisconnected(app.info.packageName);
13645            } catch (RemoteException e) {
13646                // can't happen; backup manager is local
13647            }
13648        }
13649
13650        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13651            ProcessChangeItem item = mPendingProcessChanges.get(i);
13652            if (item.pid == app.pid) {
13653                mPendingProcessChanges.remove(i);
13654                mAvailProcessChanges.add(item);
13655            }
13656        }
13657        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13658
13659        // If the caller is restarting this app, then leave it in its
13660        // current lists and let the caller take care of it.
13661        if (restarting) {
13662            return;
13663        }
13664
13665        if (!app.persistent || app.isolated) {
13666            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13667                    "Removing non-persistent process during cleanup: " + app);
13668            mProcessNames.remove(app.processName, app.uid);
13669            mIsolatedProcesses.remove(app.uid);
13670            if (mHeavyWeightProcess == app) {
13671                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13672                        mHeavyWeightProcess.userId, 0));
13673                mHeavyWeightProcess = null;
13674            }
13675        } else if (!app.removed) {
13676            // This app is persistent, so we need to keep its record around.
13677            // If it is not already on the pending app list, add it there
13678            // and start a new process for it.
13679            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13680                mPersistentStartingProcesses.add(app);
13681                restart = true;
13682            }
13683        }
13684        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13685                "Clean-up removing on hold: " + app);
13686        mProcessesOnHold.remove(app);
13687
13688        if (app == mHomeProcess) {
13689            mHomeProcess = null;
13690        }
13691        if (app == mPreviousProcess) {
13692            mPreviousProcess = null;
13693        }
13694
13695        if (restart && !app.isolated) {
13696            // We have components that still need to be running in the
13697            // process, so re-launch it.
13698            mProcessNames.put(app.processName, app.uid, app);
13699            startProcessLocked(app, "restart", app.processName);
13700        } else if (app.pid > 0 && app.pid != MY_PID) {
13701            // Goodbye!
13702            boolean removed;
13703            synchronized (mPidsSelfLocked) {
13704                mPidsSelfLocked.remove(app.pid);
13705                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13706            }
13707            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13708            if (app.isolated) {
13709                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13710            }
13711            app.setPid(0);
13712        }
13713    }
13714
13715    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13716        // Look through the content providers we are waiting to have launched,
13717        // and if any run in this process then either schedule a restart of
13718        // the process or kill the client waiting for it if this process has
13719        // gone bad.
13720        int NL = mLaunchingProviders.size();
13721        boolean restart = false;
13722        for (int i=0; i<NL; i++) {
13723            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13724            if (cpr.launchingApp == app) {
13725                if (!alwaysBad && !app.bad) {
13726                    restart = true;
13727                } else {
13728                    removeDyingProviderLocked(app, cpr, true);
13729                    // cpr should have been removed from mLaunchingProviders
13730                    NL = mLaunchingProviders.size();
13731                    i--;
13732                }
13733            }
13734        }
13735        return restart;
13736    }
13737
13738    // =========================================================
13739    // SERVICES
13740    // =========================================================
13741
13742    @Override
13743    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13744            int flags) {
13745        enforceNotIsolatedCaller("getServices");
13746        synchronized (this) {
13747            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13748        }
13749    }
13750
13751    @Override
13752    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13753        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13754        synchronized (this) {
13755            return mServices.getRunningServiceControlPanelLocked(name);
13756        }
13757    }
13758
13759    @Override
13760    public ComponentName startService(IApplicationThread caller, Intent service,
13761            String resolvedType, int userId) {
13762        enforceNotIsolatedCaller("startService");
13763        // Refuse possible leaked file descriptors
13764        if (service != null && service.hasFileDescriptors() == true) {
13765            throw new IllegalArgumentException("File descriptors passed in Intent");
13766        }
13767
13768        if (DEBUG_SERVICE)
13769            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13770        synchronized(this) {
13771            final int callingPid = Binder.getCallingPid();
13772            final int callingUid = Binder.getCallingUid();
13773            final long origId = Binder.clearCallingIdentity();
13774            ComponentName res = mServices.startServiceLocked(caller, service,
13775                    resolvedType, callingPid, callingUid, userId);
13776            Binder.restoreCallingIdentity(origId);
13777            return res;
13778        }
13779    }
13780
13781    ComponentName startServiceInPackage(int uid,
13782            Intent service, String resolvedType, int userId) {
13783        synchronized(this) {
13784            if (DEBUG_SERVICE)
13785                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13786            final long origId = Binder.clearCallingIdentity();
13787            ComponentName res = mServices.startServiceLocked(null, service,
13788                    resolvedType, -1, uid, userId);
13789            Binder.restoreCallingIdentity(origId);
13790            return res;
13791        }
13792    }
13793
13794    @Override
13795    public int stopService(IApplicationThread caller, Intent service,
13796            String resolvedType, int userId) {
13797        enforceNotIsolatedCaller("stopService");
13798        // Refuse possible leaked file descriptors
13799        if (service != null && service.hasFileDescriptors() == true) {
13800            throw new IllegalArgumentException("File descriptors passed in Intent");
13801        }
13802
13803        synchronized(this) {
13804            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13805        }
13806    }
13807
13808    @Override
13809    public IBinder peekService(Intent service, String resolvedType) {
13810        enforceNotIsolatedCaller("peekService");
13811        // Refuse possible leaked file descriptors
13812        if (service != null && service.hasFileDescriptors() == true) {
13813            throw new IllegalArgumentException("File descriptors passed in Intent");
13814        }
13815        synchronized(this) {
13816            return mServices.peekServiceLocked(service, resolvedType);
13817        }
13818    }
13819
13820    @Override
13821    public boolean stopServiceToken(ComponentName className, IBinder token,
13822            int startId) {
13823        synchronized(this) {
13824            return mServices.stopServiceTokenLocked(className, token, startId);
13825        }
13826    }
13827
13828    @Override
13829    public void setServiceForeground(ComponentName className, IBinder token,
13830            int id, Notification notification, boolean removeNotification) {
13831        synchronized(this) {
13832            mServices.setServiceForegroundLocked(className, token, id, notification,
13833                    removeNotification);
13834        }
13835    }
13836
13837    @Override
13838    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13839            boolean requireFull, String name, String callerPackage) {
13840        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13841                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13842    }
13843
13844    int unsafeConvertIncomingUser(int userId) {
13845        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13846                ? mCurrentUserId : userId;
13847    }
13848
13849    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13850            int allowMode, String name, String callerPackage) {
13851        final int callingUserId = UserHandle.getUserId(callingUid);
13852        if (callingUserId == userId) {
13853            return userId;
13854        }
13855
13856        // Note that we may be accessing mCurrentUserId outside of a lock...
13857        // shouldn't be a big deal, if this is being called outside
13858        // of a locked context there is intrinsically a race with
13859        // the value the caller will receive and someone else changing it.
13860        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13861        // we will switch to the calling user if access to the current user fails.
13862        int targetUserId = unsafeConvertIncomingUser(userId);
13863
13864        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13865            final boolean allow;
13866            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13867                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13868                // If the caller has this permission, they always pass go.  And collect $200.
13869                allow = true;
13870            } else if (allowMode == ALLOW_FULL_ONLY) {
13871                // We require full access, sucks to be you.
13872                allow = false;
13873            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13874                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13875                // If the caller does not have either permission, they are always doomed.
13876                allow = false;
13877            } else if (allowMode == ALLOW_NON_FULL) {
13878                // We are blanket allowing non-full access, you lucky caller!
13879                allow = true;
13880            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13881                // We may or may not allow this depending on whether the two users are
13882                // in the same profile.
13883                synchronized (mUserProfileGroupIdsSelfLocked) {
13884                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13885                            UserInfo.NO_PROFILE_GROUP_ID);
13886                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13887                            UserInfo.NO_PROFILE_GROUP_ID);
13888                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13889                            && callingProfile == targetProfile;
13890                }
13891            } else {
13892                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13893            }
13894            if (!allow) {
13895                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13896                    // In this case, they would like to just execute as their
13897                    // owner user instead of failing.
13898                    targetUserId = callingUserId;
13899                } else {
13900                    StringBuilder builder = new StringBuilder(128);
13901                    builder.append("Permission Denial: ");
13902                    builder.append(name);
13903                    if (callerPackage != null) {
13904                        builder.append(" from ");
13905                        builder.append(callerPackage);
13906                    }
13907                    builder.append(" asks to run as user ");
13908                    builder.append(userId);
13909                    builder.append(" but is calling from user ");
13910                    builder.append(UserHandle.getUserId(callingUid));
13911                    builder.append("; this requires ");
13912                    builder.append(INTERACT_ACROSS_USERS_FULL);
13913                    if (allowMode != ALLOW_FULL_ONLY) {
13914                        builder.append(" or ");
13915                        builder.append(INTERACT_ACROSS_USERS);
13916                    }
13917                    String msg = builder.toString();
13918                    Slog.w(TAG, msg);
13919                    throw new SecurityException(msg);
13920                }
13921            }
13922        }
13923        if (!allowAll && targetUserId < 0) {
13924            throw new IllegalArgumentException(
13925                    "Call does not support special user #" + targetUserId);
13926        }
13927        return targetUserId;
13928    }
13929
13930    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13931            String className, int flags) {
13932        boolean result = false;
13933        // For apps that don't have pre-defined UIDs, check for permission
13934        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13935            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13936                if (ActivityManager.checkUidPermission(
13937                        INTERACT_ACROSS_USERS,
13938                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13939                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13940                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13941                            + " requests FLAG_SINGLE_USER, but app does not hold "
13942                            + INTERACT_ACROSS_USERS;
13943                    Slog.w(TAG, msg);
13944                    throw new SecurityException(msg);
13945                }
13946                // Permission passed
13947                result = true;
13948            }
13949        } else if ("system".equals(componentProcessName)) {
13950            result = true;
13951        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
13952                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13953            // Phone app is allowed to export singleuser providers.
13954            result = true;
13955        } else {
13956            // App with pre-defined UID, check if it's a persistent app
13957            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13958        }
13959        if (DEBUG_MU) {
13960            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13961                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13962        }
13963        return result;
13964    }
13965
13966    /**
13967     * Checks to see if the caller is in the same app as the singleton
13968     * component, or the component is in a special app. It allows special apps
13969     * to export singleton components but prevents exporting singleton
13970     * components for regular apps.
13971     */
13972    boolean isValidSingletonCall(int callingUid, int componentUid) {
13973        int componentAppId = UserHandle.getAppId(componentUid);
13974        return UserHandle.isSameApp(callingUid, componentUid)
13975                || componentAppId == Process.SYSTEM_UID
13976                || componentAppId == Process.PHONE_UID
13977                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13978                        == PackageManager.PERMISSION_GRANTED;
13979    }
13980
13981    public int bindService(IApplicationThread caller, IBinder token,
13982            Intent service, String resolvedType,
13983            IServiceConnection connection, int flags, int userId) {
13984        enforceNotIsolatedCaller("bindService");
13985        // Refuse possible leaked file descriptors
13986        if (service != null && service.hasFileDescriptors() == true) {
13987            throw new IllegalArgumentException("File descriptors passed in Intent");
13988        }
13989
13990        synchronized(this) {
13991            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13992                    connection, flags, userId);
13993        }
13994    }
13995
13996    public boolean unbindService(IServiceConnection connection) {
13997        synchronized (this) {
13998            return mServices.unbindServiceLocked(connection);
13999        }
14000    }
14001
14002    public void publishService(IBinder token, Intent intent, IBinder service) {
14003        // Refuse possible leaked file descriptors
14004        if (intent != null && intent.hasFileDescriptors() == true) {
14005            throw new IllegalArgumentException("File descriptors passed in Intent");
14006        }
14007
14008        synchronized(this) {
14009            if (!(token instanceof ServiceRecord)) {
14010                throw new IllegalArgumentException("Invalid service token");
14011            }
14012            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14013        }
14014    }
14015
14016    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14017        // Refuse possible leaked file descriptors
14018        if (intent != null && intent.hasFileDescriptors() == true) {
14019            throw new IllegalArgumentException("File descriptors passed in Intent");
14020        }
14021
14022        synchronized(this) {
14023            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14024        }
14025    }
14026
14027    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14028        synchronized(this) {
14029            if (!(token instanceof ServiceRecord)) {
14030                throw new IllegalArgumentException("Invalid service token");
14031            }
14032            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14033        }
14034    }
14035
14036    // =========================================================
14037    // BACKUP AND RESTORE
14038    // =========================================================
14039
14040    // Cause the target app to be launched if necessary and its backup agent
14041    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14042    // activity manager to announce its creation.
14043    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14044        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14045        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14046
14047        synchronized(this) {
14048            // !!! TODO: currently no check here that we're already bound
14049            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14050            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14051            synchronized (stats) {
14052                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14053            }
14054
14055            // Backup agent is now in use, its package can't be stopped.
14056            try {
14057                AppGlobals.getPackageManager().setPackageStoppedState(
14058                        app.packageName, false, UserHandle.getUserId(app.uid));
14059            } catch (RemoteException e) {
14060            } catch (IllegalArgumentException e) {
14061                Slog.w(TAG, "Failed trying to unstop package "
14062                        + app.packageName + ": " + e);
14063            }
14064
14065            BackupRecord r = new BackupRecord(ss, app, backupMode);
14066            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14067                    ? new ComponentName(app.packageName, app.backupAgentName)
14068                    : new ComponentName("android", "FullBackupAgent");
14069            // startProcessLocked() returns existing proc's record if it's already running
14070            ProcessRecord proc = startProcessLocked(app.processName, app,
14071                    false, 0, "backup", hostingName, false, false, false);
14072            if (proc == null) {
14073                Slog.e(TAG, "Unable to start backup agent process " + r);
14074                return false;
14075            }
14076
14077            r.app = proc;
14078            mBackupTarget = r;
14079            mBackupAppName = app.packageName;
14080
14081            // Try not to kill the process during backup
14082            updateOomAdjLocked(proc);
14083
14084            // If the process is already attached, schedule the creation of the backup agent now.
14085            // If it is not yet live, this will be done when it attaches to the framework.
14086            if (proc.thread != null) {
14087                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14088                try {
14089                    proc.thread.scheduleCreateBackupAgent(app,
14090                            compatibilityInfoForPackageLocked(app), backupMode);
14091                } catch (RemoteException e) {
14092                    // Will time out on the backup manager side
14093                }
14094            } else {
14095                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14096            }
14097            // Invariants: at this point, the target app process exists and the application
14098            // is either already running or in the process of coming up.  mBackupTarget and
14099            // mBackupAppName describe the app, so that when it binds back to the AM we
14100            // know that it's scheduled for a backup-agent operation.
14101        }
14102
14103        return true;
14104    }
14105
14106    @Override
14107    public void clearPendingBackup() {
14108        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14109        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14110
14111        synchronized (this) {
14112            mBackupTarget = null;
14113            mBackupAppName = null;
14114        }
14115    }
14116
14117    // A backup agent has just come up
14118    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14119        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14120                + " = " + agent);
14121
14122        synchronized(this) {
14123            if (!agentPackageName.equals(mBackupAppName)) {
14124                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14125                return;
14126            }
14127        }
14128
14129        long oldIdent = Binder.clearCallingIdentity();
14130        try {
14131            IBackupManager bm = IBackupManager.Stub.asInterface(
14132                    ServiceManager.getService(Context.BACKUP_SERVICE));
14133            bm.agentConnected(agentPackageName, agent);
14134        } catch (RemoteException e) {
14135            // can't happen; the backup manager service is local
14136        } catch (Exception e) {
14137            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14138            e.printStackTrace();
14139        } finally {
14140            Binder.restoreCallingIdentity(oldIdent);
14141        }
14142    }
14143
14144    // done with this agent
14145    public void unbindBackupAgent(ApplicationInfo appInfo) {
14146        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14147        if (appInfo == null) {
14148            Slog.w(TAG, "unbind backup agent for null app");
14149            return;
14150        }
14151
14152        synchronized(this) {
14153            try {
14154                if (mBackupAppName == null) {
14155                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14156                    return;
14157                }
14158
14159                if (!mBackupAppName.equals(appInfo.packageName)) {
14160                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14161                    return;
14162                }
14163
14164                // Not backing this app up any more; reset its OOM adjustment
14165                final ProcessRecord proc = mBackupTarget.app;
14166                updateOomAdjLocked(proc);
14167
14168                // If the app crashed during backup, 'thread' will be null here
14169                if (proc.thread != null) {
14170                    try {
14171                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14172                                compatibilityInfoForPackageLocked(appInfo));
14173                    } catch (Exception e) {
14174                        Slog.e(TAG, "Exception when unbinding backup agent:");
14175                        e.printStackTrace();
14176                    }
14177                }
14178            } finally {
14179                mBackupTarget = null;
14180                mBackupAppName = null;
14181            }
14182        }
14183    }
14184    // =========================================================
14185    // BROADCASTS
14186    // =========================================================
14187
14188    private final List getStickiesLocked(String action, IntentFilter filter,
14189            List cur, int userId) {
14190        final ContentResolver resolver = mContext.getContentResolver();
14191        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14192        if (stickies == null) {
14193            return cur;
14194        }
14195        final ArrayList<Intent> list = stickies.get(action);
14196        if (list == null) {
14197            return cur;
14198        }
14199        int N = list.size();
14200        for (int i=0; i<N; i++) {
14201            Intent intent = list.get(i);
14202            if (filter.match(resolver, intent, true, TAG) >= 0) {
14203                if (cur == null) {
14204                    cur = new ArrayList<Intent>();
14205                }
14206                cur.add(intent);
14207            }
14208        }
14209        return cur;
14210    }
14211
14212    boolean isPendingBroadcastProcessLocked(int pid) {
14213        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14214                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14215    }
14216
14217    void skipPendingBroadcastLocked(int pid) {
14218            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14219            for (BroadcastQueue queue : mBroadcastQueues) {
14220                queue.skipPendingBroadcastLocked(pid);
14221            }
14222    }
14223
14224    // The app just attached; send any pending broadcasts that it should receive
14225    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14226        boolean didSomething = false;
14227        for (BroadcastQueue queue : mBroadcastQueues) {
14228            didSomething |= queue.sendPendingBroadcastsLocked(app);
14229        }
14230        return didSomething;
14231    }
14232
14233    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14234            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14235        enforceNotIsolatedCaller("registerReceiver");
14236        int callingUid;
14237        int callingPid;
14238        synchronized(this) {
14239            ProcessRecord callerApp = null;
14240            if (caller != null) {
14241                callerApp = getRecordForAppLocked(caller);
14242                if (callerApp == null) {
14243                    throw new SecurityException(
14244                            "Unable to find app for caller " + caller
14245                            + " (pid=" + Binder.getCallingPid()
14246                            + ") when registering receiver " + receiver);
14247                }
14248                if (callerApp.info.uid != Process.SYSTEM_UID &&
14249                        !callerApp.pkgList.containsKey(callerPackage) &&
14250                        !"android".equals(callerPackage)) {
14251                    throw new SecurityException("Given caller package " + callerPackage
14252                            + " is not running in process " + callerApp);
14253                }
14254                callingUid = callerApp.info.uid;
14255                callingPid = callerApp.pid;
14256            } else {
14257                callerPackage = null;
14258                callingUid = Binder.getCallingUid();
14259                callingPid = Binder.getCallingPid();
14260            }
14261
14262            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14263                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14264
14265            List allSticky = null;
14266
14267            // Look for any matching sticky broadcasts...
14268            Iterator actions = filter.actionsIterator();
14269            if (actions != null) {
14270                while (actions.hasNext()) {
14271                    String action = (String)actions.next();
14272                    allSticky = getStickiesLocked(action, filter, allSticky,
14273                            UserHandle.USER_ALL);
14274                    allSticky = getStickiesLocked(action, filter, allSticky,
14275                            UserHandle.getUserId(callingUid));
14276                }
14277            } else {
14278                allSticky = getStickiesLocked(null, filter, allSticky,
14279                        UserHandle.USER_ALL);
14280                allSticky = getStickiesLocked(null, filter, allSticky,
14281                        UserHandle.getUserId(callingUid));
14282            }
14283
14284            // The first sticky in the list is returned directly back to
14285            // the client.
14286            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14287
14288            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14289                    + ": " + sticky);
14290
14291            if (receiver == null) {
14292                return sticky;
14293            }
14294
14295            ReceiverList rl
14296                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14297            if (rl == null) {
14298                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14299                        userId, receiver);
14300                if (rl.app != null) {
14301                    rl.app.receivers.add(rl);
14302                } else {
14303                    try {
14304                        receiver.asBinder().linkToDeath(rl, 0);
14305                    } catch (RemoteException e) {
14306                        return sticky;
14307                    }
14308                    rl.linkedToDeath = true;
14309                }
14310                mRegisteredReceivers.put(receiver.asBinder(), rl);
14311            } else if (rl.uid != callingUid) {
14312                throw new IllegalArgumentException(
14313                        "Receiver requested to register for uid " + callingUid
14314                        + " was previously registered for uid " + rl.uid);
14315            } else if (rl.pid != callingPid) {
14316                throw new IllegalArgumentException(
14317                        "Receiver requested to register for pid " + callingPid
14318                        + " was previously registered for pid " + rl.pid);
14319            } else if (rl.userId != userId) {
14320                throw new IllegalArgumentException(
14321                        "Receiver requested to register for user " + userId
14322                        + " was previously registered for user " + rl.userId);
14323            }
14324            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14325                    permission, callingUid, userId);
14326            rl.add(bf);
14327            if (!bf.debugCheck()) {
14328                Slog.w(TAG, "==> For Dynamic broadast");
14329            }
14330            mReceiverResolver.addFilter(bf);
14331
14332            // Enqueue broadcasts for all existing stickies that match
14333            // this filter.
14334            if (allSticky != null) {
14335                ArrayList receivers = new ArrayList();
14336                receivers.add(bf);
14337
14338                int N = allSticky.size();
14339                for (int i=0; i<N; i++) {
14340                    Intent intent = (Intent)allSticky.get(i);
14341                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14342                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14343                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14344                            null, null, false, true, true, -1);
14345                    queue.enqueueParallelBroadcastLocked(r);
14346                    queue.scheduleBroadcastsLocked();
14347                }
14348            }
14349
14350            return sticky;
14351        }
14352    }
14353
14354    public void unregisterReceiver(IIntentReceiver receiver) {
14355        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14356
14357        final long origId = Binder.clearCallingIdentity();
14358        try {
14359            boolean doTrim = false;
14360
14361            synchronized(this) {
14362                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14363                if (rl != null) {
14364                    if (rl.curBroadcast != null) {
14365                        BroadcastRecord r = rl.curBroadcast;
14366                        final boolean doNext = finishReceiverLocked(
14367                                receiver.asBinder(), r.resultCode, r.resultData,
14368                                r.resultExtras, r.resultAbort);
14369                        if (doNext) {
14370                            doTrim = true;
14371                            r.queue.processNextBroadcast(false);
14372                        }
14373                    }
14374
14375                    if (rl.app != null) {
14376                        rl.app.receivers.remove(rl);
14377                    }
14378                    removeReceiverLocked(rl);
14379                    if (rl.linkedToDeath) {
14380                        rl.linkedToDeath = false;
14381                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14382                    }
14383                }
14384            }
14385
14386            // If we actually concluded any broadcasts, we might now be able
14387            // to trim the recipients' apps from our working set
14388            if (doTrim) {
14389                trimApplications();
14390                return;
14391            }
14392
14393        } finally {
14394            Binder.restoreCallingIdentity(origId);
14395        }
14396    }
14397
14398    void removeReceiverLocked(ReceiverList rl) {
14399        mRegisteredReceivers.remove(rl.receiver.asBinder());
14400        int N = rl.size();
14401        for (int i=0; i<N; i++) {
14402            mReceiverResolver.removeFilter(rl.get(i));
14403        }
14404    }
14405
14406    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14407        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14408            ProcessRecord r = mLruProcesses.get(i);
14409            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14410                try {
14411                    r.thread.dispatchPackageBroadcast(cmd, packages);
14412                } catch (RemoteException ex) {
14413                }
14414            }
14415        }
14416    }
14417
14418    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14419            int[] users) {
14420        List<ResolveInfo> receivers = null;
14421        try {
14422            HashSet<ComponentName> singleUserReceivers = null;
14423            boolean scannedFirstReceivers = false;
14424            for (int user : users) {
14425                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14426                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14427                if (user != 0 && newReceivers != null) {
14428                    // If this is not the primary user, we need to check for
14429                    // any receivers that should be filtered out.
14430                    for (int i=0; i<newReceivers.size(); i++) {
14431                        ResolveInfo ri = newReceivers.get(i);
14432                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14433                            newReceivers.remove(i);
14434                            i--;
14435                        }
14436                    }
14437                }
14438                if (newReceivers != null && newReceivers.size() == 0) {
14439                    newReceivers = null;
14440                }
14441                if (receivers == null) {
14442                    receivers = newReceivers;
14443                } else if (newReceivers != null) {
14444                    // We need to concatenate the additional receivers
14445                    // found with what we have do far.  This would be easy,
14446                    // but we also need to de-dup any receivers that are
14447                    // singleUser.
14448                    if (!scannedFirstReceivers) {
14449                        // Collect any single user receivers we had already retrieved.
14450                        scannedFirstReceivers = true;
14451                        for (int i=0; i<receivers.size(); i++) {
14452                            ResolveInfo ri = receivers.get(i);
14453                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14454                                ComponentName cn = new ComponentName(
14455                                        ri.activityInfo.packageName, ri.activityInfo.name);
14456                                if (singleUserReceivers == null) {
14457                                    singleUserReceivers = new HashSet<ComponentName>();
14458                                }
14459                                singleUserReceivers.add(cn);
14460                            }
14461                        }
14462                    }
14463                    // Add the new results to the existing results, tracking
14464                    // and de-dupping single user receivers.
14465                    for (int i=0; i<newReceivers.size(); i++) {
14466                        ResolveInfo ri = newReceivers.get(i);
14467                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14468                            ComponentName cn = new ComponentName(
14469                                    ri.activityInfo.packageName, ri.activityInfo.name);
14470                            if (singleUserReceivers == null) {
14471                                singleUserReceivers = new HashSet<ComponentName>();
14472                            }
14473                            if (!singleUserReceivers.contains(cn)) {
14474                                singleUserReceivers.add(cn);
14475                                receivers.add(ri);
14476                            }
14477                        } else {
14478                            receivers.add(ri);
14479                        }
14480                    }
14481                }
14482            }
14483        } catch (RemoteException ex) {
14484            // pm is in same process, this will never happen.
14485        }
14486        return receivers;
14487    }
14488
14489    private final int broadcastIntentLocked(ProcessRecord callerApp,
14490            String callerPackage, Intent intent, String resolvedType,
14491            IIntentReceiver resultTo, int resultCode, String resultData,
14492            Bundle map, String requiredPermission, int appOp,
14493            boolean ordered, boolean sticky, int callingPid, int callingUid,
14494            int userId) {
14495        intent = new Intent(intent);
14496
14497        // By default broadcasts do not go to stopped apps.
14498        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14499
14500        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14501            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14502            + " ordered=" + ordered + " userid=" + userId);
14503        if ((resultTo != null) && !ordered) {
14504            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14505        }
14506
14507        userId = handleIncomingUser(callingPid, callingUid, userId,
14508                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14509
14510        // Make sure that the user who is receiving this broadcast is started.
14511        // If not, we will just skip it.
14512
14513
14514        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14515            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14516                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14517                Slog.w(TAG, "Skipping broadcast of " + intent
14518                        + ": user " + userId + " is stopped");
14519                return ActivityManager.BROADCAST_SUCCESS;
14520            }
14521        }
14522
14523        /*
14524         * Prevent non-system code (defined here to be non-persistent
14525         * processes) from sending protected broadcasts.
14526         */
14527        int callingAppId = UserHandle.getAppId(callingUid);
14528        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14529            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14530            || callingAppId == Process.NFC_UID || callingUid == 0) {
14531            // Always okay.
14532        } else if (callerApp == null || !callerApp.persistent) {
14533            try {
14534                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14535                        intent.getAction())) {
14536                    String msg = "Permission Denial: not allowed to send broadcast "
14537                            + intent.getAction() + " from pid="
14538                            + callingPid + ", uid=" + callingUid;
14539                    Slog.w(TAG, msg);
14540                    throw new SecurityException(msg);
14541                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14542                    // Special case for compatibility: we don't want apps to send this,
14543                    // but historically it has not been protected and apps may be using it
14544                    // to poke their own app widget.  So, instead of making it protected,
14545                    // just limit it to the caller.
14546                    if (callerApp == null) {
14547                        String msg = "Permission Denial: not allowed to send broadcast "
14548                                + intent.getAction() + " from unknown caller.";
14549                        Slog.w(TAG, msg);
14550                        throw new SecurityException(msg);
14551                    } else if (intent.getComponent() != null) {
14552                        // They are good enough to send to an explicit component...  verify
14553                        // it is being sent to the calling app.
14554                        if (!intent.getComponent().getPackageName().equals(
14555                                callerApp.info.packageName)) {
14556                            String msg = "Permission Denial: not allowed to send broadcast "
14557                                    + intent.getAction() + " to "
14558                                    + intent.getComponent().getPackageName() + " from "
14559                                    + callerApp.info.packageName;
14560                            Slog.w(TAG, msg);
14561                            throw new SecurityException(msg);
14562                        }
14563                    } else {
14564                        // Limit broadcast to their own package.
14565                        intent.setPackage(callerApp.info.packageName);
14566                    }
14567                }
14568            } catch (RemoteException e) {
14569                Slog.w(TAG, "Remote exception", e);
14570                return ActivityManager.BROADCAST_SUCCESS;
14571            }
14572        }
14573
14574        // Handle special intents: if this broadcast is from the package
14575        // manager about a package being removed, we need to remove all of
14576        // its activities from the history stack.
14577        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14578                intent.getAction());
14579        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14580                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14581                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14582                || uidRemoved) {
14583            if (checkComponentPermission(
14584                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14585                    callingPid, callingUid, -1, true)
14586                    == PackageManager.PERMISSION_GRANTED) {
14587                if (uidRemoved) {
14588                    final Bundle intentExtras = intent.getExtras();
14589                    final int uid = intentExtras != null
14590                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14591                    if (uid >= 0) {
14592                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14593                        synchronized (bs) {
14594                            bs.removeUidStatsLocked(uid);
14595                        }
14596                        mAppOpsService.uidRemoved(uid);
14597                    }
14598                } else {
14599                    // If resources are unavailable just force stop all
14600                    // those packages and flush the attribute cache as well.
14601                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14602                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14603                        if (list != null && (list.length > 0)) {
14604                            for (String pkg : list) {
14605                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14606                                        "storage unmount");
14607                            }
14608                            sendPackageBroadcastLocked(
14609                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14610                        }
14611                    } else {
14612                        Uri data = intent.getData();
14613                        String ssp;
14614                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14615                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14616                                    intent.getAction());
14617                            boolean fullUninstall = removed &&
14618                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14619                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14620                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14621                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14622                                        false, fullUninstall, userId,
14623                                        removed ? "pkg removed" : "pkg changed");
14624                            }
14625                            if (removed) {
14626                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14627                                        new String[] {ssp}, userId);
14628                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14629                                    mAppOpsService.packageRemoved(
14630                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14631
14632                                    // Remove all permissions granted from/to this package
14633                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14634                                }
14635                            }
14636                        }
14637                    }
14638                }
14639            } else {
14640                String msg = "Permission Denial: " + intent.getAction()
14641                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14642                        + ", uid=" + callingUid + ")"
14643                        + " requires "
14644                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14645                Slog.w(TAG, msg);
14646                throw new SecurityException(msg);
14647            }
14648
14649        // Special case for adding a package: by default turn on compatibility
14650        // mode.
14651        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14652            Uri data = intent.getData();
14653            String ssp;
14654            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14655                mCompatModePackages.handlePackageAddedLocked(ssp,
14656                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14657            }
14658        }
14659
14660        /*
14661         * If this is the time zone changed action, queue up a message that will reset the timezone
14662         * of all currently running processes. This message will get queued up before the broadcast
14663         * happens.
14664         */
14665        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14666            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14667        }
14668
14669        /*
14670         * If the user set the time, let all running processes know.
14671         */
14672        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14673            final int is24Hour = intent.getBooleanExtra(
14674                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14675            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14676        }
14677
14678        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14679            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14680        }
14681
14682        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14683            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14684            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14685        }
14686
14687        // Add to the sticky list if requested.
14688        if (sticky) {
14689            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14690                    callingPid, callingUid)
14691                    != PackageManager.PERMISSION_GRANTED) {
14692                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14693                        + callingPid + ", uid=" + callingUid
14694                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14695                Slog.w(TAG, msg);
14696                throw new SecurityException(msg);
14697            }
14698            if (requiredPermission != null) {
14699                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14700                        + " and enforce permission " + requiredPermission);
14701                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14702            }
14703            if (intent.getComponent() != null) {
14704                throw new SecurityException(
14705                        "Sticky broadcasts can't target a specific component");
14706            }
14707            // We use userId directly here, since the "all" target is maintained
14708            // as a separate set of sticky broadcasts.
14709            if (userId != UserHandle.USER_ALL) {
14710                // But first, if this is not a broadcast to all users, then
14711                // make sure it doesn't conflict with an existing broadcast to
14712                // all users.
14713                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14714                        UserHandle.USER_ALL);
14715                if (stickies != null) {
14716                    ArrayList<Intent> list = stickies.get(intent.getAction());
14717                    if (list != null) {
14718                        int N = list.size();
14719                        int i;
14720                        for (i=0; i<N; i++) {
14721                            if (intent.filterEquals(list.get(i))) {
14722                                throw new IllegalArgumentException(
14723                                        "Sticky broadcast " + intent + " for user "
14724                                        + userId + " conflicts with existing global broadcast");
14725                            }
14726                        }
14727                    }
14728                }
14729            }
14730            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14731            if (stickies == null) {
14732                stickies = new ArrayMap<String, ArrayList<Intent>>();
14733                mStickyBroadcasts.put(userId, stickies);
14734            }
14735            ArrayList<Intent> list = stickies.get(intent.getAction());
14736            if (list == null) {
14737                list = new ArrayList<Intent>();
14738                stickies.put(intent.getAction(), list);
14739            }
14740            int N = list.size();
14741            int i;
14742            for (i=0; i<N; i++) {
14743                if (intent.filterEquals(list.get(i))) {
14744                    // This sticky already exists, replace it.
14745                    list.set(i, new Intent(intent));
14746                    break;
14747                }
14748            }
14749            if (i >= N) {
14750                list.add(new Intent(intent));
14751            }
14752        }
14753
14754        int[] users;
14755        if (userId == UserHandle.USER_ALL) {
14756            // Caller wants broadcast to go to all started users.
14757            users = mStartedUserArray;
14758        } else {
14759            // Caller wants broadcast to go to one specific user.
14760            users = new int[] {userId};
14761        }
14762
14763        // Figure out who all will receive this broadcast.
14764        List receivers = null;
14765        List<BroadcastFilter> registeredReceivers = null;
14766        // Need to resolve the intent to interested receivers...
14767        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14768                 == 0) {
14769            receivers = collectReceiverComponents(intent, resolvedType, users);
14770        }
14771        if (intent.getComponent() == null) {
14772            registeredReceivers = mReceiverResolver.queryIntent(intent,
14773                    resolvedType, false, userId);
14774        }
14775
14776        final boolean replacePending =
14777                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14778
14779        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14780                + " replacePending=" + replacePending);
14781
14782        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14783        if (!ordered && NR > 0) {
14784            // If we are not serializing this broadcast, then send the
14785            // registered receivers separately so they don't wait for the
14786            // components to be launched.
14787            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14788            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14789                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14790                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14791                    ordered, sticky, false, userId);
14792            if (DEBUG_BROADCAST) Slog.v(
14793                    TAG, "Enqueueing parallel broadcast " + r);
14794            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14795            if (!replaced) {
14796                queue.enqueueParallelBroadcastLocked(r);
14797                queue.scheduleBroadcastsLocked();
14798            }
14799            registeredReceivers = null;
14800            NR = 0;
14801        }
14802
14803        // Merge into one list.
14804        int ir = 0;
14805        if (receivers != null) {
14806            // A special case for PACKAGE_ADDED: do not allow the package
14807            // being added to see this broadcast.  This prevents them from
14808            // using this as a back door to get run as soon as they are
14809            // installed.  Maybe in the future we want to have a special install
14810            // broadcast or such for apps, but we'd like to deliberately make
14811            // this decision.
14812            String skipPackages[] = null;
14813            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14814                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14815                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14816                Uri data = intent.getData();
14817                if (data != null) {
14818                    String pkgName = data.getSchemeSpecificPart();
14819                    if (pkgName != null) {
14820                        skipPackages = new String[] { pkgName };
14821                    }
14822                }
14823            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14824                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14825            }
14826            if (skipPackages != null && (skipPackages.length > 0)) {
14827                for (String skipPackage : skipPackages) {
14828                    if (skipPackage != null) {
14829                        int NT = receivers.size();
14830                        for (int it=0; it<NT; it++) {
14831                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14832                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14833                                receivers.remove(it);
14834                                it--;
14835                                NT--;
14836                            }
14837                        }
14838                    }
14839                }
14840            }
14841
14842            int NT = receivers != null ? receivers.size() : 0;
14843            int it = 0;
14844            ResolveInfo curt = null;
14845            BroadcastFilter curr = null;
14846            while (it < NT && ir < NR) {
14847                if (curt == null) {
14848                    curt = (ResolveInfo)receivers.get(it);
14849                }
14850                if (curr == null) {
14851                    curr = registeredReceivers.get(ir);
14852                }
14853                if (curr.getPriority() >= curt.priority) {
14854                    // Insert this broadcast record into the final list.
14855                    receivers.add(it, curr);
14856                    ir++;
14857                    curr = null;
14858                    it++;
14859                    NT++;
14860                } else {
14861                    // Skip to the next ResolveInfo in the final list.
14862                    it++;
14863                    curt = null;
14864                }
14865            }
14866        }
14867        while (ir < NR) {
14868            if (receivers == null) {
14869                receivers = new ArrayList();
14870            }
14871            receivers.add(registeredReceivers.get(ir));
14872            ir++;
14873        }
14874
14875        if ((receivers != null && receivers.size() > 0)
14876                || resultTo != null) {
14877            BroadcastQueue queue = broadcastQueueForIntent(intent);
14878            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14879                    callerPackage, callingPid, callingUid, resolvedType,
14880                    requiredPermission, appOp, receivers, resultTo, resultCode,
14881                    resultData, map, ordered, sticky, false, userId);
14882            if (DEBUG_BROADCAST) Slog.v(
14883                    TAG, "Enqueueing ordered broadcast " + r
14884                    + ": prev had " + queue.mOrderedBroadcasts.size());
14885            if (DEBUG_BROADCAST) {
14886                int seq = r.intent.getIntExtra("seq", -1);
14887                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14888            }
14889            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14890            if (!replaced) {
14891                queue.enqueueOrderedBroadcastLocked(r);
14892                queue.scheduleBroadcastsLocked();
14893            }
14894        }
14895
14896        return ActivityManager.BROADCAST_SUCCESS;
14897    }
14898
14899    final Intent verifyBroadcastLocked(Intent intent) {
14900        // Refuse possible leaked file descriptors
14901        if (intent != null && intent.hasFileDescriptors() == true) {
14902            throw new IllegalArgumentException("File descriptors passed in Intent");
14903        }
14904
14905        int flags = intent.getFlags();
14906
14907        if (!mProcessesReady) {
14908            // if the caller really truly claims to know what they're doing, go
14909            // ahead and allow the broadcast without launching any receivers
14910            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14911                intent = new Intent(intent);
14912                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14913            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14914                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14915                        + " before boot completion");
14916                throw new IllegalStateException("Cannot broadcast before boot completed");
14917            }
14918        }
14919
14920        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14921            throw new IllegalArgumentException(
14922                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14923        }
14924
14925        return intent;
14926    }
14927
14928    public final int broadcastIntent(IApplicationThread caller,
14929            Intent intent, String resolvedType, IIntentReceiver resultTo,
14930            int resultCode, String resultData, Bundle map,
14931            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14932        enforceNotIsolatedCaller("broadcastIntent");
14933        synchronized(this) {
14934            intent = verifyBroadcastLocked(intent);
14935
14936            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14937            final int callingPid = Binder.getCallingPid();
14938            final int callingUid = Binder.getCallingUid();
14939            final long origId = Binder.clearCallingIdentity();
14940            int res = broadcastIntentLocked(callerApp,
14941                    callerApp != null ? callerApp.info.packageName : null,
14942                    intent, resolvedType, resultTo,
14943                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14944                    callingPid, callingUid, userId);
14945            Binder.restoreCallingIdentity(origId);
14946            return res;
14947        }
14948    }
14949
14950    int broadcastIntentInPackage(String packageName, int uid,
14951            Intent intent, String resolvedType, IIntentReceiver resultTo,
14952            int resultCode, String resultData, Bundle map,
14953            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14954        synchronized(this) {
14955            intent = verifyBroadcastLocked(intent);
14956
14957            final long origId = Binder.clearCallingIdentity();
14958            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14959                    resultTo, resultCode, resultData, map, requiredPermission,
14960                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14961            Binder.restoreCallingIdentity(origId);
14962            return res;
14963        }
14964    }
14965
14966    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14967        // Refuse possible leaked file descriptors
14968        if (intent != null && intent.hasFileDescriptors() == true) {
14969            throw new IllegalArgumentException("File descriptors passed in Intent");
14970        }
14971
14972        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14973                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14974
14975        synchronized(this) {
14976            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14977                    != PackageManager.PERMISSION_GRANTED) {
14978                String msg = "Permission Denial: unbroadcastIntent() from pid="
14979                        + Binder.getCallingPid()
14980                        + ", uid=" + Binder.getCallingUid()
14981                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14982                Slog.w(TAG, msg);
14983                throw new SecurityException(msg);
14984            }
14985            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14986            if (stickies != null) {
14987                ArrayList<Intent> list = stickies.get(intent.getAction());
14988                if (list != null) {
14989                    int N = list.size();
14990                    int i;
14991                    for (i=0; i<N; i++) {
14992                        if (intent.filterEquals(list.get(i))) {
14993                            list.remove(i);
14994                            break;
14995                        }
14996                    }
14997                    if (list.size() <= 0) {
14998                        stickies.remove(intent.getAction());
14999                    }
15000                }
15001                if (stickies.size() <= 0) {
15002                    mStickyBroadcasts.remove(userId);
15003                }
15004            }
15005        }
15006    }
15007
15008    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15009            String resultData, Bundle resultExtras, boolean resultAbort) {
15010        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15011        if (r == null) {
15012            Slog.w(TAG, "finishReceiver called but not found on queue");
15013            return false;
15014        }
15015
15016        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15017    }
15018
15019    void backgroundServicesFinishedLocked(int userId) {
15020        for (BroadcastQueue queue : mBroadcastQueues) {
15021            queue.backgroundServicesFinishedLocked(userId);
15022        }
15023    }
15024
15025    public void finishReceiver(IBinder who, int resultCode, String resultData,
15026            Bundle resultExtras, boolean resultAbort) {
15027        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15028
15029        // Refuse possible leaked file descriptors
15030        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15031            throw new IllegalArgumentException("File descriptors passed in Bundle");
15032        }
15033
15034        final long origId = Binder.clearCallingIdentity();
15035        try {
15036            boolean doNext = false;
15037            BroadcastRecord r;
15038
15039            synchronized(this) {
15040                r = broadcastRecordForReceiverLocked(who);
15041                if (r != null) {
15042                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15043                        resultData, resultExtras, resultAbort, true);
15044                }
15045            }
15046
15047            if (doNext) {
15048                r.queue.processNextBroadcast(false);
15049            }
15050            trimApplications();
15051        } finally {
15052            Binder.restoreCallingIdentity(origId);
15053        }
15054    }
15055
15056    // =========================================================
15057    // INSTRUMENTATION
15058    // =========================================================
15059
15060    public boolean startInstrumentation(ComponentName className,
15061            String profileFile, int flags, Bundle arguments,
15062            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15063            int userId, String abiOverride) {
15064        enforceNotIsolatedCaller("startInstrumentation");
15065        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15066                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15067        // Refuse possible leaked file descriptors
15068        if (arguments != null && arguments.hasFileDescriptors()) {
15069            throw new IllegalArgumentException("File descriptors passed in Bundle");
15070        }
15071
15072        synchronized(this) {
15073            InstrumentationInfo ii = null;
15074            ApplicationInfo ai = null;
15075            try {
15076                ii = mContext.getPackageManager().getInstrumentationInfo(
15077                    className, STOCK_PM_FLAGS);
15078                ai = AppGlobals.getPackageManager().getApplicationInfo(
15079                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15080            } catch (PackageManager.NameNotFoundException e) {
15081            } catch (RemoteException e) {
15082            }
15083            if (ii == null) {
15084                reportStartInstrumentationFailure(watcher, className,
15085                        "Unable to find instrumentation info for: " + className);
15086                return false;
15087            }
15088            if (ai == null) {
15089                reportStartInstrumentationFailure(watcher, className,
15090                        "Unable to find instrumentation target package: " + ii.targetPackage);
15091                return false;
15092            }
15093
15094            int match = mContext.getPackageManager().checkSignatures(
15095                    ii.targetPackage, ii.packageName);
15096            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15097                String msg = "Permission Denial: starting instrumentation "
15098                        + className + " from pid="
15099                        + Binder.getCallingPid()
15100                        + ", uid=" + Binder.getCallingPid()
15101                        + " not allowed because package " + ii.packageName
15102                        + " does not have a signature matching the target "
15103                        + ii.targetPackage;
15104                reportStartInstrumentationFailure(watcher, className, msg);
15105                throw new SecurityException(msg);
15106            }
15107
15108            final long origId = Binder.clearCallingIdentity();
15109            // Instrumentation can kill and relaunch even persistent processes
15110            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15111                    "start instr");
15112            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15113            app.instrumentationClass = className;
15114            app.instrumentationInfo = ai;
15115            app.instrumentationProfileFile = profileFile;
15116            app.instrumentationArguments = arguments;
15117            app.instrumentationWatcher = watcher;
15118            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15119            app.instrumentationResultClass = className;
15120            Binder.restoreCallingIdentity(origId);
15121        }
15122
15123        return true;
15124    }
15125
15126    /**
15127     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15128     * error to the logs, but if somebody is watching, send the report there too.  This enables
15129     * the "am" command to report errors with more information.
15130     *
15131     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15132     * @param cn The component name of the instrumentation.
15133     * @param report The error report.
15134     */
15135    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15136            ComponentName cn, String report) {
15137        Slog.w(TAG, report);
15138        try {
15139            if (watcher != null) {
15140                Bundle results = new Bundle();
15141                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15142                results.putString("Error", report);
15143                watcher.instrumentationStatus(cn, -1, results);
15144            }
15145        } catch (RemoteException e) {
15146            Slog.w(TAG, e);
15147        }
15148    }
15149
15150    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15151        if (app.instrumentationWatcher != null) {
15152            try {
15153                // NOTE:  IInstrumentationWatcher *must* be oneway here
15154                app.instrumentationWatcher.instrumentationFinished(
15155                    app.instrumentationClass,
15156                    resultCode,
15157                    results);
15158            } catch (RemoteException e) {
15159            }
15160        }
15161        if (app.instrumentationUiAutomationConnection != null) {
15162            try {
15163                app.instrumentationUiAutomationConnection.shutdown();
15164            } catch (RemoteException re) {
15165                /* ignore */
15166            }
15167            // Only a UiAutomation can set this flag and now that
15168            // it is finished we make sure it is reset to its default.
15169            mUserIsMonkey = false;
15170        }
15171        app.instrumentationWatcher = null;
15172        app.instrumentationUiAutomationConnection = null;
15173        app.instrumentationClass = null;
15174        app.instrumentationInfo = null;
15175        app.instrumentationProfileFile = null;
15176        app.instrumentationArguments = null;
15177
15178        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15179                "finished inst");
15180    }
15181
15182    public void finishInstrumentation(IApplicationThread target,
15183            int resultCode, Bundle results) {
15184        int userId = UserHandle.getCallingUserId();
15185        // Refuse possible leaked file descriptors
15186        if (results != null && results.hasFileDescriptors()) {
15187            throw new IllegalArgumentException("File descriptors passed in Intent");
15188        }
15189
15190        synchronized(this) {
15191            ProcessRecord app = getRecordForAppLocked(target);
15192            if (app == null) {
15193                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15194                return;
15195            }
15196            final long origId = Binder.clearCallingIdentity();
15197            finishInstrumentationLocked(app, resultCode, results);
15198            Binder.restoreCallingIdentity(origId);
15199        }
15200    }
15201
15202    // =========================================================
15203    // CONFIGURATION
15204    // =========================================================
15205
15206    public ConfigurationInfo getDeviceConfigurationInfo() {
15207        ConfigurationInfo config = new ConfigurationInfo();
15208        synchronized (this) {
15209            config.reqTouchScreen = mConfiguration.touchscreen;
15210            config.reqKeyboardType = mConfiguration.keyboard;
15211            config.reqNavigation = mConfiguration.navigation;
15212            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15213                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15214                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15215            }
15216            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15217                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15218                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15219            }
15220            config.reqGlEsVersion = GL_ES_VERSION;
15221        }
15222        return config;
15223    }
15224
15225    ActivityStack getFocusedStack() {
15226        return mStackSupervisor.getFocusedStack();
15227    }
15228
15229    public Configuration getConfiguration() {
15230        Configuration ci;
15231        synchronized(this) {
15232            ci = new Configuration(mConfiguration);
15233        }
15234        return ci;
15235    }
15236
15237    public void updatePersistentConfiguration(Configuration values) {
15238        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15239                "updateConfiguration()");
15240        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15241                "updateConfiguration()");
15242        if (values == null) {
15243            throw new NullPointerException("Configuration must not be null");
15244        }
15245
15246        synchronized(this) {
15247            final long origId = Binder.clearCallingIdentity();
15248            updateConfigurationLocked(values, null, true, false);
15249            Binder.restoreCallingIdentity(origId);
15250        }
15251    }
15252
15253    public void updateConfiguration(Configuration values) {
15254        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15255                "updateConfiguration()");
15256
15257        synchronized(this) {
15258            if (values == null && mWindowManager != null) {
15259                // sentinel: fetch the current configuration from the window manager
15260                values = mWindowManager.computeNewConfiguration();
15261            }
15262
15263            if (mWindowManager != null) {
15264                mProcessList.applyDisplaySize(mWindowManager);
15265            }
15266
15267            final long origId = Binder.clearCallingIdentity();
15268            if (values != null) {
15269                Settings.System.clearConfiguration(values);
15270            }
15271            updateConfigurationLocked(values, null, false, false);
15272            Binder.restoreCallingIdentity(origId);
15273        }
15274    }
15275
15276    /**
15277     * Do either or both things: (1) change the current configuration, and (2)
15278     * make sure the given activity is running with the (now) current
15279     * configuration.  Returns true if the activity has been left running, or
15280     * false if <var>starting</var> is being destroyed to match the new
15281     * configuration.
15282     * @param persistent TODO
15283     */
15284    boolean updateConfigurationLocked(Configuration values,
15285            ActivityRecord starting, boolean persistent, boolean initLocale) {
15286        int changes = 0;
15287
15288        if (values != null) {
15289            Configuration newConfig = new Configuration(mConfiguration);
15290            changes = newConfig.updateFrom(values);
15291            if (changes != 0) {
15292                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15293                    Slog.i(TAG, "Updating configuration to: " + values);
15294                }
15295
15296                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15297
15298                if (values.locale != null && !initLocale) {
15299                    saveLocaleLocked(values.locale,
15300                                     !values.locale.equals(mConfiguration.locale),
15301                                     values.userSetLocale);
15302                }
15303
15304                mConfigurationSeq++;
15305                if (mConfigurationSeq <= 0) {
15306                    mConfigurationSeq = 1;
15307                }
15308                newConfig.seq = mConfigurationSeq;
15309                mConfiguration = newConfig;
15310                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15311                //mUsageStatsService.noteStartConfig(newConfig);
15312
15313                final Configuration configCopy = new Configuration(mConfiguration);
15314
15315                // TODO: If our config changes, should we auto dismiss any currently
15316                // showing dialogs?
15317                mShowDialogs = shouldShowDialogs(newConfig);
15318
15319                AttributeCache ac = AttributeCache.instance();
15320                if (ac != null) {
15321                    ac.updateConfiguration(configCopy);
15322                }
15323
15324                // Make sure all resources in our process are updated
15325                // right now, so that anyone who is going to retrieve
15326                // resource values after we return will be sure to get
15327                // the new ones.  This is especially important during
15328                // boot, where the first config change needs to guarantee
15329                // all resources have that config before following boot
15330                // code is executed.
15331                mSystemThread.applyConfigurationToResources(configCopy);
15332
15333                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15334                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15335                    msg.obj = new Configuration(configCopy);
15336                    mHandler.sendMessage(msg);
15337                }
15338
15339                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15340                    ProcessRecord app = mLruProcesses.get(i);
15341                    try {
15342                        if (app.thread != null) {
15343                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15344                                    + app.processName + " new config " + mConfiguration);
15345                            app.thread.scheduleConfigurationChanged(configCopy);
15346                        }
15347                    } catch (Exception e) {
15348                    }
15349                }
15350                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15351                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15352                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15353                        | Intent.FLAG_RECEIVER_FOREGROUND);
15354                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15355                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15356                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15357                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15358                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15359                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15360                    broadcastIntentLocked(null, null, intent,
15361                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15362                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15363                }
15364            }
15365        }
15366
15367        boolean kept = true;
15368        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15369        // mainStack is null during startup.
15370        if (mainStack != null) {
15371            if (changes != 0 && starting == null) {
15372                // If the configuration changed, and the caller is not already
15373                // in the process of starting an activity, then find the top
15374                // activity to check if its configuration needs to change.
15375                starting = mainStack.topRunningActivityLocked(null);
15376            }
15377
15378            if (starting != null) {
15379                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15380                // And we need to make sure at this point that all other activities
15381                // are made visible with the correct configuration.
15382                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15383            }
15384        }
15385
15386        if (values != null && mWindowManager != null) {
15387            mWindowManager.setNewConfiguration(mConfiguration);
15388        }
15389
15390        return kept;
15391    }
15392
15393    /**
15394     * Decide based on the configuration whether we should shouw the ANR,
15395     * crash, etc dialogs.  The idea is that if there is no affordnace to
15396     * press the on-screen buttons, we shouldn't show the dialog.
15397     *
15398     * A thought: SystemUI might also want to get told about this, the Power
15399     * dialog / global actions also might want different behaviors.
15400     */
15401    private static final boolean shouldShowDialogs(Configuration config) {
15402        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15403                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15404    }
15405
15406    /**
15407     * Save the locale.  You must be inside a synchronized (this) block.
15408     */
15409    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15410        if(isDiff) {
15411            SystemProperties.set("user.language", l.getLanguage());
15412            SystemProperties.set("user.region", l.getCountry());
15413        }
15414
15415        if(isPersist) {
15416            SystemProperties.set("persist.sys.language", l.getLanguage());
15417            SystemProperties.set("persist.sys.country", l.getCountry());
15418            SystemProperties.set("persist.sys.localevar", l.getVariant());
15419        }
15420    }
15421
15422    @Override
15423    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15424        ActivityRecord srec = ActivityRecord.forToken(token);
15425        return srec != null && srec.task.affinity != null &&
15426                srec.task.affinity.equals(destAffinity);
15427    }
15428
15429    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15430            Intent resultData) {
15431
15432        synchronized (this) {
15433            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15434            if (stack != null) {
15435                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15436            }
15437            return false;
15438        }
15439    }
15440
15441    public int getLaunchedFromUid(IBinder activityToken) {
15442        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15443        if (srec == null) {
15444            return -1;
15445        }
15446        return srec.launchedFromUid;
15447    }
15448
15449    public String getLaunchedFromPackage(IBinder activityToken) {
15450        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15451        if (srec == null) {
15452            return null;
15453        }
15454        return srec.launchedFromPackage;
15455    }
15456
15457    // =========================================================
15458    // LIFETIME MANAGEMENT
15459    // =========================================================
15460
15461    // Returns which broadcast queue the app is the current [or imminent] receiver
15462    // on, or 'null' if the app is not an active broadcast recipient.
15463    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15464        BroadcastRecord r = app.curReceiver;
15465        if (r != null) {
15466            return r.queue;
15467        }
15468
15469        // It's not the current receiver, but it might be starting up to become one
15470        synchronized (this) {
15471            for (BroadcastQueue queue : mBroadcastQueues) {
15472                r = queue.mPendingBroadcast;
15473                if (r != null && r.curApp == app) {
15474                    // found it; report which queue it's in
15475                    return queue;
15476                }
15477            }
15478        }
15479
15480        return null;
15481    }
15482
15483    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15484            boolean doingAll, long now) {
15485        if (mAdjSeq == app.adjSeq) {
15486            // This adjustment has already been computed.
15487            return app.curRawAdj;
15488        }
15489
15490        if (app.thread == null) {
15491            app.adjSeq = mAdjSeq;
15492            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15493            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15494            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15495        }
15496
15497        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15498        app.adjSource = null;
15499        app.adjTarget = null;
15500        app.empty = false;
15501        app.cached = false;
15502
15503        final int activitiesSize = app.activities.size();
15504
15505        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15506            // The max adjustment doesn't allow this app to be anything
15507            // below foreground, so it is not worth doing work for it.
15508            app.adjType = "fixed";
15509            app.adjSeq = mAdjSeq;
15510            app.curRawAdj = app.maxAdj;
15511            app.foregroundActivities = false;
15512            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15513            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15514            // System processes can do UI, and when they do we want to have
15515            // them trim their memory after the user leaves the UI.  To
15516            // facilitate this, here we need to determine whether or not it
15517            // is currently showing UI.
15518            app.systemNoUi = true;
15519            if (app == TOP_APP) {
15520                app.systemNoUi = false;
15521            } else if (activitiesSize > 0) {
15522                for (int j = 0; j < activitiesSize; j++) {
15523                    final ActivityRecord r = app.activities.get(j);
15524                    if (r.visible) {
15525                        app.systemNoUi = false;
15526                    }
15527                }
15528            }
15529            if (!app.systemNoUi) {
15530                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15531            }
15532            return (app.curAdj=app.maxAdj);
15533        }
15534
15535        app.systemNoUi = false;
15536
15537        // Determine the importance of the process, starting with most
15538        // important to least, and assign an appropriate OOM adjustment.
15539        int adj;
15540        int schedGroup;
15541        int procState;
15542        boolean foregroundActivities = false;
15543        BroadcastQueue queue;
15544        if (app == TOP_APP) {
15545            // The last app on the list is the foreground app.
15546            adj = ProcessList.FOREGROUND_APP_ADJ;
15547            schedGroup = Process.THREAD_GROUP_DEFAULT;
15548            app.adjType = "top-activity";
15549            foregroundActivities = true;
15550            procState = ActivityManager.PROCESS_STATE_TOP;
15551        } else if (app.instrumentationClass != null) {
15552            // Don't want to kill running instrumentation.
15553            adj = ProcessList.FOREGROUND_APP_ADJ;
15554            schedGroup = Process.THREAD_GROUP_DEFAULT;
15555            app.adjType = "instrumentation";
15556            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15557        } else if ((queue = isReceivingBroadcast(app)) != null) {
15558            // An app that is currently receiving a broadcast also
15559            // counts as being in the foreground for OOM killer purposes.
15560            // It's placed in a sched group based on the nature of the
15561            // broadcast as reflected by which queue it's active in.
15562            adj = ProcessList.FOREGROUND_APP_ADJ;
15563            schedGroup = (queue == mFgBroadcastQueue)
15564                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15565            app.adjType = "broadcast";
15566            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15567        } else if (app.executingServices.size() > 0) {
15568            // An app that is currently executing a service callback also
15569            // counts as being in the foreground.
15570            adj = ProcessList.FOREGROUND_APP_ADJ;
15571            schedGroup = app.execServicesFg ?
15572                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15573            app.adjType = "exec-service";
15574            procState = ActivityManager.PROCESS_STATE_SERVICE;
15575            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15576        } else {
15577            // As far as we know the process is empty.  We may change our mind later.
15578            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15579            // At this point we don't actually know the adjustment.  Use the cached adj
15580            // value that the caller wants us to.
15581            adj = cachedAdj;
15582            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15583            app.cached = true;
15584            app.empty = true;
15585            app.adjType = "cch-empty";
15586        }
15587
15588        // Examine all activities if not already foreground.
15589        if (!foregroundActivities && activitiesSize > 0) {
15590            for (int j = 0; j < activitiesSize; j++) {
15591                final ActivityRecord r = app.activities.get(j);
15592                if (r.app != app) {
15593                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15594                            + app + "?!?");
15595                    continue;
15596                }
15597                if (r.visible) {
15598                    // App has a visible activity; only upgrade adjustment.
15599                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15600                        adj = ProcessList.VISIBLE_APP_ADJ;
15601                        app.adjType = "visible";
15602                    }
15603                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15604                        procState = ActivityManager.PROCESS_STATE_TOP;
15605                    }
15606                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15607                    app.cached = false;
15608                    app.empty = false;
15609                    foregroundActivities = true;
15610                    break;
15611                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15612                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15613                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15614                        app.adjType = "pausing";
15615                    }
15616                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15617                        procState = ActivityManager.PROCESS_STATE_TOP;
15618                    }
15619                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15620                    app.cached = false;
15621                    app.empty = false;
15622                    foregroundActivities = true;
15623                } else if (r.state == ActivityState.STOPPING) {
15624                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15625                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15626                        app.adjType = "stopping";
15627                    }
15628                    // For the process state, we will at this point consider the
15629                    // process to be cached.  It will be cached either as an activity
15630                    // or empty depending on whether the activity is finishing.  We do
15631                    // this so that we can treat the process as cached for purposes of
15632                    // memory trimming (determing current memory level, trim command to
15633                    // send to process) since there can be an arbitrary number of stopping
15634                    // processes and they should soon all go into the cached state.
15635                    if (!r.finishing) {
15636                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15637                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15638                        }
15639                    }
15640                    app.cached = false;
15641                    app.empty = false;
15642                    foregroundActivities = true;
15643                } else {
15644                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15645                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15646                        app.adjType = "cch-act";
15647                    }
15648                }
15649            }
15650        }
15651
15652        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15653            if (app.foregroundServices) {
15654                // The user is aware of this app, so make it visible.
15655                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15656                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15657                app.cached = false;
15658                app.adjType = "fg-service";
15659                schedGroup = Process.THREAD_GROUP_DEFAULT;
15660            } else if (app.forcingToForeground != null) {
15661                // The user is aware of this app, so make it visible.
15662                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15663                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15664                app.cached = false;
15665                app.adjType = "force-fg";
15666                app.adjSource = app.forcingToForeground;
15667                schedGroup = Process.THREAD_GROUP_DEFAULT;
15668            }
15669        }
15670
15671        if (app == mHeavyWeightProcess) {
15672            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15673                // We don't want to kill the current heavy-weight process.
15674                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15675                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15676                app.cached = false;
15677                app.adjType = "heavy";
15678            }
15679            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15680                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15681            }
15682        }
15683
15684        if (app == mHomeProcess) {
15685            if (adj > ProcessList.HOME_APP_ADJ) {
15686                // This process is hosting what we currently consider to be the
15687                // home app, so we don't want to let it go into the background.
15688                adj = ProcessList.HOME_APP_ADJ;
15689                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15690                app.cached = false;
15691                app.adjType = "home";
15692            }
15693            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15694                procState = ActivityManager.PROCESS_STATE_HOME;
15695            }
15696        }
15697
15698        if (app == mPreviousProcess && app.activities.size() > 0) {
15699            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15700                // This was the previous process that showed UI to the user.
15701                // We want to try to keep it around more aggressively, to give
15702                // a good experience around switching between two apps.
15703                adj = ProcessList.PREVIOUS_APP_ADJ;
15704                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15705                app.cached = false;
15706                app.adjType = "previous";
15707            }
15708            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15709                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15710            }
15711        }
15712
15713        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15714                + " reason=" + app.adjType);
15715
15716        // By default, we use the computed adjustment.  It may be changed if
15717        // there are applications dependent on our services or providers, but
15718        // this gives us a baseline and makes sure we don't get into an
15719        // infinite recursion.
15720        app.adjSeq = mAdjSeq;
15721        app.curRawAdj = adj;
15722        app.hasStartedServices = false;
15723
15724        if (mBackupTarget != null && app == mBackupTarget.app) {
15725            // If possible we want to avoid killing apps while they're being backed up
15726            if (adj > ProcessList.BACKUP_APP_ADJ) {
15727                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15728                adj = ProcessList.BACKUP_APP_ADJ;
15729                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15730                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15731                }
15732                app.adjType = "backup";
15733                app.cached = false;
15734            }
15735            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15736                procState = ActivityManager.PROCESS_STATE_BACKUP;
15737            }
15738        }
15739
15740        boolean mayBeTop = false;
15741
15742        for (int is = app.services.size()-1;
15743                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15744                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15745                        || procState > ActivityManager.PROCESS_STATE_TOP);
15746                is--) {
15747            ServiceRecord s = app.services.valueAt(is);
15748            if (s.startRequested) {
15749                app.hasStartedServices = true;
15750                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15751                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15752                }
15753                if (app.hasShownUi && app != mHomeProcess) {
15754                    // If this process has shown some UI, let it immediately
15755                    // go to the LRU list because it may be pretty heavy with
15756                    // UI stuff.  We'll tag it with a label just to help
15757                    // debug and understand what is going on.
15758                    if (adj > ProcessList.SERVICE_ADJ) {
15759                        app.adjType = "cch-started-ui-services";
15760                    }
15761                } else {
15762                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15763                        // This service has seen some activity within
15764                        // recent memory, so we will keep its process ahead
15765                        // of the background processes.
15766                        if (adj > ProcessList.SERVICE_ADJ) {
15767                            adj = ProcessList.SERVICE_ADJ;
15768                            app.adjType = "started-services";
15769                            app.cached = false;
15770                        }
15771                    }
15772                    // If we have let the service slide into the background
15773                    // state, still have some text describing what it is doing
15774                    // even though the service no longer has an impact.
15775                    if (adj > ProcessList.SERVICE_ADJ) {
15776                        app.adjType = "cch-started-services";
15777                    }
15778                }
15779            }
15780            for (int conni = s.connections.size()-1;
15781                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15782                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15783                            || procState > ActivityManager.PROCESS_STATE_TOP);
15784                    conni--) {
15785                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15786                for (int i = 0;
15787                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15788                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15789                                || procState > ActivityManager.PROCESS_STATE_TOP);
15790                        i++) {
15791                    // XXX should compute this based on the max of
15792                    // all connected clients.
15793                    ConnectionRecord cr = clist.get(i);
15794                    if (cr.binding.client == app) {
15795                        // Binding to ourself is not interesting.
15796                        continue;
15797                    }
15798                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15799                        ProcessRecord client = cr.binding.client;
15800                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15801                                TOP_APP, doingAll, now);
15802                        int clientProcState = client.curProcState;
15803                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15804                            // If the other app is cached for any reason, for purposes here
15805                            // we are going to consider it empty.  The specific cached state
15806                            // doesn't propagate except under certain conditions.
15807                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15808                        }
15809                        String adjType = null;
15810                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15811                            // Not doing bind OOM management, so treat
15812                            // this guy more like a started service.
15813                            if (app.hasShownUi && app != mHomeProcess) {
15814                                // If this process has shown some UI, let it immediately
15815                                // go to the LRU list because it may be pretty heavy with
15816                                // UI stuff.  We'll tag it with a label just to help
15817                                // debug and understand what is going on.
15818                                if (adj > clientAdj) {
15819                                    adjType = "cch-bound-ui-services";
15820                                }
15821                                app.cached = false;
15822                                clientAdj = adj;
15823                                clientProcState = procState;
15824                            } else {
15825                                if (now >= (s.lastActivity
15826                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15827                                    // This service has not seen activity within
15828                                    // recent memory, so allow it to drop to the
15829                                    // LRU list if there is no other reason to keep
15830                                    // it around.  We'll also tag it with a label just
15831                                    // to help debug and undertand what is going on.
15832                                    if (adj > clientAdj) {
15833                                        adjType = "cch-bound-services";
15834                                    }
15835                                    clientAdj = adj;
15836                                }
15837                            }
15838                        }
15839                        if (adj > clientAdj) {
15840                            // If this process has recently shown UI, and
15841                            // the process that is binding to it is less
15842                            // important than being visible, then we don't
15843                            // care about the binding as much as we care
15844                            // about letting this process get into the LRU
15845                            // list to be killed and restarted if needed for
15846                            // memory.
15847                            if (app.hasShownUi && app != mHomeProcess
15848                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15849                                adjType = "cch-bound-ui-services";
15850                            } else {
15851                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15852                                        |Context.BIND_IMPORTANT)) != 0) {
15853                                    adj = clientAdj;
15854                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15855                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15856                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15857                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15858                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15859                                    adj = clientAdj;
15860                                } else {
15861                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15862                                        adj = ProcessList.VISIBLE_APP_ADJ;
15863                                    }
15864                                }
15865                                if (!client.cached) {
15866                                    app.cached = false;
15867                                }
15868                                adjType = "service";
15869                            }
15870                        }
15871                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15872                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15873                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15874                            }
15875                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15876                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15877                                    // Special handling of clients who are in the top state.
15878                                    // We *may* want to consider this process to be in the
15879                                    // top state as well, but only if there is not another
15880                                    // reason for it to be running.  Being on the top is a
15881                                    // special state, meaning you are specifically running
15882                                    // for the current top app.  If the process is already
15883                                    // running in the background for some other reason, it
15884                                    // is more important to continue considering it to be
15885                                    // in the background state.
15886                                    mayBeTop = true;
15887                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15888                                } else {
15889                                    // Special handling for above-top states (persistent
15890                                    // processes).  These should not bring the current process
15891                                    // into the top state, since they are not on top.  Instead
15892                                    // give them the best state after that.
15893                                    clientProcState =
15894                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15895                                }
15896                            }
15897                        } else {
15898                            if (clientProcState <
15899                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15900                                clientProcState =
15901                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15902                            }
15903                        }
15904                        if (procState > clientProcState) {
15905                            procState = clientProcState;
15906                        }
15907                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15908                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15909                            app.pendingUiClean = true;
15910                        }
15911                        if (adjType != null) {
15912                            app.adjType = adjType;
15913                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15914                                    .REASON_SERVICE_IN_USE;
15915                            app.adjSource = cr.binding.client;
15916                            app.adjSourceProcState = clientProcState;
15917                            app.adjTarget = s.name;
15918                        }
15919                    }
15920                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15921                        app.treatLikeActivity = true;
15922                    }
15923                    final ActivityRecord a = cr.activity;
15924                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15925                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15926                                (a.visible || a.state == ActivityState.RESUMED
15927                                 || a.state == ActivityState.PAUSING)) {
15928                            adj = ProcessList.FOREGROUND_APP_ADJ;
15929                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15930                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15931                            }
15932                            app.cached = false;
15933                            app.adjType = "service";
15934                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15935                                    .REASON_SERVICE_IN_USE;
15936                            app.adjSource = a;
15937                            app.adjSourceProcState = procState;
15938                            app.adjTarget = s.name;
15939                        }
15940                    }
15941                }
15942            }
15943        }
15944
15945        for (int provi = app.pubProviders.size()-1;
15946                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15947                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15948                        || procState > ActivityManager.PROCESS_STATE_TOP);
15949                provi--) {
15950            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15951            for (int i = cpr.connections.size()-1;
15952                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15953                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15954                            || procState > ActivityManager.PROCESS_STATE_TOP);
15955                    i--) {
15956                ContentProviderConnection conn = cpr.connections.get(i);
15957                ProcessRecord client = conn.client;
15958                if (client == app) {
15959                    // Being our own client is not interesting.
15960                    continue;
15961                }
15962                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15963                int clientProcState = client.curProcState;
15964                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15965                    // If the other app is cached for any reason, for purposes here
15966                    // we are going to consider it empty.
15967                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15968                }
15969                if (adj > clientAdj) {
15970                    if (app.hasShownUi && app != mHomeProcess
15971                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15972                        app.adjType = "cch-ui-provider";
15973                    } else {
15974                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15975                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15976                        app.adjType = "provider";
15977                    }
15978                    app.cached &= client.cached;
15979                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15980                            .REASON_PROVIDER_IN_USE;
15981                    app.adjSource = client;
15982                    app.adjSourceProcState = clientProcState;
15983                    app.adjTarget = cpr.name;
15984                }
15985                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15986                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15987                        // Special handling of clients who are in the top state.
15988                        // We *may* want to consider this process to be in the
15989                        // top state as well, but only if there is not another
15990                        // reason for it to be running.  Being on the top is a
15991                        // special state, meaning you are specifically running
15992                        // for the current top app.  If the process is already
15993                        // running in the background for some other reason, it
15994                        // is more important to continue considering it to be
15995                        // in the background state.
15996                        mayBeTop = true;
15997                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15998                    } else {
15999                        // Special handling for above-top states (persistent
16000                        // processes).  These should not bring the current process
16001                        // into the top state, since they are not on top.  Instead
16002                        // give them the best state after that.
16003                        clientProcState =
16004                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16005                    }
16006                }
16007                if (procState > clientProcState) {
16008                    procState = clientProcState;
16009                }
16010                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16011                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16012                }
16013            }
16014            // If the provider has external (non-framework) process
16015            // dependencies, ensure that its adjustment is at least
16016            // FOREGROUND_APP_ADJ.
16017            if (cpr.hasExternalProcessHandles()) {
16018                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16019                    adj = ProcessList.FOREGROUND_APP_ADJ;
16020                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16021                    app.cached = false;
16022                    app.adjType = "provider";
16023                    app.adjTarget = cpr.name;
16024                }
16025                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16026                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16027                }
16028            }
16029        }
16030
16031        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16032            // A client of one of our services or providers is in the top state.  We
16033            // *may* want to be in the top state, but not if we are already running in
16034            // the background for some other reason.  For the decision here, we are going
16035            // to pick out a few specific states that we want to remain in when a client
16036            // is top (states that tend to be longer-term) and otherwise allow it to go
16037            // to the top state.
16038            switch (procState) {
16039                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16040                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16041                case ActivityManager.PROCESS_STATE_SERVICE:
16042                    // These all are longer-term states, so pull them up to the top
16043                    // of the background states, but not all the way to the top state.
16044                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16045                    break;
16046                default:
16047                    // Otherwise, top is a better choice, so take it.
16048                    procState = ActivityManager.PROCESS_STATE_TOP;
16049                    break;
16050            }
16051        }
16052
16053        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16054            if (app.hasClientActivities) {
16055                // This is a cached process, but with client activities.  Mark it so.
16056                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16057                app.adjType = "cch-client-act";
16058            } else if (app.treatLikeActivity) {
16059                // This is a cached process, but somebody wants us to treat it like it has
16060                // an activity, okay!
16061                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16062                app.adjType = "cch-as-act";
16063            }
16064        }
16065
16066        if (adj == ProcessList.SERVICE_ADJ) {
16067            if (doingAll) {
16068                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16069                mNewNumServiceProcs++;
16070                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16071                if (!app.serviceb) {
16072                    // This service isn't far enough down on the LRU list to
16073                    // normally be a B service, but if we are low on RAM and it
16074                    // is large we want to force it down since we would prefer to
16075                    // keep launcher over it.
16076                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16077                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16078                        app.serviceHighRam = true;
16079                        app.serviceb = true;
16080                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16081                    } else {
16082                        mNewNumAServiceProcs++;
16083                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16084                    }
16085                } else {
16086                    app.serviceHighRam = false;
16087                }
16088            }
16089            if (app.serviceb) {
16090                adj = ProcessList.SERVICE_B_ADJ;
16091            }
16092        }
16093
16094        app.curRawAdj = adj;
16095
16096        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16097        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16098        if (adj > app.maxAdj) {
16099            adj = app.maxAdj;
16100            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16101                schedGroup = Process.THREAD_GROUP_DEFAULT;
16102            }
16103        }
16104
16105        // Do final modification to adj.  Everything we do between here and applying
16106        // the final setAdj must be done in this function, because we will also use
16107        // it when computing the final cached adj later.  Note that we don't need to
16108        // worry about this for max adj above, since max adj will always be used to
16109        // keep it out of the cached vaues.
16110        app.curAdj = app.modifyRawOomAdj(adj);
16111        app.curSchedGroup = schedGroup;
16112        app.curProcState = procState;
16113        app.foregroundActivities = foregroundActivities;
16114
16115        return app.curRawAdj;
16116    }
16117
16118    /**
16119     * Schedule PSS collection of a process.
16120     */
16121    void requestPssLocked(ProcessRecord proc, int procState) {
16122        if (mPendingPssProcesses.contains(proc)) {
16123            return;
16124        }
16125        if (mPendingPssProcesses.size() == 0) {
16126            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16127        }
16128        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16129        proc.pssProcState = procState;
16130        mPendingPssProcesses.add(proc);
16131    }
16132
16133    /**
16134     * Schedule PSS collection of all processes.
16135     */
16136    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16137        if (!always) {
16138            if (now < (mLastFullPssTime +
16139                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16140                return;
16141            }
16142        }
16143        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16144        mLastFullPssTime = now;
16145        mFullPssPending = true;
16146        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16147        mPendingPssProcesses.clear();
16148        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16149            ProcessRecord app = mLruProcesses.get(i);
16150            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16151                app.pssProcState = app.setProcState;
16152                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16153                        isSleeping(), now);
16154                mPendingPssProcesses.add(app);
16155            }
16156        }
16157        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16158    }
16159
16160    /**
16161     * Ask a given process to GC right now.
16162     */
16163    final void performAppGcLocked(ProcessRecord app) {
16164        try {
16165            app.lastRequestedGc = SystemClock.uptimeMillis();
16166            if (app.thread != null) {
16167                if (app.reportLowMemory) {
16168                    app.reportLowMemory = false;
16169                    app.thread.scheduleLowMemory();
16170                } else {
16171                    app.thread.processInBackground();
16172                }
16173            }
16174        } catch (Exception e) {
16175            // whatever.
16176        }
16177    }
16178
16179    /**
16180     * Returns true if things are idle enough to perform GCs.
16181     */
16182    private final boolean canGcNowLocked() {
16183        boolean processingBroadcasts = false;
16184        for (BroadcastQueue q : mBroadcastQueues) {
16185            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16186                processingBroadcasts = true;
16187            }
16188        }
16189        return !processingBroadcasts
16190                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16191    }
16192
16193    /**
16194     * Perform GCs on all processes that are waiting for it, but only
16195     * if things are idle.
16196     */
16197    final void performAppGcsLocked() {
16198        final int N = mProcessesToGc.size();
16199        if (N <= 0) {
16200            return;
16201        }
16202        if (canGcNowLocked()) {
16203            while (mProcessesToGc.size() > 0) {
16204                ProcessRecord proc = mProcessesToGc.remove(0);
16205                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16206                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16207                            <= SystemClock.uptimeMillis()) {
16208                        // To avoid spamming the system, we will GC processes one
16209                        // at a time, waiting a few seconds between each.
16210                        performAppGcLocked(proc);
16211                        scheduleAppGcsLocked();
16212                        return;
16213                    } else {
16214                        // It hasn't been long enough since we last GCed this
16215                        // process...  put it in the list to wait for its time.
16216                        addProcessToGcListLocked(proc);
16217                        break;
16218                    }
16219                }
16220            }
16221
16222            scheduleAppGcsLocked();
16223        }
16224    }
16225
16226    /**
16227     * If all looks good, perform GCs on all processes waiting for them.
16228     */
16229    final void performAppGcsIfAppropriateLocked() {
16230        if (canGcNowLocked()) {
16231            performAppGcsLocked();
16232            return;
16233        }
16234        // Still not idle, wait some more.
16235        scheduleAppGcsLocked();
16236    }
16237
16238    /**
16239     * Schedule the execution of all pending app GCs.
16240     */
16241    final void scheduleAppGcsLocked() {
16242        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16243
16244        if (mProcessesToGc.size() > 0) {
16245            // Schedule a GC for the time to the next process.
16246            ProcessRecord proc = mProcessesToGc.get(0);
16247            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16248
16249            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16250            long now = SystemClock.uptimeMillis();
16251            if (when < (now+GC_TIMEOUT)) {
16252                when = now + GC_TIMEOUT;
16253            }
16254            mHandler.sendMessageAtTime(msg, when);
16255        }
16256    }
16257
16258    /**
16259     * Add a process to the array of processes waiting to be GCed.  Keeps the
16260     * list in sorted order by the last GC time.  The process can't already be
16261     * on the list.
16262     */
16263    final void addProcessToGcListLocked(ProcessRecord proc) {
16264        boolean added = false;
16265        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16266            if (mProcessesToGc.get(i).lastRequestedGc <
16267                    proc.lastRequestedGc) {
16268                added = true;
16269                mProcessesToGc.add(i+1, proc);
16270                break;
16271            }
16272        }
16273        if (!added) {
16274            mProcessesToGc.add(0, proc);
16275        }
16276    }
16277
16278    /**
16279     * Set up to ask a process to GC itself.  This will either do it
16280     * immediately, or put it on the list of processes to gc the next
16281     * time things are idle.
16282     */
16283    final void scheduleAppGcLocked(ProcessRecord app) {
16284        long now = SystemClock.uptimeMillis();
16285        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16286            return;
16287        }
16288        if (!mProcessesToGc.contains(app)) {
16289            addProcessToGcListLocked(app);
16290            scheduleAppGcsLocked();
16291        }
16292    }
16293
16294    final void checkExcessivePowerUsageLocked(boolean doKills) {
16295        updateCpuStatsNow();
16296
16297        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16298        boolean doWakeKills = doKills;
16299        boolean doCpuKills = doKills;
16300        if (mLastPowerCheckRealtime == 0) {
16301            doWakeKills = false;
16302        }
16303        if (mLastPowerCheckUptime == 0) {
16304            doCpuKills = false;
16305        }
16306        if (stats.isScreenOn()) {
16307            doWakeKills = false;
16308        }
16309        final long curRealtime = SystemClock.elapsedRealtime();
16310        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16311        final long curUptime = SystemClock.uptimeMillis();
16312        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16313        mLastPowerCheckRealtime = curRealtime;
16314        mLastPowerCheckUptime = curUptime;
16315        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16316            doWakeKills = false;
16317        }
16318        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16319            doCpuKills = false;
16320        }
16321        int i = mLruProcesses.size();
16322        while (i > 0) {
16323            i--;
16324            ProcessRecord app = mLruProcesses.get(i);
16325            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16326                long wtime;
16327                synchronized (stats) {
16328                    wtime = stats.getProcessWakeTime(app.info.uid,
16329                            app.pid, curRealtime);
16330                }
16331                long wtimeUsed = wtime - app.lastWakeTime;
16332                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16333                if (DEBUG_POWER) {
16334                    StringBuilder sb = new StringBuilder(128);
16335                    sb.append("Wake for ");
16336                    app.toShortString(sb);
16337                    sb.append(": over ");
16338                    TimeUtils.formatDuration(realtimeSince, sb);
16339                    sb.append(" used ");
16340                    TimeUtils.formatDuration(wtimeUsed, sb);
16341                    sb.append(" (");
16342                    sb.append((wtimeUsed*100)/realtimeSince);
16343                    sb.append("%)");
16344                    Slog.i(TAG, sb.toString());
16345                    sb.setLength(0);
16346                    sb.append("CPU for ");
16347                    app.toShortString(sb);
16348                    sb.append(": over ");
16349                    TimeUtils.formatDuration(uptimeSince, sb);
16350                    sb.append(" used ");
16351                    TimeUtils.formatDuration(cputimeUsed, sb);
16352                    sb.append(" (");
16353                    sb.append((cputimeUsed*100)/uptimeSince);
16354                    sb.append("%)");
16355                    Slog.i(TAG, sb.toString());
16356                }
16357                // If a process has held a wake lock for more
16358                // than 50% of the time during this period,
16359                // that sounds bad.  Kill!
16360                if (doWakeKills && realtimeSince > 0
16361                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16362                    synchronized (stats) {
16363                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16364                                realtimeSince, wtimeUsed);
16365                    }
16366                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16367                            + " during " + realtimeSince);
16368                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16369                } else if (doCpuKills && uptimeSince > 0
16370                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16371                    synchronized (stats) {
16372                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16373                                uptimeSince, cputimeUsed);
16374                    }
16375                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16376                            + " during " + uptimeSince);
16377                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16378                } else {
16379                    app.lastWakeTime = wtime;
16380                    app.lastCpuTime = app.curCpuTime;
16381                }
16382            }
16383        }
16384    }
16385
16386    private final boolean applyOomAdjLocked(ProcessRecord app,
16387            ProcessRecord TOP_APP, boolean doingAll, long now) {
16388        boolean success = true;
16389
16390        if (app.curRawAdj != app.setRawAdj) {
16391            app.setRawAdj = app.curRawAdj;
16392        }
16393
16394        int changes = 0;
16395
16396        if (app.curAdj != app.setAdj) {
16397            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16398            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16399                TAG, "Set " + app.pid + " " + app.processName +
16400                " adj " + app.curAdj + ": " + app.adjType);
16401            app.setAdj = app.curAdj;
16402        }
16403
16404        if (app.setSchedGroup != app.curSchedGroup) {
16405            app.setSchedGroup = app.curSchedGroup;
16406            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16407                    "Setting process group of " + app.processName
16408                    + " to " + app.curSchedGroup);
16409            if (app.waitingToKill != null &&
16410                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16411                killUnneededProcessLocked(app, app.waitingToKill);
16412                success = false;
16413            } else {
16414                if (true) {
16415                    long oldId = Binder.clearCallingIdentity();
16416                    try {
16417                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16418                    } catch (Exception e) {
16419                        Slog.w(TAG, "Failed setting process group of " + app.pid
16420                                + " to " + app.curSchedGroup);
16421                        e.printStackTrace();
16422                    } finally {
16423                        Binder.restoreCallingIdentity(oldId);
16424                    }
16425                } else {
16426                    if (app.thread != null) {
16427                        try {
16428                            app.thread.setSchedulingGroup(app.curSchedGroup);
16429                        } catch (RemoteException e) {
16430                        }
16431                    }
16432                }
16433                Process.setSwappiness(app.pid,
16434                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16435            }
16436        }
16437        if (app.repForegroundActivities != app.foregroundActivities) {
16438            app.repForegroundActivities = app.foregroundActivities;
16439            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16440        }
16441        if (app.repProcState != app.curProcState) {
16442            app.repProcState = app.curProcState;
16443            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16444            if (app.thread != null) {
16445                try {
16446                    if (false) {
16447                        //RuntimeException h = new RuntimeException("here");
16448                        Slog.i(TAG, "Sending new process state " + app.repProcState
16449                                + " to " + app /*, h*/);
16450                    }
16451                    app.thread.setProcessState(app.repProcState);
16452                } catch (RemoteException e) {
16453                }
16454            }
16455        }
16456        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16457                app.setProcState)) {
16458            app.lastStateTime = now;
16459            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16460                    isSleeping(), now);
16461            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16462                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16463                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16464                    + (app.nextPssTime-now) + ": " + app);
16465        } else {
16466            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16467                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16468                requestPssLocked(app, app.setProcState);
16469                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16470                        isSleeping(), now);
16471            } else if (false && DEBUG_PSS) {
16472                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16473            }
16474        }
16475        if (app.setProcState != app.curProcState) {
16476            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16477                    "Proc state change of " + app.processName
16478                    + " to " + app.curProcState);
16479            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16480            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16481            if (setImportant && !curImportant) {
16482                // This app is no longer something we consider important enough to allow to
16483                // use arbitrary amounts of battery power.  Note
16484                // its current wake lock time to later know to kill it if
16485                // it is not behaving well.
16486                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16487                synchronized (stats) {
16488                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16489                            app.pid, SystemClock.elapsedRealtime());
16490                }
16491                app.lastCpuTime = app.curCpuTime;
16492
16493            }
16494            app.setProcState = app.curProcState;
16495            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16496                app.notCachedSinceIdle = false;
16497            }
16498            if (!doingAll) {
16499                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16500            } else {
16501                app.procStateChanged = true;
16502            }
16503        }
16504
16505        if (changes != 0) {
16506            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16507            int i = mPendingProcessChanges.size()-1;
16508            ProcessChangeItem item = null;
16509            while (i >= 0) {
16510                item = mPendingProcessChanges.get(i);
16511                if (item.pid == app.pid) {
16512                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16513                    break;
16514                }
16515                i--;
16516            }
16517            if (i < 0) {
16518                // No existing item in pending changes; need a new one.
16519                final int NA = mAvailProcessChanges.size();
16520                if (NA > 0) {
16521                    item = mAvailProcessChanges.remove(NA-1);
16522                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16523                } else {
16524                    item = new ProcessChangeItem();
16525                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16526                }
16527                item.changes = 0;
16528                item.pid = app.pid;
16529                item.uid = app.info.uid;
16530                if (mPendingProcessChanges.size() == 0) {
16531                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16532                            "*** Enqueueing dispatch processes changed!");
16533                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16534                }
16535                mPendingProcessChanges.add(item);
16536            }
16537            item.changes |= changes;
16538            item.processState = app.repProcState;
16539            item.foregroundActivities = app.repForegroundActivities;
16540            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16541                    + Integer.toHexString(System.identityHashCode(item))
16542                    + " " + app.toShortString() + ": changes=" + item.changes
16543                    + " procState=" + item.processState
16544                    + " foreground=" + item.foregroundActivities
16545                    + " type=" + app.adjType + " source=" + app.adjSource
16546                    + " target=" + app.adjTarget);
16547        }
16548
16549        return success;
16550    }
16551
16552    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16553        if (proc.thread != null) {
16554            if (proc.baseProcessTracker != null) {
16555                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16556            }
16557            if (proc.repProcState >= 0) {
16558                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16559                        proc.repProcState);
16560            }
16561        }
16562    }
16563
16564    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16565            ProcessRecord TOP_APP, boolean doingAll, long now) {
16566        if (app.thread == null) {
16567            return false;
16568        }
16569
16570        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16571
16572        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16573    }
16574
16575    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16576            boolean oomAdj) {
16577        if (isForeground != proc.foregroundServices) {
16578            proc.foregroundServices = isForeground;
16579            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16580                    proc.info.uid);
16581            if (isForeground) {
16582                if (curProcs == null) {
16583                    curProcs = new ArrayList<ProcessRecord>();
16584                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16585                }
16586                if (!curProcs.contains(proc)) {
16587                    curProcs.add(proc);
16588                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16589                            proc.info.packageName, proc.info.uid);
16590                }
16591            } else {
16592                if (curProcs != null) {
16593                    if (curProcs.remove(proc)) {
16594                        mBatteryStatsService.noteEvent(
16595                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16596                                proc.info.packageName, proc.info.uid);
16597                        if (curProcs.size() <= 0) {
16598                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16599                        }
16600                    }
16601                }
16602            }
16603            if (oomAdj) {
16604                updateOomAdjLocked();
16605            }
16606        }
16607    }
16608
16609    private final ActivityRecord resumedAppLocked() {
16610        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16611        String pkg;
16612        int uid;
16613        if (act != null) {
16614            pkg = act.packageName;
16615            uid = act.info.applicationInfo.uid;
16616        } else {
16617            pkg = null;
16618            uid = -1;
16619        }
16620        // Has the UID or resumed package name changed?
16621        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16622                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16623            if (mCurResumedPackage != null) {
16624                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16625                        mCurResumedPackage, mCurResumedUid);
16626            }
16627            mCurResumedPackage = pkg;
16628            mCurResumedUid = uid;
16629            if (mCurResumedPackage != null) {
16630                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16631                        mCurResumedPackage, mCurResumedUid);
16632            }
16633        }
16634        return act;
16635    }
16636
16637    final boolean updateOomAdjLocked(ProcessRecord app) {
16638        final ActivityRecord TOP_ACT = resumedAppLocked();
16639        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16640        final boolean wasCached = app.cached;
16641
16642        mAdjSeq++;
16643
16644        // This is the desired cached adjusment we want to tell it to use.
16645        // If our app is currently cached, we know it, and that is it.  Otherwise,
16646        // we don't know it yet, and it needs to now be cached we will then
16647        // need to do a complete oom adj.
16648        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16649                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16650        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16651                SystemClock.uptimeMillis());
16652        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16653            // Changed to/from cached state, so apps after it in the LRU
16654            // list may also be changed.
16655            updateOomAdjLocked();
16656        }
16657        return success;
16658    }
16659
16660    final void updateOomAdjLocked() {
16661        final ActivityRecord TOP_ACT = resumedAppLocked();
16662        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16663        final long now = SystemClock.uptimeMillis();
16664        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16665        final int N = mLruProcesses.size();
16666
16667        if (false) {
16668            RuntimeException e = new RuntimeException();
16669            e.fillInStackTrace();
16670            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16671        }
16672
16673        mAdjSeq++;
16674        mNewNumServiceProcs = 0;
16675        mNewNumAServiceProcs = 0;
16676
16677        final int emptyProcessLimit;
16678        final int cachedProcessLimit;
16679        if (mProcessLimit <= 0) {
16680            emptyProcessLimit = cachedProcessLimit = 0;
16681        } else if (mProcessLimit == 1) {
16682            emptyProcessLimit = 1;
16683            cachedProcessLimit = 0;
16684        } else {
16685            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16686            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16687        }
16688
16689        // Let's determine how many processes we have running vs.
16690        // how many slots we have for background processes; we may want
16691        // to put multiple processes in a slot of there are enough of
16692        // them.
16693        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16694                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16695        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16696        if (numEmptyProcs > cachedProcessLimit) {
16697            // If there are more empty processes than our limit on cached
16698            // processes, then use the cached process limit for the factor.
16699            // This ensures that the really old empty processes get pushed
16700            // down to the bottom, so if we are running low on memory we will
16701            // have a better chance at keeping around more cached processes
16702            // instead of a gazillion empty processes.
16703            numEmptyProcs = cachedProcessLimit;
16704        }
16705        int emptyFactor = numEmptyProcs/numSlots;
16706        if (emptyFactor < 1) emptyFactor = 1;
16707        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16708        if (cachedFactor < 1) cachedFactor = 1;
16709        int stepCached = 0;
16710        int stepEmpty = 0;
16711        int numCached = 0;
16712        int numEmpty = 0;
16713        int numTrimming = 0;
16714
16715        mNumNonCachedProcs = 0;
16716        mNumCachedHiddenProcs = 0;
16717
16718        // First update the OOM adjustment for each of the
16719        // application processes based on their current state.
16720        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16721        int nextCachedAdj = curCachedAdj+1;
16722        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16723        int nextEmptyAdj = curEmptyAdj+2;
16724        for (int i=N-1; i>=0; i--) {
16725            ProcessRecord app = mLruProcesses.get(i);
16726            if (!app.killedByAm && app.thread != null) {
16727                app.procStateChanged = false;
16728                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16729
16730                // If we haven't yet assigned the final cached adj
16731                // to the process, do that now.
16732                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16733                    switch (app.curProcState) {
16734                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16735                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16736                            // This process is a cached process holding activities...
16737                            // assign it the next cached value for that type, and then
16738                            // step that cached level.
16739                            app.curRawAdj = curCachedAdj;
16740                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16741                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16742                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16743                                    + ")");
16744                            if (curCachedAdj != nextCachedAdj) {
16745                                stepCached++;
16746                                if (stepCached >= cachedFactor) {
16747                                    stepCached = 0;
16748                                    curCachedAdj = nextCachedAdj;
16749                                    nextCachedAdj += 2;
16750                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16751                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16752                                    }
16753                                }
16754                            }
16755                            break;
16756                        default:
16757                            // For everything else, assign next empty cached process
16758                            // level and bump that up.  Note that this means that
16759                            // long-running services that have dropped down to the
16760                            // cached level will be treated as empty (since their process
16761                            // state is still as a service), which is what we want.
16762                            app.curRawAdj = curEmptyAdj;
16763                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16764                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16765                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16766                                    + ")");
16767                            if (curEmptyAdj != nextEmptyAdj) {
16768                                stepEmpty++;
16769                                if (stepEmpty >= emptyFactor) {
16770                                    stepEmpty = 0;
16771                                    curEmptyAdj = nextEmptyAdj;
16772                                    nextEmptyAdj += 2;
16773                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16774                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16775                                    }
16776                                }
16777                            }
16778                            break;
16779                    }
16780                }
16781
16782                applyOomAdjLocked(app, TOP_APP, true, now);
16783
16784                // Count the number of process types.
16785                switch (app.curProcState) {
16786                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16787                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16788                        mNumCachedHiddenProcs++;
16789                        numCached++;
16790                        if (numCached > cachedProcessLimit) {
16791                            killUnneededProcessLocked(app, "cached #" + numCached);
16792                        }
16793                        break;
16794                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16795                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16796                                && app.lastActivityTime < oldTime) {
16797                            killUnneededProcessLocked(app, "empty for "
16798                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16799                                    / 1000) + "s");
16800                        } else {
16801                            numEmpty++;
16802                            if (numEmpty > emptyProcessLimit) {
16803                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16804                            }
16805                        }
16806                        break;
16807                    default:
16808                        mNumNonCachedProcs++;
16809                        break;
16810                }
16811
16812                if (app.isolated && app.services.size() <= 0) {
16813                    // If this is an isolated process, and there are no
16814                    // services running in it, then the process is no longer
16815                    // needed.  We agressively kill these because we can by
16816                    // definition not re-use the same process again, and it is
16817                    // good to avoid having whatever code was running in them
16818                    // left sitting around after no longer needed.
16819                    killUnneededProcessLocked(app, "isolated not needed");
16820                }
16821
16822                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16823                        && !app.killedByAm) {
16824                    numTrimming++;
16825                }
16826            }
16827        }
16828
16829        mNumServiceProcs = mNewNumServiceProcs;
16830
16831        // Now determine the memory trimming level of background processes.
16832        // Unfortunately we need to start at the back of the list to do this
16833        // properly.  We only do this if the number of background apps we
16834        // are managing to keep around is less than half the maximum we desire;
16835        // if we are keeping a good number around, we'll let them use whatever
16836        // memory they want.
16837        final int numCachedAndEmpty = numCached + numEmpty;
16838        int memFactor;
16839        if (numCached <= ProcessList.TRIM_CACHED_APPS
16840                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16841            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16842                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16843            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16844                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16845            } else {
16846                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16847            }
16848        } else {
16849            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16850        }
16851        // We always allow the memory level to go up (better).  We only allow it to go
16852        // down if we are in a state where that is allowed, *and* the total number of processes
16853        // has gone down since last time.
16854        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16855                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16856                + " last=" + mLastNumProcesses);
16857        if (memFactor > mLastMemoryLevel) {
16858            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16859                memFactor = mLastMemoryLevel;
16860                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16861            }
16862        }
16863        mLastMemoryLevel = memFactor;
16864        mLastNumProcesses = mLruProcesses.size();
16865        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16866        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16867        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16868            if (mLowRamStartTime == 0) {
16869                mLowRamStartTime = now;
16870            }
16871            int step = 0;
16872            int fgTrimLevel;
16873            switch (memFactor) {
16874                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16875                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16876                    break;
16877                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16878                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16879                    break;
16880                default:
16881                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16882                    break;
16883            }
16884            int factor = numTrimming/3;
16885            int minFactor = 2;
16886            if (mHomeProcess != null) minFactor++;
16887            if (mPreviousProcess != null) minFactor++;
16888            if (factor < minFactor) factor = minFactor;
16889            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16890            for (int i=N-1; i>=0; i--) {
16891                ProcessRecord app = mLruProcesses.get(i);
16892                if (allChanged || app.procStateChanged) {
16893                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16894                    app.procStateChanged = false;
16895                }
16896                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16897                        && !app.killedByAm) {
16898                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16899                        try {
16900                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16901                                    "Trimming memory of " + app.processName
16902                                    + " to " + curLevel);
16903                            app.thread.scheduleTrimMemory(curLevel);
16904                        } catch (RemoteException e) {
16905                        }
16906                        if (false) {
16907                            // For now we won't do this; our memory trimming seems
16908                            // to be good enough at this point that destroying
16909                            // activities causes more harm than good.
16910                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16911                                    && app != mHomeProcess && app != mPreviousProcess) {
16912                                // Need to do this on its own message because the stack may not
16913                                // be in a consistent state at this point.
16914                                // For these apps we will also finish their activities
16915                                // to help them free memory.
16916                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16917                            }
16918                        }
16919                    }
16920                    app.trimMemoryLevel = curLevel;
16921                    step++;
16922                    if (step >= factor) {
16923                        step = 0;
16924                        switch (curLevel) {
16925                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16926                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16927                                break;
16928                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16929                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16930                                break;
16931                        }
16932                    }
16933                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16934                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16935                            && app.thread != null) {
16936                        try {
16937                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16938                                    "Trimming memory of heavy-weight " + app.processName
16939                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16940                            app.thread.scheduleTrimMemory(
16941                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16942                        } catch (RemoteException e) {
16943                        }
16944                    }
16945                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16946                } else {
16947                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16948                            || app.systemNoUi) && app.pendingUiClean) {
16949                        // If this application is now in the background and it
16950                        // had done UI, then give it the special trim level to
16951                        // have it free UI resources.
16952                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16953                        if (app.trimMemoryLevel < level && app.thread != null) {
16954                            try {
16955                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16956                                        "Trimming memory of bg-ui " + app.processName
16957                                        + " to " + level);
16958                                app.thread.scheduleTrimMemory(level);
16959                            } catch (RemoteException e) {
16960                            }
16961                        }
16962                        app.pendingUiClean = false;
16963                    }
16964                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16965                        try {
16966                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16967                                    "Trimming memory of fg " + app.processName
16968                                    + " to " + fgTrimLevel);
16969                            app.thread.scheduleTrimMemory(fgTrimLevel);
16970                        } catch (RemoteException e) {
16971                        }
16972                    }
16973                    app.trimMemoryLevel = fgTrimLevel;
16974                }
16975            }
16976        } else {
16977            if (mLowRamStartTime != 0) {
16978                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16979                mLowRamStartTime = 0;
16980            }
16981            for (int i=N-1; i>=0; i--) {
16982                ProcessRecord app = mLruProcesses.get(i);
16983                if (allChanged || app.procStateChanged) {
16984                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16985                    app.procStateChanged = false;
16986                }
16987                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16988                        || app.systemNoUi) && app.pendingUiClean) {
16989                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16990                            && app.thread != null) {
16991                        try {
16992                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16993                                    "Trimming memory of ui hidden " + app.processName
16994                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16995                            app.thread.scheduleTrimMemory(
16996                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16997                        } catch (RemoteException e) {
16998                        }
16999                    }
17000                    app.pendingUiClean = false;
17001                }
17002                app.trimMemoryLevel = 0;
17003            }
17004        }
17005
17006        if (mAlwaysFinishActivities) {
17007            // Need to do this on its own message because the stack may not
17008            // be in a consistent state at this point.
17009            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17010        }
17011
17012        if (allChanged) {
17013            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17014        }
17015
17016        if (mProcessStats.shouldWriteNowLocked(now)) {
17017            mHandler.post(new Runnable() {
17018                @Override public void run() {
17019                    synchronized (ActivityManagerService.this) {
17020                        mProcessStats.writeStateAsyncLocked();
17021                    }
17022                }
17023            });
17024        }
17025
17026        if (DEBUG_OOM_ADJ) {
17027            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17028        }
17029    }
17030
17031    final void trimApplications() {
17032        synchronized (this) {
17033            int i;
17034
17035            // First remove any unused application processes whose package
17036            // has been removed.
17037            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17038                final ProcessRecord app = mRemovedProcesses.get(i);
17039                if (app.activities.size() == 0
17040                        && app.curReceiver == null && app.services.size() == 0) {
17041                    Slog.i(
17042                        TAG, "Exiting empty application process "
17043                        + app.processName + " ("
17044                        + (app.thread != null ? app.thread.asBinder() : null)
17045                        + ")\n");
17046                    if (app.pid > 0 && app.pid != MY_PID) {
17047                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
17048                                app.processName, app.setAdj, "empty");
17049                        app.killedByAm = true;
17050                        Process.killProcessQuiet(app.pid);
17051                        Process.killProcessGroup(app.info.uid, app.pid);
17052                    } else {
17053                        try {
17054                            app.thread.scheduleExit();
17055                        } catch (Exception e) {
17056                            // Ignore exceptions.
17057                        }
17058                    }
17059                    cleanUpApplicationRecordLocked(app, false, true, -1);
17060                    mRemovedProcesses.remove(i);
17061
17062                    if (app.persistent) {
17063                        addAppLocked(app.info, false, null /* ABI override */);
17064                    }
17065                }
17066            }
17067
17068            // Now update the oom adj for all processes.
17069            updateOomAdjLocked();
17070        }
17071    }
17072
17073    /** This method sends the specified signal to each of the persistent apps */
17074    public void signalPersistentProcesses(int sig) throws RemoteException {
17075        if (sig != Process.SIGNAL_USR1) {
17076            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17077        }
17078
17079        synchronized (this) {
17080            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17081                    != PackageManager.PERMISSION_GRANTED) {
17082                throw new SecurityException("Requires permission "
17083                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17084            }
17085
17086            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17087                ProcessRecord r = mLruProcesses.get(i);
17088                if (r.thread != null && r.persistent) {
17089                    Process.sendSignal(r.pid, sig);
17090                }
17091            }
17092        }
17093    }
17094
17095    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
17096        if (proc == null || proc == mProfileProc) {
17097            proc = mProfileProc;
17098            path = mProfileFile;
17099            profileType = mProfileType;
17100            clearProfilerLocked();
17101        }
17102        if (proc == null) {
17103            return;
17104        }
17105        try {
17106            proc.thread.profilerControl(false, path, null, profileType);
17107        } catch (RemoteException e) {
17108            throw new IllegalStateException("Process disappeared");
17109        }
17110    }
17111
17112    private void clearProfilerLocked() {
17113        if (mProfileFd != null) {
17114            try {
17115                mProfileFd.close();
17116            } catch (IOException e) {
17117            }
17118        }
17119        mProfileApp = null;
17120        mProfileProc = null;
17121        mProfileFile = null;
17122        mProfileType = 0;
17123        mAutoStopProfiler = false;
17124    }
17125
17126    public boolean profileControl(String process, int userId, boolean start,
17127            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
17128
17129        try {
17130            synchronized (this) {
17131                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17132                // its own permission.
17133                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17134                        != PackageManager.PERMISSION_GRANTED) {
17135                    throw new SecurityException("Requires permission "
17136                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17137                }
17138
17139                if (start && fd == null) {
17140                    throw new IllegalArgumentException("null fd");
17141                }
17142
17143                ProcessRecord proc = null;
17144                if (process != null) {
17145                    proc = findProcessLocked(process, userId, "profileControl");
17146                }
17147
17148                if (start && (proc == null || proc.thread == null)) {
17149                    throw new IllegalArgumentException("Unknown process: " + process);
17150                }
17151
17152                if (start) {
17153                    stopProfilerLocked(null, null, 0);
17154                    setProfileApp(proc.info, proc.processName, path, fd, false);
17155                    mProfileProc = proc;
17156                    mProfileType = profileType;
17157                    try {
17158                        fd = fd.dup();
17159                    } catch (IOException e) {
17160                        fd = null;
17161                    }
17162                    proc.thread.profilerControl(start, path, fd, profileType);
17163                    fd = null;
17164                    mProfileFd = null;
17165                } else {
17166                    stopProfilerLocked(proc, path, profileType);
17167                    if (fd != null) {
17168                        try {
17169                            fd.close();
17170                        } catch (IOException e) {
17171                        }
17172                    }
17173                }
17174
17175                return true;
17176            }
17177        } catch (RemoteException e) {
17178            throw new IllegalStateException("Process disappeared");
17179        } finally {
17180            if (fd != null) {
17181                try {
17182                    fd.close();
17183                } catch (IOException e) {
17184                }
17185            }
17186        }
17187    }
17188
17189    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17190        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17191                userId, true, ALLOW_FULL_ONLY, callName, null);
17192        ProcessRecord proc = null;
17193        try {
17194            int pid = Integer.parseInt(process);
17195            synchronized (mPidsSelfLocked) {
17196                proc = mPidsSelfLocked.get(pid);
17197            }
17198        } catch (NumberFormatException e) {
17199        }
17200
17201        if (proc == null) {
17202            ArrayMap<String, SparseArray<ProcessRecord>> all
17203                    = mProcessNames.getMap();
17204            SparseArray<ProcessRecord> procs = all.get(process);
17205            if (procs != null && procs.size() > 0) {
17206                proc = procs.valueAt(0);
17207                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17208                    for (int i=1; i<procs.size(); i++) {
17209                        ProcessRecord thisProc = procs.valueAt(i);
17210                        if (thisProc.userId == userId) {
17211                            proc = thisProc;
17212                            break;
17213                        }
17214                    }
17215                }
17216            }
17217        }
17218
17219        return proc;
17220    }
17221
17222    public boolean dumpHeap(String process, int userId, boolean managed,
17223            String path, ParcelFileDescriptor fd) throws RemoteException {
17224
17225        try {
17226            synchronized (this) {
17227                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17228                // its own permission (same as profileControl).
17229                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17230                        != PackageManager.PERMISSION_GRANTED) {
17231                    throw new SecurityException("Requires permission "
17232                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17233                }
17234
17235                if (fd == null) {
17236                    throw new IllegalArgumentException("null fd");
17237                }
17238
17239                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17240                if (proc == null || proc.thread == null) {
17241                    throw new IllegalArgumentException("Unknown process: " + process);
17242                }
17243
17244                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17245                if (!isDebuggable) {
17246                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17247                        throw new SecurityException("Process not debuggable: " + proc);
17248                    }
17249                }
17250
17251                proc.thread.dumpHeap(managed, path, fd);
17252                fd = null;
17253                return true;
17254            }
17255        } catch (RemoteException e) {
17256            throw new IllegalStateException("Process disappeared");
17257        } finally {
17258            if (fd != null) {
17259                try {
17260                    fd.close();
17261                } catch (IOException e) {
17262                }
17263            }
17264        }
17265    }
17266
17267    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17268    public void monitor() {
17269        synchronized (this) { }
17270    }
17271
17272    void onCoreSettingsChange(Bundle settings) {
17273        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17274            ProcessRecord processRecord = mLruProcesses.get(i);
17275            try {
17276                if (processRecord.thread != null) {
17277                    processRecord.thread.setCoreSettings(settings);
17278                }
17279            } catch (RemoteException re) {
17280                /* ignore */
17281            }
17282        }
17283    }
17284
17285    // Multi-user methods
17286
17287    /**
17288     * Start user, if its not already running, but don't bring it to foreground.
17289     */
17290    @Override
17291    public boolean startUserInBackground(final int userId) {
17292        return startUser(userId, /* foreground */ false);
17293    }
17294
17295    /**
17296     * Refreshes the list of users related to the current user when either a
17297     * user switch happens or when a new related user is started in the
17298     * background.
17299     */
17300    private void updateCurrentProfileIdsLocked() {
17301        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17302                mCurrentUserId, false /* enabledOnly */);
17303        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17304        for (int i = 0; i < currentProfileIds.length; i++) {
17305            currentProfileIds[i] = profiles.get(i).id;
17306        }
17307        mCurrentProfileIds = currentProfileIds;
17308
17309        synchronized (mUserProfileGroupIdsSelfLocked) {
17310            mUserProfileGroupIdsSelfLocked.clear();
17311            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17312            for (int i = 0; i < users.size(); i++) {
17313                UserInfo user = users.get(i);
17314                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17315                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17316                }
17317            }
17318        }
17319    }
17320
17321    private Set getProfileIdsLocked(int userId) {
17322        Set userIds = new HashSet<Integer>();
17323        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17324                userId, false /* enabledOnly */);
17325        for (UserInfo user : profiles) {
17326            userIds.add(Integer.valueOf(user.id));
17327        }
17328        return userIds;
17329    }
17330
17331    @Override
17332    public boolean switchUser(final int userId) {
17333        return startUser(userId, /* foregound */ true);
17334    }
17335
17336    private boolean startUser(final int userId, boolean foreground) {
17337        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17338                != PackageManager.PERMISSION_GRANTED) {
17339            String msg = "Permission Denial: switchUser() from pid="
17340                    + Binder.getCallingPid()
17341                    + ", uid=" + Binder.getCallingUid()
17342                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17343            Slog.w(TAG, msg);
17344            throw new SecurityException(msg);
17345        }
17346
17347        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17348
17349        final long ident = Binder.clearCallingIdentity();
17350        try {
17351            synchronized (this) {
17352                final int oldUserId = mCurrentUserId;
17353                if (oldUserId == userId) {
17354                    return true;
17355                }
17356
17357                mStackSupervisor.setLockTaskModeLocked(null, false);
17358
17359                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17360                if (userInfo == null) {
17361                    Slog.w(TAG, "No user info for user #" + userId);
17362                    return false;
17363                }
17364                if (foreground && userInfo.isManagedProfile()) {
17365                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17366                    return false;
17367                }
17368
17369                if (foreground) {
17370                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17371                            R.anim.screen_user_enter);
17372                }
17373
17374                boolean needStart = false;
17375
17376                // If the user we are switching to is not currently started, then
17377                // we need to start it now.
17378                if (mStartedUsers.get(userId) == null) {
17379                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17380                    updateStartedUserArrayLocked();
17381                    needStart = true;
17382                }
17383
17384                final Integer userIdInt = Integer.valueOf(userId);
17385                mUserLru.remove(userIdInt);
17386                mUserLru.add(userIdInt);
17387
17388                if (foreground) {
17389                    mCurrentUserId = userId;
17390                    updateCurrentProfileIdsLocked();
17391                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17392                    // Once the internal notion of the active user has switched, we lock the device
17393                    // with the option to show the user switcher on the keyguard.
17394                    mWindowManager.lockNow(null);
17395                } else {
17396                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17397                    updateCurrentProfileIdsLocked();
17398                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17399                    mUserLru.remove(currentUserIdInt);
17400                    mUserLru.add(currentUserIdInt);
17401                }
17402
17403                final UserStartedState uss = mStartedUsers.get(userId);
17404
17405                // Make sure user is in the started state.  If it is currently
17406                // stopping, we need to knock that off.
17407                if (uss.mState == UserStartedState.STATE_STOPPING) {
17408                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17409                    // so we can just fairly silently bring the user back from
17410                    // the almost-dead.
17411                    uss.mState = UserStartedState.STATE_RUNNING;
17412                    updateStartedUserArrayLocked();
17413                    needStart = true;
17414                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17415                    // This means ACTION_SHUTDOWN has been sent, so we will
17416                    // need to treat this as a new boot of the user.
17417                    uss.mState = UserStartedState.STATE_BOOTING;
17418                    updateStartedUserArrayLocked();
17419                    needStart = true;
17420                }
17421
17422                if (uss.mState == UserStartedState.STATE_BOOTING) {
17423                    // Booting up a new user, need to tell system services about it.
17424                    // Note that this is on the same handler as scheduling of broadcasts,
17425                    // which is important because it needs to go first.
17426                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
17427                }
17428
17429                if (foreground) {
17430                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17431                            oldUserId));
17432                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17433                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17434                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17435                            oldUserId, userId, uss));
17436                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17437                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17438                }
17439
17440                if (needStart) {
17441                    // Send USER_STARTED broadcast
17442                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17443                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17444                            | Intent.FLAG_RECEIVER_FOREGROUND);
17445                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17446                    broadcastIntentLocked(null, null, intent,
17447                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17448                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17449                }
17450
17451                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17452                    if (userId != UserHandle.USER_OWNER) {
17453                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17454                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17455                        broadcastIntentLocked(null, null, intent, null,
17456                                new IIntentReceiver.Stub() {
17457                                    public void performReceive(Intent intent, int resultCode,
17458                                            String data, Bundle extras, boolean ordered,
17459                                            boolean sticky, int sendingUser) {
17460                                        userInitialized(uss, userId);
17461                                    }
17462                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17463                                true, false, MY_PID, Process.SYSTEM_UID,
17464                                userId);
17465                        uss.initializing = true;
17466                    } else {
17467                        getUserManagerLocked().makeInitialized(userInfo.id);
17468                    }
17469                }
17470
17471                if (foreground) {
17472                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17473                    if (homeInFront) {
17474                        startHomeActivityLocked(userId);
17475                    } else {
17476                        mStackSupervisor.resumeTopActivitiesLocked();
17477                    }
17478                    EventLogTags.writeAmSwitchUser(userId);
17479                    getUserManagerLocked().userForeground(userId);
17480                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17481                } else {
17482                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17483                }
17484
17485                if (needStart) {
17486                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17487                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17488                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17489                    broadcastIntentLocked(null, null, intent,
17490                            null, new IIntentReceiver.Stub() {
17491                                @Override
17492                                public void performReceive(Intent intent, int resultCode, String data,
17493                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17494                                        throws RemoteException {
17495                                }
17496                            }, 0, null, null,
17497                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17498                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17499                }
17500            }
17501        } finally {
17502            Binder.restoreCallingIdentity(ident);
17503        }
17504
17505        return true;
17506    }
17507
17508    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17509        long ident = Binder.clearCallingIdentity();
17510        try {
17511            Intent intent;
17512            if (oldUserId >= 0) {
17513                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17514                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17515                int count = profiles.size();
17516                for (int i = 0; i < count; i++) {
17517                    int profileUserId = profiles.get(i).id;
17518                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17519                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17520                            | Intent.FLAG_RECEIVER_FOREGROUND);
17521                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17522                    broadcastIntentLocked(null, null, intent,
17523                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17524                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17525                }
17526            }
17527            if (newUserId >= 0) {
17528                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17529                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17530                int count = profiles.size();
17531                for (int i = 0; i < count; i++) {
17532                    int profileUserId = profiles.get(i).id;
17533                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17534                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17535                            | Intent.FLAG_RECEIVER_FOREGROUND);
17536                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17537                    broadcastIntentLocked(null, null, intent,
17538                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17539                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17540                }
17541                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17542                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17543                        | Intent.FLAG_RECEIVER_FOREGROUND);
17544                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17545                broadcastIntentLocked(null, null, intent,
17546                        null, null, 0, null, null,
17547                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17548                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17549            }
17550        } finally {
17551            Binder.restoreCallingIdentity(ident);
17552        }
17553    }
17554
17555    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17556            final int newUserId) {
17557        final int N = mUserSwitchObservers.beginBroadcast();
17558        if (N > 0) {
17559            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17560                int mCount = 0;
17561                @Override
17562                public void sendResult(Bundle data) throws RemoteException {
17563                    synchronized (ActivityManagerService.this) {
17564                        if (mCurUserSwitchCallback == this) {
17565                            mCount++;
17566                            if (mCount == N) {
17567                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17568                            }
17569                        }
17570                    }
17571                }
17572            };
17573            synchronized (this) {
17574                uss.switching = true;
17575                mCurUserSwitchCallback = callback;
17576            }
17577            for (int i=0; i<N; i++) {
17578                try {
17579                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17580                            newUserId, callback);
17581                } catch (RemoteException e) {
17582                }
17583            }
17584        } else {
17585            synchronized (this) {
17586                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17587            }
17588        }
17589        mUserSwitchObservers.finishBroadcast();
17590    }
17591
17592    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17593        synchronized (this) {
17594            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17595            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17596        }
17597    }
17598
17599    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17600        mCurUserSwitchCallback = null;
17601        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17602        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17603                oldUserId, newUserId, uss));
17604    }
17605
17606    void userInitialized(UserStartedState uss, int newUserId) {
17607        completeSwitchAndInitalize(uss, newUserId, true, false);
17608    }
17609
17610    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17611        completeSwitchAndInitalize(uss, newUserId, false, true);
17612    }
17613
17614    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17615            boolean clearInitializing, boolean clearSwitching) {
17616        boolean unfrozen = false;
17617        synchronized (this) {
17618            if (clearInitializing) {
17619                uss.initializing = false;
17620                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17621            }
17622            if (clearSwitching) {
17623                uss.switching = false;
17624            }
17625            if (!uss.switching && !uss.initializing) {
17626                mWindowManager.stopFreezingScreen();
17627                unfrozen = true;
17628            }
17629        }
17630        if (unfrozen) {
17631            final int N = mUserSwitchObservers.beginBroadcast();
17632            for (int i=0; i<N; i++) {
17633                try {
17634                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17635                } catch (RemoteException e) {
17636                }
17637            }
17638            mUserSwitchObservers.finishBroadcast();
17639        }
17640    }
17641
17642    void scheduleStartProfilesLocked() {
17643        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17644            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17645                    DateUtils.SECOND_IN_MILLIS);
17646        }
17647    }
17648
17649    void startProfilesLocked() {
17650        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17651        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17652                mCurrentUserId, false /* enabledOnly */);
17653        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17654        for (UserInfo user : profiles) {
17655            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17656                    && user.id != mCurrentUserId) {
17657                toStart.add(user);
17658            }
17659        }
17660        final int n = toStart.size();
17661        int i = 0;
17662        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17663            startUserInBackground(toStart.get(i).id);
17664        }
17665        if (i < n) {
17666            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17667        }
17668    }
17669
17670    void finishUserBoot(UserStartedState uss) {
17671        synchronized (this) {
17672            if (uss.mState == UserStartedState.STATE_BOOTING
17673                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17674                uss.mState = UserStartedState.STATE_RUNNING;
17675                final int userId = uss.mHandle.getIdentifier();
17676                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17677                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17678                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17679                broadcastIntentLocked(null, null, intent,
17680                        null, null, 0, null, null,
17681                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17682                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17683            }
17684        }
17685    }
17686
17687    void finishUserSwitch(UserStartedState uss) {
17688        synchronized (this) {
17689            finishUserBoot(uss);
17690
17691            startProfilesLocked();
17692
17693            int num = mUserLru.size();
17694            int i = 0;
17695            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17696                Integer oldUserId = mUserLru.get(i);
17697                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17698                if (oldUss == null) {
17699                    // Shouldn't happen, but be sane if it does.
17700                    mUserLru.remove(i);
17701                    num--;
17702                    continue;
17703                }
17704                if (oldUss.mState == UserStartedState.STATE_STOPPING
17705                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17706                    // This user is already stopping, doesn't count.
17707                    num--;
17708                    i++;
17709                    continue;
17710                }
17711                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17712                    // Owner and current can't be stopped, but count as running.
17713                    i++;
17714                    continue;
17715                }
17716                // This is a user to be stopped.
17717                stopUserLocked(oldUserId, null);
17718                num--;
17719                i++;
17720            }
17721        }
17722    }
17723
17724    @Override
17725    public int stopUser(final int userId, final IStopUserCallback callback) {
17726        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17727                != PackageManager.PERMISSION_GRANTED) {
17728            String msg = "Permission Denial: switchUser() from pid="
17729                    + Binder.getCallingPid()
17730                    + ", uid=" + Binder.getCallingUid()
17731                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17732            Slog.w(TAG, msg);
17733            throw new SecurityException(msg);
17734        }
17735        if (userId <= 0) {
17736            throw new IllegalArgumentException("Can't stop primary user " + userId);
17737        }
17738        synchronized (this) {
17739            return stopUserLocked(userId, callback);
17740        }
17741    }
17742
17743    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17744        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17745        if (mCurrentUserId == userId) {
17746            return ActivityManager.USER_OP_IS_CURRENT;
17747        }
17748
17749        final UserStartedState uss = mStartedUsers.get(userId);
17750        if (uss == null) {
17751            // User is not started, nothing to do...  but we do need to
17752            // callback if requested.
17753            if (callback != null) {
17754                mHandler.post(new Runnable() {
17755                    @Override
17756                    public void run() {
17757                        try {
17758                            callback.userStopped(userId);
17759                        } catch (RemoteException e) {
17760                        }
17761                    }
17762                });
17763            }
17764            return ActivityManager.USER_OP_SUCCESS;
17765        }
17766
17767        if (callback != null) {
17768            uss.mStopCallbacks.add(callback);
17769        }
17770
17771        if (uss.mState != UserStartedState.STATE_STOPPING
17772                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17773            uss.mState = UserStartedState.STATE_STOPPING;
17774            updateStartedUserArrayLocked();
17775
17776            long ident = Binder.clearCallingIdentity();
17777            try {
17778                // We are going to broadcast ACTION_USER_STOPPING and then
17779                // once that is done send a final ACTION_SHUTDOWN and then
17780                // stop the user.
17781                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17782                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17783                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17784                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17785                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17786                // This is the result receiver for the final shutdown broadcast.
17787                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17788                    @Override
17789                    public void performReceive(Intent intent, int resultCode, String data,
17790                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17791                        finishUserStop(uss);
17792                    }
17793                };
17794                // This is the result receiver for the initial stopping broadcast.
17795                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17796                    @Override
17797                    public void performReceive(Intent intent, int resultCode, String data,
17798                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17799                        // On to the next.
17800                        synchronized (ActivityManagerService.this) {
17801                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17802                                // Whoops, we are being started back up.  Abort, abort!
17803                                return;
17804                            }
17805                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17806                        }
17807                        mBatteryStatsService.noteEvent(
17808                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17809                                Integer.toString(userId), userId);
17810                        mSystemServiceManager.stopUser(userId);
17811                        broadcastIntentLocked(null, null, shutdownIntent,
17812                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17813                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17814                    }
17815                };
17816                // Kick things off.
17817                broadcastIntentLocked(null, null, stoppingIntent,
17818                        null, stoppingReceiver, 0, null, null,
17819                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17820                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17821            } finally {
17822                Binder.restoreCallingIdentity(ident);
17823            }
17824        }
17825
17826        return ActivityManager.USER_OP_SUCCESS;
17827    }
17828
17829    void finishUserStop(UserStartedState uss) {
17830        final int userId = uss.mHandle.getIdentifier();
17831        boolean stopped;
17832        ArrayList<IStopUserCallback> callbacks;
17833        synchronized (this) {
17834            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17835            if (mStartedUsers.get(userId) != uss) {
17836                stopped = false;
17837            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17838                stopped = false;
17839            } else {
17840                stopped = true;
17841                // User can no longer run.
17842                mStartedUsers.remove(userId);
17843                mUserLru.remove(Integer.valueOf(userId));
17844                updateStartedUserArrayLocked();
17845
17846                // Clean up all state and processes associated with the user.
17847                // Kill all the processes for the user.
17848                forceStopUserLocked(userId, "finish user");
17849            }
17850
17851            // Explicitly remove the old information in mRecentTasks.
17852            removeRecentTasksForUserLocked(userId);
17853        }
17854
17855        for (int i=0; i<callbacks.size(); i++) {
17856            try {
17857                if (stopped) callbacks.get(i).userStopped(userId);
17858                else callbacks.get(i).userStopAborted(userId);
17859            } catch (RemoteException e) {
17860            }
17861        }
17862
17863        if (stopped) {
17864            mSystemServiceManager.cleanupUser(userId);
17865            synchronized (this) {
17866                mStackSupervisor.removeUserLocked(userId);
17867            }
17868        }
17869    }
17870
17871    @Override
17872    public UserInfo getCurrentUser() {
17873        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17874                != PackageManager.PERMISSION_GRANTED) && (
17875                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17876                != PackageManager.PERMISSION_GRANTED)) {
17877            String msg = "Permission Denial: getCurrentUser() from pid="
17878                    + Binder.getCallingPid()
17879                    + ", uid=" + Binder.getCallingUid()
17880                    + " requires " + INTERACT_ACROSS_USERS;
17881            Slog.w(TAG, msg);
17882            throw new SecurityException(msg);
17883        }
17884        synchronized (this) {
17885            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17886        }
17887    }
17888
17889    int getCurrentUserIdLocked() {
17890        return mCurrentUserId;
17891    }
17892
17893    @Override
17894    public boolean isUserRunning(int userId, boolean orStopped) {
17895        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17896                != PackageManager.PERMISSION_GRANTED) {
17897            String msg = "Permission Denial: isUserRunning() from pid="
17898                    + Binder.getCallingPid()
17899                    + ", uid=" + Binder.getCallingUid()
17900                    + " requires " + INTERACT_ACROSS_USERS;
17901            Slog.w(TAG, msg);
17902            throw new SecurityException(msg);
17903        }
17904        synchronized (this) {
17905            return isUserRunningLocked(userId, orStopped);
17906        }
17907    }
17908
17909    boolean isUserRunningLocked(int userId, boolean orStopped) {
17910        UserStartedState state = mStartedUsers.get(userId);
17911        if (state == null) {
17912            return false;
17913        }
17914        if (orStopped) {
17915            return true;
17916        }
17917        return state.mState != UserStartedState.STATE_STOPPING
17918                && state.mState != UserStartedState.STATE_SHUTDOWN;
17919    }
17920
17921    @Override
17922    public int[] getRunningUserIds() {
17923        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17924                != PackageManager.PERMISSION_GRANTED) {
17925            String msg = "Permission Denial: isUserRunning() from pid="
17926                    + Binder.getCallingPid()
17927                    + ", uid=" + Binder.getCallingUid()
17928                    + " requires " + INTERACT_ACROSS_USERS;
17929            Slog.w(TAG, msg);
17930            throw new SecurityException(msg);
17931        }
17932        synchronized (this) {
17933            return mStartedUserArray;
17934        }
17935    }
17936
17937    private void updateStartedUserArrayLocked() {
17938        int num = 0;
17939        for (int i=0; i<mStartedUsers.size();  i++) {
17940            UserStartedState uss = mStartedUsers.valueAt(i);
17941            // This list does not include stopping users.
17942            if (uss.mState != UserStartedState.STATE_STOPPING
17943                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17944                num++;
17945            }
17946        }
17947        mStartedUserArray = new int[num];
17948        num = 0;
17949        for (int i=0; i<mStartedUsers.size();  i++) {
17950            UserStartedState uss = mStartedUsers.valueAt(i);
17951            if (uss.mState != UserStartedState.STATE_STOPPING
17952                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17953                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17954                num++;
17955            }
17956        }
17957    }
17958
17959    @Override
17960    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17961        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17962                != PackageManager.PERMISSION_GRANTED) {
17963            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17964                    + Binder.getCallingPid()
17965                    + ", uid=" + Binder.getCallingUid()
17966                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17967            Slog.w(TAG, msg);
17968            throw new SecurityException(msg);
17969        }
17970
17971        mUserSwitchObservers.register(observer);
17972    }
17973
17974    @Override
17975    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17976        mUserSwitchObservers.unregister(observer);
17977    }
17978
17979    private boolean userExists(int userId) {
17980        if (userId == 0) {
17981            return true;
17982        }
17983        UserManagerService ums = getUserManagerLocked();
17984        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17985    }
17986
17987    int[] getUsersLocked() {
17988        UserManagerService ums = getUserManagerLocked();
17989        return ums != null ? ums.getUserIds() : new int[] { 0 };
17990    }
17991
17992    UserManagerService getUserManagerLocked() {
17993        if (mUserManager == null) {
17994            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17995            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17996        }
17997        return mUserManager;
17998    }
17999
18000    private int applyUserId(int uid, int userId) {
18001        return UserHandle.getUid(userId, uid);
18002    }
18003
18004    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18005        if (info == null) return null;
18006        ApplicationInfo newInfo = new ApplicationInfo(info);
18007        newInfo.uid = applyUserId(info.uid, userId);
18008        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18009                + info.packageName;
18010        return newInfo;
18011    }
18012
18013    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18014        if (aInfo == null
18015                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18016            return aInfo;
18017        }
18018
18019        ActivityInfo info = new ActivityInfo(aInfo);
18020        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18021        return info;
18022    }
18023
18024    private final class LocalService extends ActivityManagerInternal {
18025        @Override
18026        public void goingToSleep() {
18027            ActivityManagerService.this.goingToSleep();
18028        }
18029
18030        @Override
18031        public void wakingUp() {
18032            ActivityManagerService.this.wakingUp();
18033        }
18034
18035        @Override
18036        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18037                String processName, String abiOverride, int uid, Runnable crashHandler) {
18038            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18039                    processName, abiOverride, uid, crashHandler);
18040        }
18041    }
18042
18043    /**
18044     * An implementation of IAppTask, that allows an app to manage its own tasks via
18045     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18046     * only the process that calls getAppTasks() can call the AppTask methods.
18047     */
18048    class AppTaskImpl extends IAppTask.Stub {
18049        private int mTaskId;
18050        private int mCallingUid;
18051
18052        public AppTaskImpl(int taskId, int callingUid) {
18053            mTaskId = taskId;
18054            mCallingUid = callingUid;
18055        }
18056
18057        @Override
18058        public void finishAndRemoveTask() {
18059            // Ensure that we are called from the same process that created this AppTask
18060            if (mCallingUid != Binder.getCallingUid()) {
18061                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
18062                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18063                return;
18064            }
18065
18066            synchronized (ActivityManagerService.this) {
18067                long origId = Binder.clearCallingIdentity();
18068                try {
18069                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18070                    if (tr != null) {
18071                        // Only kill the process if we are not a new document
18072                        int flags = tr.getBaseIntent().getFlags();
18073                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18074                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18075                        removeTaskByIdLocked(mTaskId,
18076                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18077                    }
18078                } finally {
18079                    Binder.restoreCallingIdentity(origId);
18080                }
18081            }
18082        }
18083
18084        @Override
18085        public ActivityManager.RecentTaskInfo getTaskInfo() {
18086            // Ensure that we are called from the same process that created this AppTask
18087            if (mCallingUid != Binder.getCallingUid()) {
18088                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
18089                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18090                return null;
18091            }
18092
18093            synchronized (ActivityManagerService.this) {
18094                long origId = Binder.clearCallingIdentity();
18095                try {
18096                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18097                    if (tr != null) {
18098                        return createRecentTaskInfoFromTaskRecord(tr);
18099                    }
18100                } finally {
18101                    Binder.restoreCallingIdentity(origId);
18102                }
18103                return null;
18104            }
18105        }
18106    }
18107}
18108