ActivityManagerService.java revision 63f29d9d7cab8c714f54db520eebd3047977d19c
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.color = mContext.getResources().getColor(
1476                            com.android.internal.R.color.system_notification_accent_color);
1477                    notification.setLatestEventInfo(context, text,
1478                            mContext.getText(R.string.heavy_weight_notification_detail),
1479                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1480                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1481                                    new UserHandle(root.userId)));
1482
1483                    try {
1484                        int[] outId = new int[1];
1485                        inm.enqueueNotificationWithTag("android", "android", null,
1486                                R.string.heavy_weight_notification,
1487                                notification, outId, root.userId);
1488                    } catch (RuntimeException e) {
1489                        Slog.w(ActivityManagerService.TAG,
1490                                "Error showing notification for heavy-weight app", e);
1491                    } catch (RemoteException e) {
1492                    }
1493                } catch (NameNotFoundException e) {
1494                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1495                }
1496            } break;
1497            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1498                INotificationManager inm = NotificationManager.getService();
1499                if (inm == null) {
1500                    return;
1501                }
1502                try {
1503                    inm.cancelNotificationWithTag("android", null,
1504                            R.string.heavy_weight_notification,  msg.arg1);
1505                } catch (RuntimeException e) {
1506                    Slog.w(ActivityManagerService.TAG,
1507                            "Error canceling notification for service", e);
1508                } catch (RemoteException e) {
1509                }
1510            } break;
1511            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1512                synchronized (ActivityManagerService.this) {
1513                    checkExcessivePowerUsageLocked(true);
1514                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1515                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1516                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1517                }
1518            } break;
1519            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1520                synchronized (ActivityManagerService.this) {
1521                    ActivityRecord ar = (ActivityRecord)msg.obj;
1522                    if (mCompatModeDialog != null) {
1523                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1524                                ar.info.applicationInfo.packageName)) {
1525                            return;
1526                        }
1527                        mCompatModeDialog.dismiss();
1528                        mCompatModeDialog = null;
1529                    }
1530                    if (ar != null && false) {
1531                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1532                                ar.packageName)) {
1533                            int mode = mCompatModePackages.computeCompatModeLocked(
1534                                    ar.info.applicationInfo);
1535                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1536                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1537                                mCompatModeDialog = new CompatModeDialog(
1538                                        ActivityManagerService.this, mContext,
1539                                        ar.info.applicationInfo);
1540                                mCompatModeDialog.show();
1541                            }
1542                        }
1543                    }
1544                }
1545                break;
1546            }
1547            case DISPATCH_PROCESSES_CHANGED: {
1548                dispatchProcessesChanged();
1549                break;
1550            }
1551            case DISPATCH_PROCESS_DIED: {
1552                final int pid = msg.arg1;
1553                final int uid = msg.arg2;
1554                dispatchProcessDied(pid, uid);
1555                break;
1556            }
1557            case REPORT_MEM_USAGE_MSG: {
1558                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1559                Thread thread = new Thread() {
1560                    @Override public void run() {
1561                        final SparseArray<ProcessMemInfo> infoMap
1562                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1563                        for (int i=0, N=memInfos.size(); i<N; i++) {
1564                            ProcessMemInfo mi = memInfos.get(i);
1565                            infoMap.put(mi.pid, mi);
1566                        }
1567                        updateCpuStatsNow();
1568                        synchronized (mProcessCpuThread) {
1569                            final int N = mProcessCpuTracker.countStats();
1570                            for (int i=0; i<N; i++) {
1571                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1572                                if (st.vsize > 0) {
1573                                    long pss = Debug.getPss(st.pid, null);
1574                                    if (pss > 0) {
1575                                        if (infoMap.indexOfKey(st.pid) < 0) {
1576                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1577                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1578                                            mi.pss = pss;
1579                                            memInfos.add(mi);
1580                                        }
1581                                    }
1582                                }
1583                            }
1584                        }
1585
1586                        long totalPss = 0;
1587                        for (int i=0, N=memInfos.size(); i<N; i++) {
1588                            ProcessMemInfo mi = memInfos.get(i);
1589                            if (mi.pss == 0) {
1590                                mi.pss = Debug.getPss(mi.pid, null);
1591                            }
1592                            totalPss += mi.pss;
1593                        }
1594                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1595                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1596                                if (lhs.oomAdj != rhs.oomAdj) {
1597                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1598                                }
1599                                if (lhs.pss != rhs.pss) {
1600                                    return lhs.pss < rhs.pss ? 1 : -1;
1601                                }
1602                                return 0;
1603                            }
1604                        });
1605
1606                        StringBuilder tag = new StringBuilder(128);
1607                        StringBuilder stack = new StringBuilder(128);
1608                        tag.append("Low on memory -- ");
1609                        appendMemBucket(tag, totalPss, "total", false);
1610                        appendMemBucket(stack, totalPss, "total", true);
1611
1612                        StringBuilder logBuilder = new StringBuilder(1024);
1613                        logBuilder.append("Low on memory:\n");
1614
1615                        boolean firstLine = true;
1616                        int lastOomAdj = Integer.MIN_VALUE;
1617                        for (int i=0, N=memInfos.size(); i<N; i++) {
1618                            ProcessMemInfo mi = memInfos.get(i);
1619
1620                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1621                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1622                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1623                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1624                                if (lastOomAdj != mi.oomAdj) {
1625                                    lastOomAdj = mi.oomAdj;
1626                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1627                                        tag.append(" / ");
1628                                    }
1629                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1630                                        if (firstLine) {
1631                                            stack.append(":");
1632                                            firstLine = false;
1633                                        }
1634                                        stack.append("\n\t at ");
1635                                    } else {
1636                                        stack.append("$");
1637                                    }
1638                                } else {
1639                                    tag.append(" ");
1640                                    stack.append("$");
1641                                }
1642                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1643                                    appendMemBucket(tag, mi.pss, mi.name, false);
1644                                }
1645                                appendMemBucket(stack, mi.pss, mi.name, true);
1646                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1647                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1648                                    stack.append("(");
1649                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1650                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1651                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1652                                            stack.append(":");
1653                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1654                                        }
1655                                    }
1656                                    stack.append(")");
1657                                }
1658                            }
1659
1660                            logBuilder.append("  ");
1661                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1662                            logBuilder.append(' ');
1663                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1664                            logBuilder.append(' ');
1665                            ProcessList.appendRamKb(logBuilder, mi.pss);
1666                            logBuilder.append(" kB: ");
1667                            logBuilder.append(mi.name);
1668                            logBuilder.append(" (");
1669                            logBuilder.append(mi.pid);
1670                            logBuilder.append(") ");
1671                            logBuilder.append(mi.adjType);
1672                            logBuilder.append('\n');
1673                            if (mi.adjReason != null) {
1674                                logBuilder.append("                      ");
1675                                logBuilder.append(mi.adjReason);
1676                                logBuilder.append('\n');
1677                            }
1678                        }
1679
1680                        logBuilder.append("           ");
1681                        ProcessList.appendRamKb(logBuilder, totalPss);
1682                        logBuilder.append(" kB: TOTAL\n");
1683
1684                        long[] infos = new long[Debug.MEMINFO_COUNT];
1685                        Debug.getMemInfo(infos);
1686                        logBuilder.append("  MemInfo: ");
1687                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1688                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1689                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1690                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1691                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1692                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1693                            logBuilder.append("  ZRAM: ");
1694                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1695                            logBuilder.append(" kB RAM, ");
1696                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1697                            logBuilder.append(" kB swap total, ");
1698                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1699                            logBuilder.append(" kB swap free\n");
1700                        }
1701                        Slog.i(TAG, logBuilder.toString());
1702
1703                        StringBuilder dropBuilder = new StringBuilder(1024);
1704                        /*
1705                        StringWriter oomSw = new StringWriter();
1706                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1707                        StringWriter catSw = new StringWriter();
1708                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1709                        String[] emptyArgs = new String[] { };
1710                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1711                        oomPw.flush();
1712                        String oomString = oomSw.toString();
1713                        */
1714                        dropBuilder.append(stack);
1715                        dropBuilder.append('\n');
1716                        dropBuilder.append('\n');
1717                        dropBuilder.append(logBuilder);
1718                        dropBuilder.append('\n');
1719                        /*
1720                        dropBuilder.append(oomString);
1721                        dropBuilder.append('\n');
1722                        */
1723                        StringWriter catSw = new StringWriter();
1724                        synchronized (ActivityManagerService.this) {
1725                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1726                            String[] emptyArgs = new String[] { };
1727                            catPw.println();
1728                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1729                            catPw.println();
1730                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1731                                    false, false, null);
1732                            catPw.println();
1733                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1734                            catPw.flush();
1735                        }
1736                        dropBuilder.append(catSw.toString());
1737                        addErrorToDropBox("lowmem", null, "system_server", null,
1738                                null, tag.toString(), dropBuilder.toString(), null, null);
1739                        //Slog.i(TAG, "Sent to dropbox:");
1740                        //Slog.i(TAG, dropBuilder.toString());
1741                        synchronized (ActivityManagerService.this) {
1742                            long now = SystemClock.uptimeMillis();
1743                            if (mLastMemUsageReportTime < now) {
1744                                mLastMemUsageReportTime = now;
1745                            }
1746                        }
1747                    }
1748                };
1749                thread.start();
1750                break;
1751            }
1752            case REPORT_USER_SWITCH_MSG: {
1753                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1754                break;
1755            }
1756            case CONTINUE_USER_SWITCH_MSG: {
1757                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1758                break;
1759            }
1760            case USER_SWITCH_TIMEOUT_MSG: {
1761                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1762                break;
1763            }
1764            case IMMERSIVE_MODE_LOCK_MSG: {
1765                final boolean nextState = (msg.arg1 != 0);
1766                if (mUpdateLock.isHeld() != nextState) {
1767                    if (DEBUG_IMMERSIVE) {
1768                        final ActivityRecord r = (ActivityRecord) msg.obj;
1769                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1770                    }
1771                    if (nextState) {
1772                        mUpdateLock.acquire();
1773                    } else {
1774                        mUpdateLock.release();
1775                    }
1776                }
1777                break;
1778            }
1779            case PERSIST_URI_GRANTS_MSG: {
1780                writeGrantedUriPermissions();
1781                break;
1782            }
1783            case REQUEST_ALL_PSS_MSG: {
1784                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1785                break;
1786            }
1787            case START_PROFILES_MSG: {
1788                synchronized (ActivityManagerService.this) {
1789                    startProfilesLocked();
1790                }
1791                break;
1792            }
1793            case UPDATE_TIME: {
1794                synchronized (ActivityManagerService.this) {
1795                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1796                        ProcessRecord r = mLruProcesses.get(i);
1797                        if (r.thread != null) {
1798                            try {
1799                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1800                            } catch (RemoteException ex) {
1801                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1802                            }
1803                        }
1804                    }
1805                }
1806                break;
1807            }
1808            case SYSTEM_USER_START_MSG: {
1809                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1810                        Integer.toString(msg.arg1), msg.arg1);
1811                mSystemServiceManager.startUser(msg.arg1);
1812                break;
1813            }
1814            case SYSTEM_USER_CURRENT_MSG: {
1815                mBatteryStatsService.noteEvent(
1816                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1817                        Integer.toString(msg.arg2), msg.arg2);
1818                mBatteryStatsService.noteEvent(
1819                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1820                        Integer.toString(msg.arg1), msg.arg1);
1821                mSystemServiceManager.switchUser(msg.arg1);
1822                mLockToAppRequest.clearPrompt();
1823                break;
1824            }
1825            case ENTER_ANIMATION_COMPLETE_MSG: {
1826                synchronized (ActivityManagerService.this) {
1827                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1828                    if (r != null && r.app != null && r.app.thread != null) {
1829                        try {
1830                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1831                        } catch (RemoteException e) {
1832                        }
1833                    }
1834                }
1835                break;
1836            }
1837            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1838                enableScreenAfterBoot();
1839                break;
1840            }
1841            }
1842        }
1843    };
1844
1845    static final int COLLECT_PSS_BG_MSG = 1;
1846
1847    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1848        @Override
1849        public void handleMessage(Message msg) {
1850            switch (msg.what) {
1851            case COLLECT_PSS_BG_MSG: {
1852                long start = SystemClock.uptimeMillis();
1853                MemInfoReader memInfo = null;
1854                synchronized (ActivityManagerService.this) {
1855                    if (mFullPssPending) {
1856                        mFullPssPending = false;
1857                        memInfo = new MemInfoReader();
1858                    }
1859                }
1860                if (memInfo != null) {
1861                    updateCpuStatsNow();
1862                    long nativeTotalPss = 0;
1863                    synchronized (mProcessCpuThread) {
1864                        final int N = mProcessCpuTracker.countStats();
1865                        for (int j=0; j<N; j++) {
1866                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1867                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1868                                // This is definitely an application process; skip it.
1869                                continue;
1870                            }
1871                            synchronized (mPidsSelfLocked) {
1872                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1873                                    // This is one of our own processes; skip it.
1874                                    continue;
1875                                }
1876                            }
1877                            nativeTotalPss += Debug.getPss(st.pid, null);
1878                        }
1879                    }
1880                    memInfo.readMemInfo();
1881                    synchronized (this) {
1882                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1883                                + (SystemClock.uptimeMillis()-start) + "ms");
1884                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1885                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1886                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1887                                        +memInfo.getSlabSizeKb(),
1888                                nativeTotalPss);
1889                    }
1890                }
1891
1892                int i=0, num=0;
1893                long[] tmp = new long[1];
1894                do {
1895                    ProcessRecord proc;
1896                    int procState;
1897                    int pid;
1898                    synchronized (ActivityManagerService.this) {
1899                        if (i >= mPendingPssProcesses.size()) {
1900                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1901                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1902                            mPendingPssProcesses.clear();
1903                            return;
1904                        }
1905                        proc = mPendingPssProcesses.get(i);
1906                        procState = proc.pssProcState;
1907                        if (proc.thread != null && procState == proc.setProcState) {
1908                            pid = proc.pid;
1909                        } else {
1910                            proc = null;
1911                            pid = 0;
1912                        }
1913                        i++;
1914                    }
1915                    if (proc != null) {
1916                        long pss = Debug.getPss(pid, tmp);
1917                        synchronized (ActivityManagerService.this) {
1918                            if (proc.thread != null && proc.setProcState == procState
1919                                    && proc.pid == pid) {
1920                                num++;
1921                                proc.lastPssTime = SystemClock.uptimeMillis();
1922                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1923                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1924                                        + ": " + pss + " lastPss=" + proc.lastPss
1925                                        + " state=" + ProcessList.makeProcStateString(procState));
1926                                if (proc.initialIdlePss == 0) {
1927                                    proc.initialIdlePss = pss;
1928                                }
1929                                proc.lastPss = pss;
1930                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1931                                    proc.lastCachedPss = pss;
1932                                }
1933                            }
1934                        }
1935                    }
1936                } while (true);
1937            }
1938            }
1939        }
1940    };
1941
1942    /**
1943     * Monitor for package changes and update our internal state.
1944     */
1945    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1946        @Override
1947        public void onPackageRemoved(String packageName, int uid) {
1948            // Remove all tasks with activities in the specified package from the list of recent tasks
1949            synchronized (ActivityManagerService.this) {
1950                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1951                    TaskRecord tr = mRecentTasks.get(i);
1952                    ComponentName cn = tr.intent.getComponent();
1953                    if (cn != null && cn.getPackageName().equals(packageName)) {
1954                        // If the package name matches, remove the task and kill the process
1955                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1956                    }
1957                }
1958            }
1959        }
1960
1961        @Override
1962        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1963            onPackageModified(packageName);
1964            return true;
1965        }
1966
1967        @Override
1968        public void onPackageModified(String packageName) {
1969            final PackageManager pm = mContext.getPackageManager();
1970            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1971                    new ArrayList<Pair<Intent, Integer>>();
1972            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1973            // Copy the list of recent tasks so that we don't hold onto the lock on
1974            // ActivityManagerService for long periods while checking if components exist.
1975            synchronized (ActivityManagerService.this) {
1976                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1977                    TaskRecord tr = mRecentTasks.get(i);
1978                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1979                }
1980            }
1981            // Check the recent tasks and filter out all tasks with components that no longer exist.
1982            Intent tmpI = new Intent();
1983            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1984                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1985                ComponentName cn = p.first.getComponent();
1986                if (cn != null && cn.getPackageName().equals(packageName)) {
1987                    try {
1988                        // Add the task to the list to remove if the component no longer exists
1989                        tmpI.setComponent(cn);
1990                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1991                            tasksToRemove.add(p.second);
1992                        }
1993                    } catch (Exception e) {}
1994                }
1995            }
1996            // Prune all the tasks with removed components from the list of recent tasks
1997            synchronized (ActivityManagerService.this) {
1998                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1999                    // Remove the task but don't kill the process (since other components in that
2000                    // package may still be running and in the background)
2001                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2002                }
2003            }
2004        }
2005
2006        @Override
2007        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2008            // Force stop the specified packages
2009            if (packages != null) {
2010                for (String pkg : packages) {
2011                    synchronized (ActivityManagerService.this) {
2012                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2013                                "finished booting")) {
2014                            return true;
2015                        }
2016                    }
2017                }
2018            }
2019            return false;
2020        }
2021    };
2022
2023    public void setSystemProcess() {
2024        try {
2025            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2026            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2027            ServiceManager.addService("meminfo", new MemBinder(this));
2028            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2029            ServiceManager.addService("dbinfo", new DbBinder(this));
2030            if (MONITOR_CPU_USAGE) {
2031                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2032            }
2033            ServiceManager.addService("permission", new PermissionController(this));
2034
2035            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2036                    "android", STOCK_PM_FLAGS);
2037            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2038
2039            synchronized (this) {
2040                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2041                app.persistent = true;
2042                app.pid = MY_PID;
2043                app.maxAdj = ProcessList.SYSTEM_ADJ;
2044                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2045                mProcessNames.put(app.processName, app.uid, app);
2046                synchronized (mPidsSelfLocked) {
2047                    mPidsSelfLocked.put(app.pid, app);
2048                }
2049                updateLruProcessLocked(app, false, null);
2050                updateOomAdjLocked();
2051            }
2052        } catch (PackageManager.NameNotFoundException e) {
2053            throw new RuntimeException(
2054                    "Unable to find android system package", e);
2055        }
2056    }
2057
2058    public void setWindowManager(WindowManagerService wm) {
2059        mWindowManager = wm;
2060        mStackSupervisor.setWindowManager(wm);
2061    }
2062
2063    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2064        mUsageStatsService = usageStatsManager;
2065    }
2066
2067    public void startObservingNativeCrashes() {
2068        final NativeCrashListener ncl = new NativeCrashListener(this);
2069        ncl.start();
2070    }
2071
2072    public IAppOpsService getAppOpsService() {
2073        return mAppOpsService;
2074    }
2075
2076    static class MemBinder extends Binder {
2077        ActivityManagerService mActivityManagerService;
2078        MemBinder(ActivityManagerService activityManagerService) {
2079            mActivityManagerService = activityManagerService;
2080        }
2081
2082        @Override
2083        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2084            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2085                    != PackageManager.PERMISSION_GRANTED) {
2086                pw.println("Permission Denial: can't dump meminfo from from pid="
2087                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2088                        + " without permission " + android.Manifest.permission.DUMP);
2089                return;
2090            }
2091
2092            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2093        }
2094    }
2095
2096    static class GraphicsBinder extends Binder {
2097        ActivityManagerService mActivityManagerService;
2098        GraphicsBinder(ActivityManagerService activityManagerService) {
2099            mActivityManagerService = activityManagerService;
2100        }
2101
2102        @Override
2103        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2104            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2105                    != PackageManager.PERMISSION_GRANTED) {
2106                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2107                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2108                        + " without permission " + android.Manifest.permission.DUMP);
2109                return;
2110            }
2111
2112            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2113        }
2114    }
2115
2116    static class DbBinder extends Binder {
2117        ActivityManagerService mActivityManagerService;
2118        DbBinder(ActivityManagerService activityManagerService) {
2119            mActivityManagerService = activityManagerService;
2120        }
2121
2122        @Override
2123        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2124            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2125                    != PackageManager.PERMISSION_GRANTED) {
2126                pw.println("Permission Denial: can't dump dbinfo from from pid="
2127                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2128                        + " without permission " + android.Manifest.permission.DUMP);
2129                return;
2130            }
2131
2132            mActivityManagerService.dumpDbInfo(fd, pw, args);
2133        }
2134    }
2135
2136    static class CpuBinder extends Binder {
2137        ActivityManagerService mActivityManagerService;
2138        CpuBinder(ActivityManagerService activityManagerService) {
2139            mActivityManagerService = activityManagerService;
2140        }
2141
2142        @Override
2143        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2144            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2145                    != PackageManager.PERMISSION_GRANTED) {
2146                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2147                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2148                        + " without permission " + android.Manifest.permission.DUMP);
2149                return;
2150            }
2151
2152            synchronized (mActivityManagerService.mProcessCpuThread) {
2153                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2154                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2155                        SystemClock.uptimeMillis()));
2156            }
2157        }
2158    }
2159
2160    public static final class Lifecycle extends SystemService {
2161        private final ActivityManagerService mService;
2162
2163        public Lifecycle(Context context) {
2164            super(context);
2165            mService = new ActivityManagerService(context);
2166        }
2167
2168        @Override
2169        public void onStart() {
2170            mService.start();
2171        }
2172
2173        public ActivityManagerService getService() {
2174            return mService;
2175        }
2176    }
2177
2178    // Note: This method is invoked on the main thread but may need to attach various
2179    // handlers to other threads.  So take care to be explicit about the looper.
2180    public ActivityManagerService(Context systemContext) {
2181        mContext = systemContext;
2182        mFactoryTest = FactoryTest.getMode();
2183        mSystemThread = ActivityThread.currentActivityThread();
2184
2185        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2186
2187        mHandlerThread = new ServiceThread(TAG,
2188                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2189        mHandlerThread.start();
2190        mHandler = new MainHandler(mHandlerThread.getLooper());
2191
2192        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2193                "foreground", BROADCAST_FG_TIMEOUT, false);
2194        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2195                "background", BROADCAST_BG_TIMEOUT, true);
2196        mBroadcastQueues[0] = mFgBroadcastQueue;
2197        mBroadcastQueues[1] = mBgBroadcastQueue;
2198
2199        mServices = new ActiveServices(this);
2200        mProviderMap = new ProviderMap(this);
2201
2202        // TODO: Move creation of battery stats service outside of activity manager service.
2203        File dataDir = Environment.getDataDirectory();
2204        File systemDir = new File(dataDir, "system");
2205        systemDir.mkdirs();
2206        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2207        mBatteryStatsService.getActiveStatistics().readLocked();
2208        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2209        mOnBattery = DEBUG_POWER ? true
2210                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2211        mBatteryStatsService.getActiveStatistics().setCallback(this);
2212
2213        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2214
2215        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2216
2217        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2218
2219        // User 0 is the first and only user that runs at boot.
2220        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2221        mUserLru.add(Integer.valueOf(0));
2222        updateStartedUserArrayLocked();
2223
2224        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2225            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2226
2227        mConfiguration.setToDefaults();
2228        mConfiguration.setLocale(Locale.getDefault());
2229
2230        mConfigurationSeq = mConfiguration.seq = 1;
2231        mProcessCpuTracker.init();
2232
2233        mHasRecents = mContext.getResources().getBoolean(
2234                com.android.internal.R.bool.config_hasRecents);
2235
2236        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2237        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2238        mStackSupervisor = new ActivityStackSupervisor(this);
2239        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2240
2241        mProcessCpuThread = new Thread("CpuTracker") {
2242            @Override
2243            public void run() {
2244                while (true) {
2245                    try {
2246                        try {
2247                            synchronized(this) {
2248                                final long now = SystemClock.uptimeMillis();
2249                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2250                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2251                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2252                                //        + ", write delay=" + nextWriteDelay);
2253                                if (nextWriteDelay < nextCpuDelay) {
2254                                    nextCpuDelay = nextWriteDelay;
2255                                }
2256                                if (nextCpuDelay > 0) {
2257                                    mProcessCpuMutexFree.set(true);
2258                                    this.wait(nextCpuDelay);
2259                                }
2260                            }
2261                        } catch (InterruptedException e) {
2262                        }
2263                        updateCpuStatsNow();
2264                    } catch (Exception e) {
2265                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2266                    }
2267                }
2268            }
2269        };
2270
2271        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2272
2273        Watchdog.getInstance().addMonitor(this);
2274        Watchdog.getInstance().addThread(mHandler);
2275    }
2276
2277    public void setSystemServiceManager(SystemServiceManager mgr) {
2278        mSystemServiceManager = mgr;
2279    }
2280
2281    private void start() {
2282        Process.removeAllProcessGroups();
2283        mProcessCpuThread.start();
2284
2285        mBatteryStatsService.publish(mContext);
2286        mAppOpsService.publish(mContext);
2287        Slog.d("AppOps", "AppOpsService published");
2288        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2289    }
2290
2291    public void initPowerManagement() {
2292        mStackSupervisor.initPowerManagement();
2293        mBatteryStatsService.initPowerManagement();
2294    }
2295
2296    @Override
2297    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2298            throws RemoteException {
2299        if (code == SYSPROPS_TRANSACTION) {
2300            // We need to tell all apps about the system property change.
2301            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2302            synchronized(this) {
2303                final int NP = mProcessNames.getMap().size();
2304                for (int ip=0; ip<NP; ip++) {
2305                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2306                    final int NA = apps.size();
2307                    for (int ia=0; ia<NA; ia++) {
2308                        ProcessRecord app = apps.valueAt(ia);
2309                        if (app.thread != null) {
2310                            procs.add(app.thread.asBinder());
2311                        }
2312                    }
2313                }
2314            }
2315
2316            int N = procs.size();
2317            for (int i=0; i<N; i++) {
2318                Parcel data2 = Parcel.obtain();
2319                try {
2320                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2321                } catch (RemoteException e) {
2322                }
2323                data2.recycle();
2324            }
2325        }
2326        try {
2327            return super.onTransact(code, data, reply, flags);
2328        } catch (RuntimeException e) {
2329            // The activity manager only throws security exceptions, so let's
2330            // log all others.
2331            if (!(e instanceof SecurityException)) {
2332                Slog.wtf(TAG, "Activity Manager Crash", e);
2333            }
2334            throw e;
2335        }
2336    }
2337
2338    void updateCpuStats() {
2339        final long now = SystemClock.uptimeMillis();
2340        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2341            return;
2342        }
2343        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2344            synchronized (mProcessCpuThread) {
2345                mProcessCpuThread.notify();
2346            }
2347        }
2348    }
2349
2350    void updateCpuStatsNow() {
2351        synchronized (mProcessCpuThread) {
2352            mProcessCpuMutexFree.set(false);
2353            final long now = SystemClock.uptimeMillis();
2354            boolean haveNewCpuStats = false;
2355
2356            if (MONITOR_CPU_USAGE &&
2357                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2358                mLastCpuTime.set(now);
2359                haveNewCpuStats = true;
2360                mProcessCpuTracker.update();
2361                //Slog.i(TAG, mProcessCpu.printCurrentState());
2362                //Slog.i(TAG, "Total CPU usage: "
2363                //        + mProcessCpu.getTotalCpuPercent() + "%");
2364
2365                // Slog the cpu usage if the property is set.
2366                if ("true".equals(SystemProperties.get("events.cpu"))) {
2367                    int user = mProcessCpuTracker.getLastUserTime();
2368                    int system = mProcessCpuTracker.getLastSystemTime();
2369                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2370                    int irq = mProcessCpuTracker.getLastIrqTime();
2371                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2372                    int idle = mProcessCpuTracker.getLastIdleTime();
2373
2374                    int total = user + system + iowait + irq + softIrq + idle;
2375                    if (total == 0) total = 1;
2376
2377                    EventLog.writeEvent(EventLogTags.CPU,
2378                            ((user+system+iowait+irq+softIrq) * 100) / total,
2379                            (user * 100) / total,
2380                            (system * 100) / total,
2381                            (iowait * 100) / total,
2382                            (irq * 100) / total,
2383                            (softIrq * 100) / total);
2384                }
2385            }
2386
2387            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2388            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2389            synchronized(bstats) {
2390                synchronized(mPidsSelfLocked) {
2391                    if (haveNewCpuStats) {
2392                        if (mOnBattery) {
2393                            int perc = bstats.startAddingCpuLocked();
2394                            int totalUTime = 0;
2395                            int totalSTime = 0;
2396                            final int N = mProcessCpuTracker.countStats();
2397                            for (int i=0; i<N; i++) {
2398                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2399                                if (!st.working) {
2400                                    continue;
2401                                }
2402                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2403                                int otherUTime = (st.rel_utime*perc)/100;
2404                                int otherSTime = (st.rel_stime*perc)/100;
2405                                totalUTime += otherUTime;
2406                                totalSTime += otherSTime;
2407                                if (pr != null) {
2408                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2409                                    if (ps == null || !ps.isActive()) {
2410                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2411                                                pr.info.uid, pr.processName);
2412                                    }
2413                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2414                                            st.rel_stime-otherSTime);
2415                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2416                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2417                                } else {
2418                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2419                                    if (ps == null || !ps.isActive()) {
2420                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2421                                                bstats.mapUid(st.uid), st.name);
2422                                    }
2423                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2424                                            st.rel_stime-otherSTime);
2425                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2426                                }
2427                            }
2428                            bstats.finishAddingCpuLocked(perc, totalUTime,
2429                                    totalSTime, cpuSpeedTimes);
2430                        }
2431                    }
2432                }
2433
2434                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2435                    mLastWriteTime = now;
2436                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2437                }
2438            }
2439        }
2440    }
2441
2442    @Override
2443    public void batteryNeedsCpuUpdate() {
2444        updateCpuStatsNow();
2445    }
2446
2447    @Override
2448    public void batteryPowerChanged(boolean onBattery) {
2449        // When plugging in, update the CPU stats first before changing
2450        // the plug state.
2451        updateCpuStatsNow();
2452        synchronized (this) {
2453            synchronized(mPidsSelfLocked) {
2454                mOnBattery = DEBUG_POWER ? true : onBattery;
2455            }
2456        }
2457    }
2458
2459    /**
2460     * Initialize the application bind args. These are passed to each
2461     * process when the bindApplication() IPC is sent to the process. They're
2462     * lazily setup to make sure the services are running when they're asked for.
2463     */
2464    private HashMap<String, IBinder> getCommonServicesLocked() {
2465        if (mAppBindArgs == null) {
2466            mAppBindArgs = new HashMap<String, IBinder>();
2467
2468            // Setup the application init args
2469            mAppBindArgs.put("package", ServiceManager.getService("package"));
2470            mAppBindArgs.put("window", ServiceManager.getService("window"));
2471            mAppBindArgs.put(Context.ALARM_SERVICE,
2472                    ServiceManager.getService(Context.ALARM_SERVICE));
2473        }
2474        return mAppBindArgs;
2475    }
2476
2477    final void setFocusedActivityLocked(ActivityRecord r) {
2478        if (mFocusedActivity != r) {
2479            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2480            mFocusedActivity = r;
2481            if (r.task != null && r.task.voiceInteractor != null) {
2482                startRunningVoiceLocked();
2483            } else {
2484                finishRunningVoiceLocked();
2485            }
2486            mStackSupervisor.setFocusedStack(r);
2487            if (r != null) {
2488                mWindowManager.setFocusedApp(r.appToken, true);
2489            }
2490            applyUpdateLockStateLocked(r);
2491        }
2492    }
2493
2494    final void clearFocusedActivity(ActivityRecord r) {
2495        if (mFocusedActivity == r) {
2496            mFocusedActivity = null;
2497        }
2498    }
2499
2500    @Override
2501    public void setFocusedStack(int stackId) {
2502        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2503        synchronized (ActivityManagerService.this) {
2504            ActivityStack stack = mStackSupervisor.getStack(stackId);
2505            if (stack != null) {
2506                ActivityRecord r = stack.topRunningActivityLocked(null);
2507                if (r != null) {
2508                    setFocusedActivityLocked(r);
2509                }
2510            }
2511        }
2512    }
2513
2514    @Override
2515    public void notifyActivityDrawn(IBinder token) {
2516        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2517        synchronized (this) {
2518            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2519            if (r != null) {
2520                r.task.stack.notifyActivityDrawnLocked(r);
2521            }
2522        }
2523    }
2524
2525    final void applyUpdateLockStateLocked(ActivityRecord r) {
2526        // Modifications to the UpdateLock state are done on our handler, outside
2527        // the activity manager's locks.  The new state is determined based on the
2528        // state *now* of the relevant activity record.  The object is passed to
2529        // the handler solely for logging detail, not to be consulted/modified.
2530        final boolean nextState = r != null && r.immersive;
2531        mHandler.sendMessage(
2532                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2533    }
2534
2535    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2536        Message msg = Message.obtain();
2537        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2538        msg.obj = r.task.askedCompatMode ? null : r;
2539        mHandler.sendMessage(msg);
2540    }
2541
2542    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2543            String what, Object obj, ProcessRecord srcApp) {
2544        app.lastActivityTime = now;
2545
2546        if (app.activities.size() > 0) {
2547            // Don't want to touch dependent processes that are hosting activities.
2548            return index;
2549        }
2550
2551        int lrui = mLruProcesses.lastIndexOf(app);
2552        if (lrui < 0) {
2553            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2554                    + what + " " + obj + " from " + srcApp);
2555            return index;
2556        }
2557
2558        if (lrui >= index) {
2559            // Don't want to cause this to move dependent processes *back* in the
2560            // list as if they were less frequently used.
2561            return index;
2562        }
2563
2564        if (lrui >= mLruProcessActivityStart) {
2565            // Don't want to touch dependent processes that are hosting activities.
2566            return index;
2567        }
2568
2569        mLruProcesses.remove(lrui);
2570        if (index > 0) {
2571            index--;
2572        }
2573        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2574                + " in LRU list: " + app);
2575        mLruProcesses.add(index, app);
2576        return index;
2577    }
2578
2579    final void removeLruProcessLocked(ProcessRecord app) {
2580        int lrui = mLruProcesses.lastIndexOf(app);
2581        if (lrui >= 0) {
2582            if (lrui <= mLruProcessActivityStart) {
2583                mLruProcessActivityStart--;
2584            }
2585            if (lrui <= mLruProcessServiceStart) {
2586                mLruProcessServiceStart--;
2587            }
2588            mLruProcesses.remove(lrui);
2589        }
2590    }
2591
2592    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2593            ProcessRecord client) {
2594        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2595                || app.treatLikeActivity;
2596        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2597        if (!activityChange && hasActivity) {
2598            // The process has activities, so we are only allowing activity-based adjustments
2599            // to move it.  It should be kept in the front of the list with other
2600            // processes that have activities, and we don't want those to change their
2601            // order except due to activity operations.
2602            return;
2603        }
2604
2605        mLruSeq++;
2606        final long now = SystemClock.uptimeMillis();
2607        app.lastActivityTime = now;
2608
2609        // First a quick reject: if the app is already at the position we will
2610        // put it, then there is nothing to do.
2611        if (hasActivity) {
2612            final int N = mLruProcesses.size();
2613            if (N > 0 && mLruProcesses.get(N-1) == app) {
2614                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2615                return;
2616            }
2617        } else {
2618            if (mLruProcessServiceStart > 0
2619                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2620                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2621                return;
2622            }
2623        }
2624
2625        int lrui = mLruProcesses.lastIndexOf(app);
2626
2627        if (app.persistent && lrui >= 0) {
2628            // We don't care about the position of persistent processes, as long as
2629            // they are in the list.
2630            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2631            return;
2632        }
2633
2634        /* In progress: compute new position first, so we can avoid doing work
2635           if the process is not actually going to move.  Not yet working.
2636        int addIndex;
2637        int nextIndex;
2638        boolean inActivity = false, inService = false;
2639        if (hasActivity) {
2640            // Process has activities, put it at the very tipsy-top.
2641            addIndex = mLruProcesses.size();
2642            nextIndex = mLruProcessServiceStart;
2643            inActivity = true;
2644        } else if (hasService) {
2645            // Process has services, put it at the top of the service list.
2646            addIndex = mLruProcessActivityStart;
2647            nextIndex = mLruProcessServiceStart;
2648            inActivity = true;
2649            inService = true;
2650        } else  {
2651            // Process not otherwise of interest, it goes to the top of the non-service area.
2652            addIndex = mLruProcessServiceStart;
2653            if (client != null) {
2654                int clientIndex = mLruProcesses.lastIndexOf(client);
2655                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2656                        + app);
2657                if (clientIndex >= 0 && addIndex > clientIndex) {
2658                    addIndex = clientIndex;
2659                }
2660            }
2661            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2662        }
2663
2664        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2665                + mLruProcessActivityStart + "): " + app);
2666        */
2667
2668        if (lrui >= 0) {
2669            if (lrui < mLruProcessActivityStart) {
2670                mLruProcessActivityStart--;
2671            }
2672            if (lrui < mLruProcessServiceStart) {
2673                mLruProcessServiceStart--;
2674            }
2675            /*
2676            if (addIndex > lrui) {
2677                addIndex--;
2678            }
2679            if (nextIndex > lrui) {
2680                nextIndex--;
2681            }
2682            */
2683            mLruProcesses.remove(lrui);
2684        }
2685
2686        /*
2687        mLruProcesses.add(addIndex, app);
2688        if (inActivity) {
2689            mLruProcessActivityStart++;
2690        }
2691        if (inService) {
2692            mLruProcessActivityStart++;
2693        }
2694        */
2695
2696        int nextIndex;
2697        if (hasActivity) {
2698            final int N = mLruProcesses.size();
2699            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2700                // Process doesn't have activities, but has clients with
2701                // activities...  move it up, but one below the top (the top
2702                // should always have a real activity).
2703                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2704                mLruProcesses.add(N-1, app);
2705                // To keep it from spamming the LRU list (by making a bunch of clients),
2706                // we will push down any other entries owned by the app.
2707                final int uid = app.info.uid;
2708                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2709                    ProcessRecord subProc = mLruProcesses.get(i);
2710                    if (subProc.info.uid == uid) {
2711                        // We want to push this one down the list.  If the process after
2712                        // it is for the same uid, however, don't do so, because we don't
2713                        // want them internally to be re-ordered.
2714                        if (mLruProcesses.get(i-1).info.uid != uid) {
2715                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2716                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2717                            ProcessRecord tmp = mLruProcesses.get(i);
2718                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2719                            mLruProcesses.set(i-1, tmp);
2720                            i--;
2721                        }
2722                    } else {
2723                        // A gap, we can stop here.
2724                        break;
2725                    }
2726                }
2727            } else {
2728                // Process has activities, put it at the very tipsy-top.
2729                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2730                mLruProcesses.add(app);
2731            }
2732            nextIndex = mLruProcessServiceStart;
2733        } else if (hasService) {
2734            // Process has services, put it at the top of the service list.
2735            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2736            mLruProcesses.add(mLruProcessActivityStart, app);
2737            nextIndex = mLruProcessServiceStart;
2738            mLruProcessActivityStart++;
2739        } else  {
2740            // Process not otherwise of interest, it goes to the top of the non-service area.
2741            int index = mLruProcessServiceStart;
2742            if (client != null) {
2743                // If there is a client, don't allow the process to be moved up higher
2744                // in the list than that client.
2745                int clientIndex = mLruProcesses.lastIndexOf(client);
2746                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2747                        + " when updating " + app);
2748                if (clientIndex <= lrui) {
2749                    // Don't allow the client index restriction to push it down farther in the
2750                    // list than it already is.
2751                    clientIndex = lrui;
2752                }
2753                if (clientIndex >= 0 && index > clientIndex) {
2754                    index = clientIndex;
2755                }
2756            }
2757            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2758            mLruProcesses.add(index, app);
2759            nextIndex = index-1;
2760            mLruProcessActivityStart++;
2761            mLruProcessServiceStart++;
2762        }
2763
2764        // If the app is currently using a content provider or service,
2765        // bump those processes as well.
2766        for (int j=app.connections.size()-1; j>=0; j--) {
2767            ConnectionRecord cr = app.connections.valueAt(j);
2768            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2769                    && cr.binding.service.app != null
2770                    && cr.binding.service.app.lruSeq != mLruSeq
2771                    && !cr.binding.service.app.persistent) {
2772                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2773                        "service connection", cr, app);
2774            }
2775        }
2776        for (int j=app.conProviders.size()-1; j>=0; j--) {
2777            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2778            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2779                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2780                        "provider reference", cpr, app);
2781            }
2782        }
2783    }
2784
2785    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2786        if (uid == Process.SYSTEM_UID) {
2787            // The system gets to run in any process.  If there are multiple
2788            // processes with the same uid, just pick the first (this
2789            // should never happen).
2790            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2791            if (procs == null) return null;
2792            final int N = procs.size();
2793            for (int i = 0; i < N; i++) {
2794                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2795            }
2796        }
2797        ProcessRecord proc = mProcessNames.get(processName, uid);
2798        if (false && proc != null && !keepIfLarge
2799                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2800                && proc.lastCachedPss >= 4000) {
2801            // Turn this condition on to cause killing to happen regularly, for testing.
2802            if (proc.baseProcessTracker != null) {
2803                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2804            }
2805            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2806                    + "k from cached");
2807        } else if (proc != null && !keepIfLarge
2808                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2809                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2810            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2811            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2812                if (proc.baseProcessTracker != null) {
2813                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2814                }
2815                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2816                        + "k from cached");
2817            }
2818        }
2819        return proc;
2820    }
2821
2822    void ensurePackageDexOpt(String packageName) {
2823        IPackageManager pm = AppGlobals.getPackageManager();
2824        try {
2825            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2826                mDidDexOpt = true;
2827            }
2828        } catch (RemoteException e) {
2829        }
2830    }
2831
2832    boolean isNextTransitionForward() {
2833        int transit = mWindowManager.getPendingAppTransition();
2834        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2835                || transit == AppTransition.TRANSIT_TASK_OPEN
2836                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2837    }
2838
2839    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2840            String processName, String abiOverride, int uid, Runnable crashHandler) {
2841        synchronized(this) {
2842            ApplicationInfo info = new ApplicationInfo();
2843            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2844            // For isolated processes, the former contains the parent's uid and the latter the
2845            // actual uid of the isolated process.
2846            // In the special case introduced by this method (which is, starting an isolated
2847            // process directly from the SystemServer without an actual parent app process) the
2848            // closest thing to a parent's uid is SYSTEM_UID.
2849            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2850            // the |isolated| logic in the ProcessRecord constructor.
2851            info.uid = Process.SYSTEM_UID;
2852            info.processName = processName;
2853            info.className = entryPoint;
2854            info.packageName = "android";
2855            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2856                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2857                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2858                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2859                    crashHandler);
2860            return proc != null ? proc.pid : 0;
2861        }
2862    }
2863
2864    final ProcessRecord startProcessLocked(String processName,
2865            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2866            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2867            boolean isolated, boolean keepIfLarge) {
2868        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2869                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2870                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2871                null /* crashHandler */);
2872    }
2873
2874    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2875            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2876            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2877            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2878        ProcessRecord app;
2879        if (!isolated) {
2880            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2881        } else {
2882            // If this is an isolated process, it can't re-use an existing process.
2883            app = null;
2884        }
2885        // We don't have to do anything more if:
2886        // (1) There is an existing application record; and
2887        // (2) The caller doesn't think it is dead, OR there is no thread
2888        //     object attached to it so we know it couldn't have crashed; and
2889        // (3) There is a pid assigned to it, so it is either starting or
2890        //     already running.
2891        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2892                + " app=" + app + " knownToBeDead=" + knownToBeDead
2893                + " thread=" + (app != null ? app.thread : null)
2894                + " pid=" + (app != null ? app.pid : -1));
2895        if (app != null && app.pid > 0) {
2896            if (!knownToBeDead || app.thread == null) {
2897                // We already have the app running, or are waiting for it to
2898                // come up (we have a pid but not yet its thread), so keep it.
2899                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2900                // If this is a new package in the process, add the package to the list
2901                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2902                return app;
2903            }
2904
2905            // An application record is attached to a previous process,
2906            // clean it up now.
2907            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2908            Process.killProcessGroup(app.info.uid, app.pid);
2909            handleAppDiedLocked(app, true, true);
2910        }
2911
2912        String hostingNameStr = hostingName != null
2913                ? hostingName.flattenToShortString() : null;
2914
2915        if (!isolated) {
2916            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2917                // If we are in the background, then check to see if this process
2918                // is bad.  If so, we will just silently fail.
2919                if (mBadProcesses.get(info.processName, info.uid) != null) {
2920                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2921                            + "/" + info.processName);
2922                    return null;
2923                }
2924            } else {
2925                // When the user is explicitly starting a process, then clear its
2926                // crash count so that we won't make it bad until they see at
2927                // least one crash dialog again, and make the process good again
2928                // if it had been bad.
2929                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2930                        + "/" + info.processName);
2931                mProcessCrashTimes.remove(info.processName, info.uid);
2932                if (mBadProcesses.get(info.processName, info.uid) != null) {
2933                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2934                            UserHandle.getUserId(info.uid), info.uid,
2935                            info.processName);
2936                    mBadProcesses.remove(info.processName, info.uid);
2937                    if (app != null) {
2938                        app.bad = false;
2939                    }
2940                }
2941            }
2942        }
2943
2944        if (app == null) {
2945            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2946            app.crashHandler = crashHandler;
2947            if (app == null) {
2948                Slog.w(TAG, "Failed making new process record for "
2949                        + processName + "/" + info.uid + " isolated=" + isolated);
2950                return null;
2951            }
2952            mProcessNames.put(processName, app.uid, app);
2953            if (isolated) {
2954                mIsolatedProcesses.put(app.uid, app);
2955            }
2956        } else {
2957            // If this is a new package in the process, add the package to the list
2958            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2959        }
2960
2961        // If the system is not ready yet, then hold off on starting this
2962        // process until it is.
2963        if (!mProcessesReady
2964                && !isAllowedWhileBooting(info)
2965                && !allowWhileBooting) {
2966            if (!mProcessesOnHold.contains(app)) {
2967                mProcessesOnHold.add(app);
2968            }
2969            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2970            return app;
2971        }
2972
2973        startProcessLocked(
2974                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2975        return (app.pid != 0) ? app : null;
2976    }
2977
2978    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2979        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2980    }
2981
2982    private final void startProcessLocked(ProcessRecord app,
2983            String hostingType, String hostingNameStr) {
2984        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2985                null /* entryPoint */, null /* entryPointArgs */);
2986    }
2987
2988    private final void startProcessLocked(ProcessRecord app, String hostingType,
2989            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2990        if (app.pid > 0 && app.pid != MY_PID) {
2991            synchronized (mPidsSelfLocked) {
2992                mPidsSelfLocked.remove(app.pid);
2993                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2994            }
2995            app.setPid(0);
2996        }
2997
2998        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2999                "startProcessLocked removing on hold: " + app);
3000        mProcessesOnHold.remove(app);
3001
3002        updateCpuStats();
3003
3004        try {
3005            int uid = app.uid;
3006
3007            int[] gids = null;
3008            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3009            if (!app.isolated) {
3010                int[] permGids = null;
3011                try {
3012                    final PackageManager pm = mContext.getPackageManager();
3013                    permGids = pm.getPackageGids(app.info.packageName);
3014
3015                    if (Environment.isExternalStorageEmulated()) {
3016                        if (pm.checkPermission(
3017                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3018                                app.info.packageName) == PERMISSION_GRANTED) {
3019                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3020                        } else {
3021                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3022                        }
3023                    }
3024                } catch (PackageManager.NameNotFoundException e) {
3025                    Slog.w(TAG, "Unable to retrieve gids", e);
3026                }
3027
3028                /*
3029                 * Add shared application and profile GIDs so applications can share some
3030                 * resources like shared libraries and access user-wide resources
3031                 */
3032                if (permGids == null) {
3033                    gids = new int[2];
3034                } else {
3035                    gids = new int[permGids.length + 2];
3036                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3037                }
3038                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3039                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3040            }
3041            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3042                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3043                        && mTopComponent != null
3044                        && app.processName.equals(mTopComponent.getPackageName())) {
3045                    uid = 0;
3046                }
3047                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3048                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3049                    uid = 0;
3050                }
3051            }
3052            int debugFlags = 0;
3053            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3054                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3055                // Also turn on CheckJNI for debuggable apps. It's quite
3056                // awkward to turn on otherwise.
3057                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3058            }
3059            // Run the app in safe mode if its manifest requests so or the
3060            // system is booted in safe mode.
3061            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3062                mSafeMode == true) {
3063                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3064            }
3065            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3066                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3067            }
3068            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3069                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3070            }
3071            if ("1".equals(SystemProperties.get("debug.assert"))) {
3072                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3073            }
3074
3075            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3076            if (requiredAbi == null) {
3077                requiredAbi = Build.SUPPORTED_ABIS[0];
3078            }
3079
3080            // Start the process.  It will either succeed and return a result containing
3081            // the PID of the new process, or else throw a RuntimeException.
3082            boolean isActivityProcess = (entryPoint == null);
3083            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3084            Process.ProcessStartResult startResult = Process.start(entryPoint,
3085                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3086                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
3087
3088            if (app.isolated) {
3089                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3090            }
3091            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3092
3093            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3094                    UserHandle.getUserId(uid), startResult.pid, uid,
3095                    app.processName, hostingType,
3096                    hostingNameStr != null ? hostingNameStr : "");
3097
3098            if (app.persistent) {
3099                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3100            }
3101
3102            StringBuilder buf = mStringBuilder;
3103            buf.setLength(0);
3104            buf.append("Start proc ");
3105            buf.append(app.processName);
3106            if (!isActivityProcess) {
3107                buf.append(" [");
3108                buf.append(entryPoint);
3109                buf.append("]");
3110            }
3111            buf.append(" for ");
3112            buf.append(hostingType);
3113            if (hostingNameStr != null) {
3114                buf.append(" ");
3115                buf.append(hostingNameStr);
3116            }
3117            buf.append(": pid=");
3118            buf.append(startResult.pid);
3119            buf.append(" uid=");
3120            buf.append(uid);
3121            buf.append(" gids={");
3122            if (gids != null) {
3123                for (int gi=0; gi<gids.length; gi++) {
3124                    if (gi != 0) buf.append(", ");
3125                    buf.append(gids[gi]);
3126
3127                }
3128            }
3129            buf.append("}");
3130            if (requiredAbi != null) {
3131                buf.append(" abi=");
3132                buf.append(requiredAbi);
3133            }
3134            Slog.i(TAG, buf.toString());
3135            app.setPid(startResult.pid);
3136            app.usingWrapper = startResult.usingWrapper;
3137            app.removed = false;
3138            app.killedByAm = false;
3139            synchronized (mPidsSelfLocked) {
3140                this.mPidsSelfLocked.put(startResult.pid, app);
3141                if (isActivityProcess) {
3142                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3143                    msg.obj = app;
3144                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3145                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3146                }
3147            }
3148        } catch (RuntimeException e) {
3149            // XXX do better error recovery.
3150            app.setPid(0);
3151            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3152            if (app.isolated) {
3153                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3154            }
3155            Slog.e(TAG, "Failure starting process " + app.processName, e);
3156        }
3157    }
3158
3159    void updateUsageStats(ActivityRecord component, boolean resumed) {
3160        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3161        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3162        if (resumed) {
3163            if (mUsageStatsService != null) {
3164                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3165                        System.currentTimeMillis(),
3166                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3167            }
3168            synchronized (stats) {
3169                stats.noteActivityResumedLocked(component.app.uid);
3170            }
3171        } else {
3172            if (mUsageStatsService != null) {
3173                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3174                        System.currentTimeMillis(),
3175                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3176            }
3177            synchronized (stats) {
3178                stats.noteActivityPausedLocked(component.app.uid);
3179            }
3180        }
3181    }
3182
3183    Intent getHomeIntent() {
3184        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3185        intent.setComponent(mTopComponent);
3186        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3187            intent.addCategory(Intent.CATEGORY_HOME);
3188        }
3189        return intent;
3190    }
3191
3192    boolean startHomeActivityLocked(int userId) {
3193        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3194                && mTopAction == null) {
3195            // We are running in factory test mode, but unable to find
3196            // the factory test app, so just sit around displaying the
3197            // error message and don't try to start anything.
3198            return false;
3199        }
3200        Intent intent = getHomeIntent();
3201        ActivityInfo aInfo =
3202            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3203        if (aInfo != null) {
3204            intent.setComponent(new ComponentName(
3205                    aInfo.applicationInfo.packageName, aInfo.name));
3206            // Don't do this if the home app is currently being
3207            // instrumented.
3208            aInfo = new ActivityInfo(aInfo);
3209            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3210            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3211                    aInfo.applicationInfo.uid, true);
3212            if (app == null || app.instrumentationClass == null) {
3213                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3214                mStackSupervisor.startHomeActivity(intent, aInfo);
3215            }
3216        }
3217
3218        return true;
3219    }
3220
3221    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3222        ActivityInfo ai = null;
3223        ComponentName comp = intent.getComponent();
3224        try {
3225            if (comp != null) {
3226                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3227            } else {
3228                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3229                        intent,
3230                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3231                            flags, userId);
3232
3233                if (info != null) {
3234                    ai = info.activityInfo;
3235                }
3236            }
3237        } catch (RemoteException e) {
3238            // ignore
3239        }
3240
3241        return ai;
3242    }
3243
3244    /**
3245     * Starts the "new version setup screen" if appropriate.
3246     */
3247    void startSetupActivityLocked() {
3248        // Only do this once per boot.
3249        if (mCheckedForSetup) {
3250            return;
3251        }
3252
3253        // We will show this screen if the current one is a different
3254        // version than the last one shown, and we are not running in
3255        // low-level factory test mode.
3256        final ContentResolver resolver = mContext.getContentResolver();
3257        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3258                Settings.Global.getInt(resolver,
3259                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3260            mCheckedForSetup = true;
3261
3262            // See if we should be showing the platform update setup UI.
3263            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3264            List<ResolveInfo> ris = mContext.getPackageManager()
3265                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3266
3267            // We don't allow third party apps to replace this.
3268            ResolveInfo ri = null;
3269            for (int i=0; ris != null && i<ris.size(); i++) {
3270                if ((ris.get(i).activityInfo.applicationInfo.flags
3271                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3272                    ri = ris.get(i);
3273                    break;
3274                }
3275            }
3276
3277            if (ri != null) {
3278                String vers = ri.activityInfo.metaData != null
3279                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3280                        : null;
3281                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3282                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3283                            Intent.METADATA_SETUP_VERSION);
3284                }
3285                String lastVers = Settings.Secure.getString(
3286                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3287                if (vers != null && !vers.equals(lastVers)) {
3288                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3289                    intent.setComponent(new ComponentName(
3290                            ri.activityInfo.packageName, ri.activityInfo.name));
3291                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3292                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3293                }
3294            }
3295        }
3296    }
3297
3298    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3299        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3300    }
3301
3302    void enforceNotIsolatedCaller(String caller) {
3303        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3304            throw new SecurityException("Isolated process not allowed to call " + caller);
3305        }
3306    }
3307
3308    @Override
3309    public int getFrontActivityScreenCompatMode() {
3310        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3311        synchronized (this) {
3312            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3313        }
3314    }
3315
3316    @Override
3317    public void setFrontActivityScreenCompatMode(int mode) {
3318        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3319                "setFrontActivityScreenCompatMode");
3320        synchronized (this) {
3321            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3322        }
3323    }
3324
3325    @Override
3326    public int getPackageScreenCompatMode(String packageName) {
3327        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3328        synchronized (this) {
3329            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3330        }
3331    }
3332
3333    @Override
3334    public void setPackageScreenCompatMode(String packageName, int mode) {
3335        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3336                "setPackageScreenCompatMode");
3337        synchronized (this) {
3338            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3339        }
3340    }
3341
3342    @Override
3343    public boolean getPackageAskScreenCompat(String packageName) {
3344        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3345        synchronized (this) {
3346            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3347        }
3348    }
3349
3350    @Override
3351    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3352        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3353                "setPackageAskScreenCompat");
3354        synchronized (this) {
3355            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3356        }
3357    }
3358
3359    private void dispatchProcessesChanged() {
3360        int N;
3361        synchronized (this) {
3362            N = mPendingProcessChanges.size();
3363            if (mActiveProcessChanges.length < N) {
3364                mActiveProcessChanges = new ProcessChangeItem[N];
3365            }
3366            mPendingProcessChanges.toArray(mActiveProcessChanges);
3367            mAvailProcessChanges.addAll(mPendingProcessChanges);
3368            mPendingProcessChanges.clear();
3369            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3370        }
3371
3372        int i = mProcessObservers.beginBroadcast();
3373        while (i > 0) {
3374            i--;
3375            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3376            if (observer != null) {
3377                try {
3378                    for (int j=0; j<N; j++) {
3379                        ProcessChangeItem item = mActiveProcessChanges[j];
3380                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3381                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3382                                    + item.pid + " uid=" + item.uid + ": "
3383                                    + item.foregroundActivities);
3384                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3385                                    item.foregroundActivities);
3386                        }
3387                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3388                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3389                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3390                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3391                        }
3392                    }
3393                } catch (RemoteException e) {
3394                }
3395            }
3396        }
3397        mProcessObservers.finishBroadcast();
3398    }
3399
3400    private void dispatchProcessDied(int pid, int uid) {
3401        int i = mProcessObservers.beginBroadcast();
3402        while (i > 0) {
3403            i--;
3404            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3405            if (observer != null) {
3406                try {
3407                    observer.onProcessDied(pid, uid);
3408                } catch (RemoteException e) {
3409                }
3410            }
3411        }
3412        mProcessObservers.finishBroadcast();
3413    }
3414
3415    @Override
3416    public final int startActivity(IApplicationThread caller, String callingPackage,
3417            Intent intent, String resolvedType, IBinder resultTo,
3418            String resultWho, int requestCode, int startFlags,
3419            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3420        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3421                resultWho, requestCode,
3422                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3423    }
3424
3425    @Override
3426    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3427            Intent intent, String resolvedType, IBinder resultTo,
3428            String resultWho, int requestCode, int startFlags,
3429            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3430        enforceNotIsolatedCaller("startActivity");
3431        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3432                false, ALLOW_FULL_ONLY, "startActivity", null);
3433        // TODO: Switch to user app stacks here.
3434        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3435                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3436                null, null, options, userId, null);
3437    }
3438
3439    @Override
3440    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3441            Intent intent, String resolvedType, IBinder resultTo,
3442            String resultWho, int requestCode, int startFlags,
3443            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3444
3445        // This is very dangerous -- it allows you to perform a start activity (including
3446        // permission grants) as any app that may launch one of your own activities.  So
3447        // we will only allow this to be done from activities that are part of the core framework,
3448        // and then only when they are running as the system.
3449        final ActivityRecord sourceRecord;
3450        final int targetUid;
3451        final String targetPackage;
3452        synchronized (this) {
3453            if (resultTo == null) {
3454                throw new SecurityException("Must be called from an activity");
3455            }
3456            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3457            if (sourceRecord == null) {
3458                throw new SecurityException("Called with bad activity token: " + resultTo);
3459            }
3460            if (!sourceRecord.info.packageName.equals("android")) {
3461                throw new SecurityException(
3462                        "Must be called from an activity that is declared in the android package");
3463            }
3464            if (sourceRecord.app == null) {
3465                throw new SecurityException("Called without a process attached to activity");
3466            }
3467            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3468                // This is still okay, as long as this activity is running under the
3469                // uid of the original calling activity.
3470                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3471                    throw new SecurityException(
3472                            "Calling activity in uid " + sourceRecord.app.uid
3473                                    + " must be system uid or original calling uid "
3474                                    + sourceRecord.launchedFromUid);
3475                }
3476            }
3477            targetUid = sourceRecord.launchedFromUid;
3478            targetPackage = sourceRecord.launchedFromPackage;
3479        }
3480
3481        // TODO: Switch to user app stacks here.
3482        try {
3483            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3484                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3485                    null, null, null, null, options, UserHandle.getUserId(targetUid), null);
3486            return ret;
3487        } catch (SecurityException e) {
3488            // XXX need to figure out how to propagate to original app.
3489            // A SecurityException here is generally actually a fault of the original
3490            // calling activity (such as a fairly granting permissions), so propagate it
3491            // back to them.
3492            /*
3493            StringBuilder msg = new StringBuilder();
3494            msg.append("While launching");
3495            msg.append(intent.toString());
3496            msg.append(": ");
3497            msg.append(e.getMessage());
3498            */
3499            throw e;
3500        }
3501    }
3502
3503    @Override
3504    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3505            Intent intent, String resolvedType, IBinder resultTo,
3506            String resultWho, int requestCode, int startFlags, String profileFile,
3507            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3508        enforceNotIsolatedCaller("startActivityAndWait");
3509        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3510                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3511        WaitResult res = new WaitResult();
3512        // TODO: Switch to user app stacks here.
3513        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3514                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3515                res, null, options, userId, null);
3516        return res;
3517    }
3518
3519    @Override
3520    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3521            Intent intent, String resolvedType, IBinder resultTo,
3522            String resultWho, int requestCode, int startFlags, Configuration config,
3523            Bundle options, int userId) {
3524        enforceNotIsolatedCaller("startActivityWithConfig");
3525        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3526                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3527        // TODO: Switch to user app stacks here.
3528        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3529                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3530                null, null, null, config, options, userId, null);
3531        return ret;
3532    }
3533
3534    @Override
3535    public int startActivityIntentSender(IApplicationThread caller,
3536            IntentSender intent, Intent fillInIntent, String resolvedType,
3537            IBinder resultTo, String resultWho, int requestCode,
3538            int flagsMask, int flagsValues, Bundle options) {
3539        enforceNotIsolatedCaller("startActivityIntentSender");
3540        // Refuse possible leaked file descriptors
3541        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3542            throw new IllegalArgumentException("File descriptors passed in Intent");
3543        }
3544
3545        IIntentSender sender = intent.getTarget();
3546        if (!(sender instanceof PendingIntentRecord)) {
3547            throw new IllegalArgumentException("Bad PendingIntent object");
3548        }
3549
3550        PendingIntentRecord pir = (PendingIntentRecord)sender;
3551
3552        synchronized (this) {
3553            // If this is coming from the currently resumed activity, it is
3554            // effectively saying that app switches are allowed at this point.
3555            final ActivityStack stack = getFocusedStack();
3556            if (stack.mResumedActivity != null &&
3557                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3558                mAppSwitchesAllowedTime = 0;
3559            }
3560        }
3561        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3562                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3563        return ret;
3564    }
3565
3566    @Override
3567    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3568            Intent intent, String resolvedType, IVoiceInteractionSession session,
3569            IVoiceInteractor interactor, int startFlags, String profileFile,
3570            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3571        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3572                != PackageManager.PERMISSION_GRANTED) {
3573            String msg = "Permission Denial: startVoiceActivity() from pid="
3574                    + Binder.getCallingPid()
3575                    + ", uid=" + Binder.getCallingUid()
3576                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3577            Slog.w(TAG, msg);
3578            throw new SecurityException(msg);
3579        }
3580        if (session == null || interactor == null) {
3581            throw new NullPointerException("null session or interactor");
3582        }
3583        userId = handleIncomingUser(callingPid, callingUid, userId,
3584                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3585        // TODO: Switch to user app stacks here.
3586        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3587                resolvedType, session, interactor, null, null, 0, startFlags,
3588                profileFile, profileFd, null, null, options, userId, null);
3589    }
3590
3591    @Override
3592    public boolean startNextMatchingActivity(IBinder callingActivity,
3593            Intent intent, Bundle options) {
3594        // Refuse possible leaked file descriptors
3595        if (intent != null && intent.hasFileDescriptors() == true) {
3596            throw new IllegalArgumentException("File descriptors passed in Intent");
3597        }
3598
3599        synchronized (this) {
3600            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3601            if (r == null) {
3602                ActivityOptions.abort(options);
3603                return false;
3604            }
3605            if (r.app == null || r.app.thread == null) {
3606                // The caller is not running...  d'oh!
3607                ActivityOptions.abort(options);
3608                return false;
3609            }
3610            intent = new Intent(intent);
3611            // The caller is not allowed to change the data.
3612            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3613            // And we are resetting to find the next component...
3614            intent.setComponent(null);
3615
3616            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3617
3618            ActivityInfo aInfo = null;
3619            try {
3620                List<ResolveInfo> resolves =
3621                    AppGlobals.getPackageManager().queryIntentActivities(
3622                            intent, r.resolvedType,
3623                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3624                            UserHandle.getCallingUserId());
3625
3626                // Look for the original activity in the list...
3627                final int N = resolves != null ? resolves.size() : 0;
3628                for (int i=0; i<N; i++) {
3629                    ResolveInfo rInfo = resolves.get(i);
3630                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3631                            && rInfo.activityInfo.name.equals(r.info.name)) {
3632                        // We found the current one...  the next matching is
3633                        // after it.
3634                        i++;
3635                        if (i<N) {
3636                            aInfo = resolves.get(i).activityInfo;
3637                        }
3638                        if (debug) {
3639                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3640                                    + "/" + r.info.name);
3641                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3642                                    + "/" + aInfo.name);
3643                        }
3644                        break;
3645                    }
3646                }
3647            } catch (RemoteException e) {
3648            }
3649
3650            if (aInfo == null) {
3651                // Nobody who is next!
3652                ActivityOptions.abort(options);
3653                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3654                return false;
3655            }
3656
3657            intent.setComponent(new ComponentName(
3658                    aInfo.applicationInfo.packageName, aInfo.name));
3659            intent.setFlags(intent.getFlags()&~(
3660                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3661                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3662                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3663                    Intent.FLAG_ACTIVITY_NEW_TASK));
3664
3665            // Okay now we need to start the new activity, replacing the
3666            // currently running activity.  This is a little tricky because
3667            // we want to start the new one as if the current one is finished,
3668            // but not finish the current one first so that there is no flicker.
3669            // And thus...
3670            final boolean wasFinishing = r.finishing;
3671            r.finishing = true;
3672
3673            // Propagate reply information over to the new activity.
3674            final ActivityRecord resultTo = r.resultTo;
3675            final String resultWho = r.resultWho;
3676            final int requestCode = r.requestCode;
3677            r.resultTo = null;
3678            if (resultTo != null) {
3679                resultTo.removeResultsLocked(r, resultWho, requestCode);
3680            }
3681
3682            final long origId = Binder.clearCallingIdentity();
3683            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3684                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3685                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3686                    options, false, null, null);
3687            Binder.restoreCallingIdentity(origId);
3688
3689            r.finishing = wasFinishing;
3690            if (res != ActivityManager.START_SUCCESS) {
3691                return false;
3692            }
3693            return true;
3694        }
3695    }
3696
3697    @Override
3698    public final int startActivityFromRecents(int taskId, Bundle options) {
3699        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3700            String msg = "Permission Denial: startActivityFromRecents called without " +
3701                    START_TASKS_FROM_RECENTS;
3702            Slog.w(TAG, msg);
3703            throw new SecurityException(msg);
3704        }
3705        final int callingUid;
3706        final String callingPackage;
3707        final Intent intent;
3708        final int userId;
3709        synchronized (this) {
3710            final TaskRecord task = recentTaskForIdLocked(taskId);
3711            if (task == null) {
3712                throw new ActivityNotFoundException("Task " + taskId + " not found.");
3713            }
3714            callingUid = task.mCallingUid;
3715            callingPackage = task.mCallingPackage;
3716            intent = task.intent;
3717            userId = task.userId;
3718        }
3719        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3720                options, userId, null);
3721    }
3722
3723    final int startActivityInPackage(int uid, String callingPackage,
3724            Intent intent, String resolvedType, IBinder resultTo,
3725            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3726                    IActivityContainer container) {
3727
3728        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3729                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3730
3731        // TODO: Switch to user app stacks here.
3732        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3733                null, null, resultTo, resultWho, requestCode, startFlags,
3734                null, null, null, null, options, userId, container);
3735        return ret;
3736    }
3737
3738    @Override
3739    public final int startActivities(IApplicationThread caller, String callingPackage,
3740            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3741            int userId) {
3742        enforceNotIsolatedCaller("startActivities");
3743        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3744                false, ALLOW_FULL_ONLY, "startActivity", null);
3745        // TODO: Switch to user app stacks here.
3746        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3747                resolvedTypes, resultTo, options, userId);
3748        return ret;
3749    }
3750
3751    final int startActivitiesInPackage(int uid, String callingPackage,
3752            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3753            Bundle options, int userId) {
3754
3755        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3756                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3757        // TODO: Switch to user app stacks here.
3758        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3759                resultTo, options, userId);
3760        return ret;
3761    }
3762
3763    //explicitly remove thd old information in mRecentTasks when removing existing user.
3764    private void removeRecentTasksForUserLocked(int userId) {
3765        if(userId <= 0) {
3766            Slog.i(TAG, "Can't remove recent task on user " + userId);
3767            return;
3768        }
3769
3770        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3771            TaskRecord tr = mRecentTasks.get(i);
3772            if (tr.userId == userId) {
3773                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3774                        + " when finishing user" + userId);
3775                tr.disposeThumbnail();
3776                mRecentTasks.remove(i);
3777            }
3778        }
3779
3780        // Remove tasks from persistent storage.
3781        mTaskPersister.wakeup(null, true);
3782    }
3783
3784    final void addRecentTaskLocked(TaskRecord task) {
3785        int N = mRecentTasks.size();
3786        // Quick case: check if the top-most recent task is the same.
3787        if (N > 0 && mRecentTasks.get(0) == task) {
3788            return;
3789        }
3790        // Another quick case: never add voice sessions.
3791        if (task.voiceSession != null) {
3792            return;
3793        }
3794        // Remove any existing entries that are the same kind of task.
3795        final Intent intent = task.intent;
3796        final boolean document = intent != null && intent.isDocument();
3797        final ComponentName comp = intent.getComponent();
3798
3799        int maxRecents = task.maxRecents - 1;
3800        for (int i=0; i<N; i++) {
3801            final TaskRecord tr = mRecentTasks.get(i);
3802            if (task != tr) {
3803                if (task.userId != tr.userId) {
3804                    continue;
3805                }
3806                if (i > MAX_RECENT_BITMAPS) {
3807                    tr.freeLastThumbnail();
3808                }
3809                final Intent trIntent = tr.intent;
3810                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3811                    (intent == null || !intent.filterEquals(trIntent))) {
3812                    continue;
3813                }
3814                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3815                if (document && trIsDocument) {
3816                    // These are the same document activity (not necessarily the same doc).
3817                    if (maxRecents > 0) {
3818                        --maxRecents;
3819                        continue;
3820                    }
3821                    // Hit the maximum number of documents for this task. Fall through
3822                    // and remove this document from recents.
3823                } else if (document || trIsDocument) {
3824                    // Only one of these is a document. Not the droid we're looking for.
3825                    continue;
3826                }
3827            }
3828
3829            // Either task and tr are the same or, their affinities match or their intents match
3830            // and neither of them is a document, or they are documents using the same activity
3831            // and their maxRecents has been reached.
3832            tr.disposeThumbnail();
3833            mRecentTasks.remove(i);
3834            if (task != tr) {
3835                tr.closeRecentsChain();
3836            }
3837            i--;
3838            N--;
3839            if (task.intent == null) {
3840                // If the new recent task we are adding is not fully
3841                // specified, then replace it with the existing recent task.
3842                task = tr;
3843            }
3844            notifyTaskPersisterLocked(tr, false);
3845        }
3846        if (N >= MAX_RECENT_TASKS) {
3847            final TaskRecord tr = mRecentTasks.remove(N - 1);
3848            tr.disposeThumbnail();
3849            tr.closeRecentsChain();
3850        }
3851        mRecentTasks.add(0, task);
3852    }
3853
3854    @Override
3855    public void reportActivityFullyDrawn(IBinder token) {
3856        synchronized (this) {
3857            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3858            if (r == null) {
3859                return;
3860            }
3861            r.reportFullyDrawnLocked();
3862        }
3863    }
3864
3865    @Override
3866    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3867        synchronized (this) {
3868            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3869            if (r == null) {
3870                return;
3871            }
3872            final long origId = Binder.clearCallingIdentity();
3873            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3874            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3875                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3876            if (config != null) {
3877                r.frozenBeforeDestroy = true;
3878                if (!updateConfigurationLocked(config, r, false, false)) {
3879                    mStackSupervisor.resumeTopActivitiesLocked();
3880                }
3881            }
3882            Binder.restoreCallingIdentity(origId);
3883        }
3884    }
3885
3886    @Override
3887    public int getRequestedOrientation(IBinder token) {
3888        synchronized (this) {
3889            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3890            if (r == null) {
3891                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3892            }
3893            return mWindowManager.getAppOrientation(r.appToken);
3894        }
3895    }
3896
3897    /**
3898     * This is the internal entry point for handling Activity.finish().
3899     *
3900     * @param token The Binder token referencing the Activity we want to finish.
3901     * @param resultCode Result code, if any, from this Activity.
3902     * @param resultData Result data (Intent), if any, from this Activity.
3903     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3904     *            the root Activity in the task.
3905     *
3906     * @return Returns true if the activity successfully finished, or false if it is still running.
3907     */
3908    @Override
3909    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3910            boolean finishTask) {
3911        // Refuse possible leaked file descriptors
3912        if (resultData != null && resultData.hasFileDescriptors() == true) {
3913            throw new IllegalArgumentException("File descriptors passed in Intent");
3914        }
3915
3916        synchronized(this) {
3917            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3918            if (r == null) {
3919                return true;
3920            }
3921            // Keep track of the root activity of the task before we finish it
3922            TaskRecord tr = r.task;
3923            ActivityRecord rootR = tr.getRootActivity();
3924            // Do not allow task to finish in Lock Task mode.
3925            if (tr == mStackSupervisor.mLockTaskModeTask) {
3926                if (rootR == r) {
3927                    mStackSupervisor.showLockTaskToast();
3928                    return false;
3929                }
3930            }
3931            if (mController != null) {
3932                // Find the first activity that is not finishing.
3933                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3934                if (next != null) {
3935                    // ask watcher if this is allowed
3936                    boolean resumeOK = true;
3937                    try {
3938                        resumeOK = mController.activityResuming(next.packageName);
3939                    } catch (RemoteException e) {
3940                        mController = null;
3941                        Watchdog.getInstance().setActivityController(null);
3942                    }
3943
3944                    if (!resumeOK) {
3945                        return false;
3946                    }
3947                }
3948            }
3949            final long origId = Binder.clearCallingIdentity();
3950            try {
3951                boolean res;
3952                if (finishTask && r == rootR) {
3953                    // If requested, remove the task that is associated to this activity only if it
3954                    // was the root activity in the task.  The result code and data is ignored because
3955                    // we don't support returning them across task boundaries.
3956                    res = removeTaskByIdLocked(tr.taskId, 0);
3957                } else {
3958                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3959                            resultData, "app-request", true);
3960                }
3961                return res;
3962            } finally {
3963                Binder.restoreCallingIdentity(origId);
3964            }
3965        }
3966    }
3967
3968    @Override
3969    public final void finishHeavyWeightApp() {
3970        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3971                != PackageManager.PERMISSION_GRANTED) {
3972            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3973                    + Binder.getCallingPid()
3974                    + ", uid=" + Binder.getCallingUid()
3975                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3976            Slog.w(TAG, msg);
3977            throw new SecurityException(msg);
3978        }
3979
3980        synchronized(this) {
3981            if (mHeavyWeightProcess == null) {
3982                return;
3983            }
3984
3985            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3986                    mHeavyWeightProcess.activities);
3987            for (int i=0; i<activities.size(); i++) {
3988                ActivityRecord r = activities.get(i);
3989                if (!r.finishing) {
3990                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3991                            null, "finish-heavy", true);
3992                }
3993            }
3994
3995            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3996                    mHeavyWeightProcess.userId, 0));
3997            mHeavyWeightProcess = null;
3998        }
3999    }
4000
4001    @Override
4002    public void crashApplication(int uid, int initialPid, String packageName,
4003            String message) {
4004        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4005                != PackageManager.PERMISSION_GRANTED) {
4006            String msg = "Permission Denial: crashApplication() from pid="
4007                    + Binder.getCallingPid()
4008                    + ", uid=" + Binder.getCallingUid()
4009                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4010            Slog.w(TAG, msg);
4011            throw new SecurityException(msg);
4012        }
4013
4014        synchronized(this) {
4015            ProcessRecord proc = null;
4016
4017            // Figure out which process to kill.  We don't trust that initialPid
4018            // still has any relation to current pids, so must scan through the
4019            // list.
4020            synchronized (mPidsSelfLocked) {
4021                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4022                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4023                    if (p.uid != uid) {
4024                        continue;
4025                    }
4026                    if (p.pid == initialPid) {
4027                        proc = p;
4028                        break;
4029                    }
4030                    if (p.pkgList.containsKey(packageName)) {
4031                        proc = p;
4032                    }
4033                }
4034            }
4035
4036            if (proc == null) {
4037                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4038                        + " initialPid=" + initialPid
4039                        + " packageName=" + packageName);
4040                return;
4041            }
4042
4043            if (proc.thread != null) {
4044                if (proc.pid == Process.myPid()) {
4045                    Log.w(TAG, "crashApplication: trying to crash self!");
4046                    return;
4047                }
4048                long ident = Binder.clearCallingIdentity();
4049                try {
4050                    proc.thread.scheduleCrash(message);
4051                } catch (RemoteException e) {
4052                }
4053                Binder.restoreCallingIdentity(ident);
4054            }
4055        }
4056    }
4057
4058    @Override
4059    public final void finishSubActivity(IBinder token, String resultWho,
4060            int requestCode) {
4061        synchronized(this) {
4062            final long origId = Binder.clearCallingIdentity();
4063            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4064            if (r != null) {
4065                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4066            }
4067            Binder.restoreCallingIdentity(origId);
4068        }
4069    }
4070
4071    @Override
4072    public boolean finishActivityAffinity(IBinder token) {
4073        synchronized(this) {
4074            final long origId = Binder.clearCallingIdentity();
4075            try {
4076                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4077
4078                ActivityRecord rootR = r.task.getRootActivity();
4079                // Do not allow task to finish in Lock Task mode.
4080                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4081                    if (rootR == r) {
4082                        mStackSupervisor.showLockTaskToast();
4083                        return false;
4084                    }
4085                }
4086                boolean res = false;
4087                if (r != null) {
4088                    res = r.task.stack.finishActivityAffinityLocked(r);
4089                }
4090                return res;
4091            } finally {
4092                Binder.restoreCallingIdentity(origId);
4093            }
4094        }
4095    }
4096
4097    @Override
4098    public void finishVoiceTask(IVoiceInteractionSession session) {
4099        synchronized(this) {
4100            final long origId = Binder.clearCallingIdentity();
4101            try {
4102                mStackSupervisor.finishVoiceTask(session);
4103            } finally {
4104                Binder.restoreCallingIdentity(origId);
4105            }
4106        }
4107
4108    }
4109
4110    @Override
4111    public boolean willActivityBeVisible(IBinder token) {
4112        synchronized(this) {
4113            ActivityStack stack = ActivityRecord.getStackLocked(token);
4114            if (stack != null) {
4115                return stack.willActivityBeVisibleLocked(token);
4116            }
4117            return false;
4118        }
4119    }
4120
4121    @Override
4122    public void overridePendingTransition(IBinder token, String packageName,
4123            int enterAnim, int exitAnim) {
4124        synchronized(this) {
4125            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4126            if (self == null) {
4127                return;
4128            }
4129
4130            final long origId = Binder.clearCallingIdentity();
4131
4132            if (self.state == ActivityState.RESUMED
4133                    || self.state == ActivityState.PAUSING) {
4134                mWindowManager.overridePendingAppTransition(packageName,
4135                        enterAnim, exitAnim, null);
4136            }
4137
4138            Binder.restoreCallingIdentity(origId);
4139        }
4140    }
4141
4142    /**
4143     * Main function for removing an existing process from the activity manager
4144     * as a result of that process going away.  Clears out all connections
4145     * to the process.
4146     */
4147    private final void handleAppDiedLocked(ProcessRecord app,
4148            boolean restarting, boolean allowRestart) {
4149        int pid = app.pid;
4150        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4151        if (!restarting) {
4152            removeLruProcessLocked(app);
4153            if (pid > 0) {
4154                ProcessList.remove(pid);
4155            }
4156        }
4157
4158        if (mProfileProc == app) {
4159            clearProfilerLocked();
4160        }
4161
4162        // Remove this application's activities from active lists.
4163        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4164
4165        app.activities.clear();
4166
4167        if (app.instrumentationClass != null) {
4168            Slog.w(TAG, "Crash of app " + app.processName
4169                  + " running instrumentation " + app.instrumentationClass);
4170            Bundle info = new Bundle();
4171            info.putString("shortMsg", "Process crashed.");
4172            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4173        }
4174
4175        if (!restarting) {
4176            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4177                // If there was nothing to resume, and we are not already
4178                // restarting this process, but there is a visible activity that
4179                // is hosted by the process...  then make sure all visible
4180                // activities are running, taking care of restarting this
4181                // process.
4182                if (hasVisibleActivities) {
4183                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4184                }
4185            }
4186        }
4187    }
4188
4189    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4190        IBinder threadBinder = thread.asBinder();
4191        // Find the application record.
4192        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4193            ProcessRecord rec = mLruProcesses.get(i);
4194            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4195                return i;
4196            }
4197        }
4198        return -1;
4199    }
4200
4201    final ProcessRecord getRecordForAppLocked(
4202            IApplicationThread thread) {
4203        if (thread == null) {
4204            return null;
4205        }
4206
4207        int appIndex = getLRURecordIndexForAppLocked(thread);
4208        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4209    }
4210
4211    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4212        // If there are no longer any background processes running,
4213        // and the app that died was not running instrumentation,
4214        // then tell everyone we are now low on memory.
4215        boolean haveBg = false;
4216        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4217            ProcessRecord rec = mLruProcesses.get(i);
4218            if (rec.thread != null
4219                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4220                haveBg = true;
4221                break;
4222            }
4223        }
4224
4225        if (!haveBg) {
4226            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4227            if (doReport) {
4228                long now = SystemClock.uptimeMillis();
4229                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4230                    doReport = false;
4231                } else {
4232                    mLastMemUsageReportTime = now;
4233                }
4234            }
4235            final ArrayList<ProcessMemInfo> memInfos
4236                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4237            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4238            long now = SystemClock.uptimeMillis();
4239            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4240                ProcessRecord rec = mLruProcesses.get(i);
4241                if (rec == dyingProc || rec.thread == null) {
4242                    continue;
4243                }
4244                if (doReport) {
4245                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4246                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4247                }
4248                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4249                    // The low memory report is overriding any current
4250                    // state for a GC request.  Make sure to do
4251                    // heavy/important/visible/foreground processes first.
4252                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4253                        rec.lastRequestedGc = 0;
4254                    } else {
4255                        rec.lastRequestedGc = rec.lastLowMemory;
4256                    }
4257                    rec.reportLowMemory = true;
4258                    rec.lastLowMemory = now;
4259                    mProcessesToGc.remove(rec);
4260                    addProcessToGcListLocked(rec);
4261                }
4262            }
4263            if (doReport) {
4264                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4265                mHandler.sendMessage(msg);
4266            }
4267            scheduleAppGcsLocked();
4268        }
4269    }
4270
4271    final void appDiedLocked(ProcessRecord app) {
4272       appDiedLocked(app, app.pid, app.thread);
4273    }
4274
4275    final void appDiedLocked(ProcessRecord app, int pid,
4276            IApplicationThread thread) {
4277
4278        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4279        synchronized (stats) {
4280            stats.noteProcessDiedLocked(app.info.uid, pid);
4281        }
4282
4283        Process.killProcessGroup(app.info.uid, pid);
4284
4285        // Clean up already done if the process has been re-started.
4286        if (app.pid == pid && app.thread != null &&
4287                app.thread.asBinder() == thread.asBinder()) {
4288            boolean doLowMem = app.instrumentationClass == null;
4289            boolean doOomAdj = doLowMem;
4290            if (!app.killedByAm) {
4291                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4292                        + ") has died.");
4293                mAllowLowerMemLevel = true;
4294            } else {
4295                // Note that we always want to do oom adj to update our state with the
4296                // new number of procs.
4297                mAllowLowerMemLevel = false;
4298                doLowMem = false;
4299            }
4300            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4301            if (DEBUG_CLEANUP) Slog.v(
4302                TAG, "Dying app: " + app + ", pid: " + pid
4303                + ", thread: " + thread.asBinder());
4304            handleAppDiedLocked(app, false, true);
4305
4306            if (doOomAdj) {
4307                updateOomAdjLocked();
4308            }
4309            if (doLowMem) {
4310                doLowMemReportIfNeededLocked(app);
4311            }
4312        } else if (app.pid != pid) {
4313            // A new process has already been started.
4314            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4315                    + ") has died and restarted (pid " + app.pid + ").");
4316            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4317        } else if (DEBUG_PROCESSES) {
4318            Slog.d(TAG, "Received spurious death notification for thread "
4319                    + thread.asBinder());
4320        }
4321    }
4322
4323    /**
4324     * If a stack trace dump file is configured, dump process stack traces.
4325     * @param clearTraces causes the dump file to be erased prior to the new
4326     *    traces being written, if true; when false, the new traces will be
4327     *    appended to any existing file content.
4328     * @param firstPids of dalvik VM processes to dump stack traces for first
4329     * @param lastPids of dalvik VM processes to dump stack traces for last
4330     * @param nativeProcs optional list of native process names to dump stack crawls
4331     * @return file containing stack traces, or null if no dump file is configured
4332     */
4333    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4334            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4335        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4336        if (tracesPath == null || tracesPath.length() == 0) {
4337            return null;
4338        }
4339
4340        File tracesFile = new File(tracesPath);
4341        try {
4342            File tracesDir = tracesFile.getParentFile();
4343            if (!tracesDir.exists()) {
4344                tracesFile.mkdirs();
4345                if (!SELinux.restorecon(tracesDir)) {
4346                    return null;
4347                }
4348            }
4349            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4350
4351            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4352            tracesFile.createNewFile();
4353            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4354        } catch (IOException e) {
4355            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4356            return null;
4357        }
4358
4359        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4360        return tracesFile;
4361    }
4362
4363    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4364            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4365        // Use a FileObserver to detect when traces finish writing.
4366        // The order of traces is considered important to maintain for legibility.
4367        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4368            @Override
4369            public synchronized void onEvent(int event, String path) { notify(); }
4370        };
4371
4372        try {
4373            observer.startWatching();
4374
4375            // First collect all of the stacks of the most important pids.
4376            if (firstPids != null) {
4377                try {
4378                    int num = firstPids.size();
4379                    for (int i = 0; i < num; i++) {
4380                        synchronized (observer) {
4381                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4382                            observer.wait(200);  // Wait for write-close, give up after 200msec
4383                        }
4384                    }
4385                } catch (InterruptedException e) {
4386                    Log.wtf(TAG, e);
4387                }
4388            }
4389
4390            // Next collect the stacks of the native pids
4391            if (nativeProcs != null) {
4392                int[] pids = Process.getPidsForCommands(nativeProcs);
4393                if (pids != null) {
4394                    for (int pid : pids) {
4395                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4396                    }
4397                }
4398            }
4399
4400            // Lastly, measure CPU usage.
4401            if (processCpuTracker != null) {
4402                processCpuTracker.init();
4403                System.gc();
4404                processCpuTracker.update();
4405                try {
4406                    synchronized (processCpuTracker) {
4407                        processCpuTracker.wait(500); // measure over 1/2 second.
4408                    }
4409                } catch (InterruptedException e) {
4410                }
4411                processCpuTracker.update();
4412
4413                // We'll take the stack crawls of just the top apps using CPU.
4414                final int N = processCpuTracker.countWorkingStats();
4415                int numProcs = 0;
4416                for (int i=0; i<N && numProcs<5; i++) {
4417                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4418                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4419                        numProcs++;
4420                        try {
4421                            synchronized (observer) {
4422                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4423                                observer.wait(200);  // Wait for write-close, give up after 200msec
4424                            }
4425                        } catch (InterruptedException e) {
4426                            Log.wtf(TAG, e);
4427                        }
4428
4429                    }
4430                }
4431            }
4432        } finally {
4433            observer.stopWatching();
4434        }
4435    }
4436
4437    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4438        if (true || IS_USER_BUILD) {
4439            return;
4440        }
4441        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4442        if (tracesPath == null || tracesPath.length() == 0) {
4443            return;
4444        }
4445
4446        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4447        StrictMode.allowThreadDiskWrites();
4448        try {
4449            final File tracesFile = new File(tracesPath);
4450            final File tracesDir = tracesFile.getParentFile();
4451            final File tracesTmp = new File(tracesDir, "__tmp__");
4452            try {
4453                if (!tracesDir.exists()) {
4454                    tracesFile.mkdirs();
4455                    if (!SELinux.restorecon(tracesDir.getPath())) {
4456                        return;
4457                    }
4458                }
4459                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4460
4461                if (tracesFile.exists()) {
4462                    tracesTmp.delete();
4463                    tracesFile.renameTo(tracesTmp);
4464                }
4465                StringBuilder sb = new StringBuilder();
4466                Time tobj = new Time();
4467                tobj.set(System.currentTimeMillis());
4468                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4469                sb.append(": ");
4470                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4471                sb.append(" since ");
4472                sb.append(msg);
4473                FileOutputStream fos = new FileOutputStream(tracesFile);
4474                fos.write(sb.toString().getBytes());
4475                if (app == null) {
4476                    fos.write("\n*** No application process!".getBytes());
4477                }
4478                fos.close();
4479                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4480            } catch (IOException e) {
4481                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4482                return;
4483            }
4484
4485            if (app != null) {
4486                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4487                firstPids.add(app.pid);
4488                dumpStackTraces(tracesPath, firstPids, null, null, null);
4489            }
4490
4491            File lastTracesFile = null;
4492            File curTracesFile = null;
4493            for (int i=9; i>=0; i--) {
4494                String name = String.format(Locale.US, "slow%02d.txt", i);
4495                curTracesFile = new File(tracesDir, name);
4496                if (curTracesFile.exists()) {
4497                    if (lastTracesFile != null) {
4498                        curTracesFile.renameTo(lastTracesFile);
4499                    } else {
4500                        curTracesFile.delete();
4501                    }
4502                }
4503                lastTracesFile = curTracesFile;
4504            }
4505            tracesFile.renameTo(curTracesFile);
4506            if (tracesTmp.exists()) {
4507                tracesTmp.renameTo(tracesFile);
4508            }
4509        } finally {
4510            StrictMode.setThreadPolicy(oldPolicy);
4511        }
4512    }
4513
4514    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4515            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4516        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4517        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4518
4519        if (mController != null) {
4520            try {
4521                // 0 == continue, -1 = kill process immediately
4522                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4523                if (res < 0 && app.pid != MY_PID) {
4524                    Process.killProcess(app.pid);
4525                    Process.killProcessGroup(app.info.uid, app.pid);
4526                }
4527            } catch (RemoteException e) {
4528                mController = null;
4529                Watchdog.getInstance().setActivityController(null);
4530            }
4531        }
4532
4533        long anrTime = SystemClock.uptimeMillis();
4534        if (MONITOR_CPU_USAGE) {
4535            updateCpuStatsNow();
4536        }
4537
4538        synchronized (this) {
4539            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4540            if (mShuttingDown) {
4541                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4542                return;
4543            } else if (app.notResponding) {
4544                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4545                return;
4546            } else if (app.crashing) {
4547                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4548                return;
4549            }
4550
4551            // In case we come through here for the same app before completing
4552            // this one, mark as anring now so we will bail out.
4553            app.notResponding = true;
4554
4555            // Log the ANR to the event log.
4556            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4557                    app.processName, app.info.flags, annotation);
4558
4559            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4560            firstPids.add(app.pid);
4561
4562            int parentPid = app.pid;
4563            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4564            if (parentPid != app.pid) firstPids.add(parentPid);
4565
4566            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4567
4568            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4569                ProcessRecord r = mLruProcesses.get(i);
4570                if (r != null && r.thread != null) {
4571                    int pid = r.pid;
4572                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4573                        if (r.persistent) {
4574                            firstPids.add(pid);
4575                        } else {
4576                            lastPids.put(pid, Boolean.TRUE);
4577                        }
4578                    }
4579                }
4580            }
4581        }
4582
4583        // Log the ANR to the main log.
4584        StringBuilder info = new StringBuilder();
4585        info.setLength(0);
4586        info.append("ANR in ").append(app.processName);
4587        if (activity != null && activity.shortComponentName != null) {
4588            info.append(" (").append(activity.shortComponentName).append(")");
4589        }
4590        info.append("\n");
4591        info.append("PID: ").append(app.pid).append("\n");
4592        if (annotation != null) {
4593            info.append("Reason: ").append(annotation).append("\n");
4594        }
4595        if (parent != null && parent != activity) {
4596            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4597        }
4598
4599        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4600
4601        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4602                NATIVE_STACKS_OF_INTEREST);
4603
4604        String cpuInfo = null;
4605        if (MONITOR_CPU_USAGE) {
4606            updateCpuStatsNow();
4607            synchronized (mProcessCpuThread) {
4608                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4609            }
4610            info.append(processCpuTracker.printCurrentLoad());
4611            info.append(cpuInfo);
4612        }
4613
4614        info.append(processCpuTracker.printCurrentState(anrTime));
4615
4616        Slog.e(TAG, info.toString());
4617        if (tracesFile == null) {
4618            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4619            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4620        }
4621
4622        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4623                cpuInfo, tracesFile, null);
4624
4625        if (mController != null) {
4626            try {
4627                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4628                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4629                if (res != 0) {
4630                    if (res < 0 && app.pid != MY_PID) {
4631                        Process.killProcess(app.pid);
4632                        Process.killProcessGroup(app.info.uid, app.pid);
4633                    } else {
4634                        synchronized (this) {
4635                            mServices.scheduleServiceTimeoutLocked(app);
4636                        }
4637                    }
4638                    return;
4639                }
4640            } catch (RemoteException e) {
4641                mController = null;
4642                Watchdog.getInstance().setActivityController(null);
4643            }
4644        }
4645
4646        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4647        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4648                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4649
4650        synchronized (this) {
4651            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4652                killUnneededProcessLocked(app, "background ANR");
4653                return;
4654            }
4655
4656            // Set the app's notResponding state, and look up the errorReportReceiver
4657            makeAppNotRespondingLocked(app,
4658                    activity != null ? activity.shortComponentName : null,
4659                    annotation != null ? "ANR " + annotation : "ANR",
4660                    info.toString());
4661
4662            // Bring up the infamous App Not Responding dialog
4663            Message msg = Message.obtain();
4664            HashMap<String, Object> map = new HashMap<String, Object>();
4665            msg.what = SHOW_NOT_RESPONDING_MSG;
4666            msg.obj = map;
4667            msg.arg1 = aboveSystem ? 1 : 0;
4668            map.put("app", app);
4669            if (activity != null) {
4670                map.put("activity", activity);
4671            }
4672
4673            mHandler.sendMessage(msg);
4674        }
4675    }
4676
4677    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4678        if (!mLaunchWarningShown) {
4679            mLaunchWarningShown = true;
4680            mHandler.post(new Runnable() {
4681                @Override
4682                public void run() {
4683                    synchronized (ActivityManagerService.this) {
4684                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4685                        d.show();
4686                        mHandler.postDelayed(new Runnable() {
4687                            @Override
4688                            public void run() {
4689                                synchronized (ActivityManagerService.this) {
4690                                    d.dismiss();
4691                                    mLaunchWarningShown = false;
4692                                }
4693                            }
4694                        }, 4000);
4695                    }
4696                }
4697            });
4698        }
4699    }
4700
4701    @Override
4702    public boolean clearApplicationUserData(final String packageName,
4703            final IPackageDataObserver observer, int userId) {
4704        enforceNotIsolatedCaller("clearApplicationUserData");
4705        int uid = Binder.getCallingUid();
4706        int pid = Binder.getCallingPid();
4707        userId = handleIncomingUser(pid, uid,
4708                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4709        long callingId = Binder.clearCallingIdentity();
4710        try {
4711            IPackageManager pm = AppGlobals.getPackageManager();
4712            int pkgUid = -1;
4713            synchronized(this) {
4714                try {
4715                    pkgUid = pm.getPackageUid(packageName, userId);
4716                } catch (RemoteException e) {
4717                }
4718                if (pkgUid == -1) {
4719                    Slog.w(TAG, "Invalid packageName: " + packageName);
4720                    if (observer != null) {
4721                        try {
4722                            observer.onRemoveCompleted(packageName, false);
4723                        } catch (RemoteException e) {
4724                            Slog.i(TAG, "Observer no longer exists.");
4725                        }
4726                    }
4727                    return false;
4728                }
4729                if (uid == pkgUid || checkComponentPermission(
4730                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4731                        pid, uid, -1, true)
4732                        == PackageManager.PERMISSION_GRANTED) {
4733                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4734                } else {
4735                    throw new SecurityException("PID " + pid + " does not have permission "
4736                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4737                                    + " of package " + packageName);
4738                }
4739
4740                // Remove all tasks match the cleared application package and user
4741                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
4742                    final TaskRecord tr = mRecentTasks.get(i);
4743                    final String taskPackageName =
4744                            tr.getBaseIntent().getComponent().getPackageName();
4745                    if (tr.userId != userId) continue;
4746                    if (!taskPackageName.equals(packageName)) continue;
4747                    removeTaskByIdLocked(tr.taskId, 0);
4748                }
4749            }
4750
4751            try {
4752                // Clear application user data
4753                pm.clearApplicationUserData(packageName, observer, userId);
4754
4755                synchronized(this) {
4756                    // Remove all permissions granted from/to this package
4757                    removeUriPermissionsForPackageLocked(packageName, userId, true);
4758                }
4759
4760                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4761                        Uri.fromParts("package", packageName, null));
4762                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4763                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4764                        null, null, 0, null, null, null, false, false, userId);
4765            } catch (RemoteException e) {
4766            }
4767        } finally {
4768            Binder.restoreCallingIdentity(callingId);
4769        }
4770        return true;
4771    }
4772
4773    @Override
4774    public void killBackgroundProcesses(final String packageName, int userId) {
4775        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4776                != PackageManager.PERMISSION_GRANTED &&
4777                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4778                        != PackageManager.PERMISSION_GRANTED) {
4779            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4780                    + Binder.getCallingPid()
4781                    + ", uid=" + Binder.getCallingUid()
4782                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4783            Slog.w(TAG, msg);
4784            throw new SecurityException(msg);
4785        }
4786
4787        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4788                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4789        long callingId = Binder.clearCallingIdentity();
4790        try {
4791            IPackageManager pm = AppGlobals.getPackageManager();
4792            synchronized(this) {
4793                int appId = -1;
4794                try {
4795                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4796                } catch (RemoteException e) {
4797                }
4798                if (appId == -1) {
4799                    Slog.w(TAG, "Invalid packageName: " + packageName);
4800                    return;
4801                }
4802                killPackageProcessesLocked(packageName, appId, userId,
4803                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4804            }
4805        } finally {
4806            Binder.restoreCallingIdentity(callingId);
4807        }
4808    }
4809
4810    @Override
4811    public void killAllBackgroundProcesses() {
4812        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4813                != PackageManager.PERMISSION_GRANTED) {
4814            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4815                    + Binder.getCallingPid()
4816                    + ", uid=" + Binder.getCallingUid()
4817                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4818            Slog.w(TAG, msg);
4819            throw new SecurityException(msg);
4820        }
4821
4822        long callingId = Binder.clearCallingIdentity();
4823        try {
4824            synchronized(this) {
4825                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4826                final int NP = mProcessNames.getMap().size();
4827                for (int ip=0; ip<NP; ip++) {
4828                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4829                    final int NA = apps.size();
4830                    for (int ia=0; ia<NA; ia++) {
4831                        ProcessRecord app = apps.valueAt(ia);
4832                        if (app.persistent) {
4833                            // we don't kill persistent processes
4834                            continue;
4835                        }
4836                        if (app.removed) {
4837                            procs.add(app);
4838                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4839                            app.removed = true;
4840                            procs.add(app);
4841                        }
4842                    }
4843                }
4844
4845                int N = procs.size();
4846                for (int i=0; i<N; i++) {
4847                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4848                }
4849                mAllowLowerMemLevel = true;
4850                updateOomAdjLocked();
4851                doLowMemReportIfNeededLocked(null);
4852            }
4853        } finally {
4854            Binder.restoreCallingIdentity(callingId);
4855        }
4856    }
4857
4858    @Override
4859    public void forceStopPackage(final String packageName, int userId) {
4860        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4861                != PackageManager.PERMISSION_GRANTED) {
4862            String msg = "Permission Denial: forceStopPackage() from pid="
4863                    + Binder.getCallingPid()
4864                    + ", uid=" + Binder.getCallingUid()
4865                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4866            Slog.w(TAG, msg);
4867            throw new SecurityException(msg);
4868        }
4869        final int callingPid = Binder.getCallingPid();
4870        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4871                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4872        long callingId = Binder.clearCallingIdentity();
4873        try {
4874            IPackageManager pm = AppGlobals.getPackageManager();
4875            synchronized(this) {
4876                int[] users = userId == UserHandle.USER_ALL
4877                        ? getUsersLocked() : new int[] { userId };
4878                for (int user : users) {
4879                    int pkgUid = -1;
4880                    try {
4881                        pkgUid = pm.getPackageUid(packageName, user);
4882                    } catch (RemoteException e) {
4883                    }
4884                    if (pkgUid == -1) {
4885                        Slog.w(TAG, "Invalid packageName: " + packageName);
4886                        continue;
4887                    }
4888                    try {
4889                        pm.setPackageStoppedState(packageName, true, user);
4890                    } catch (RemoteException e) {
4891                    } catch (IllegalArgumentException e) {
4892                        Slog.w(TAG, "Failed trying to unstop package "
4893                                + packageName + ": " + e);
4894                    }
4895                    if (isUserRunningLocked(user, false)) {
4896                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4897                    }
4898                }
4899            }
4900        } finally {
4901            Binder.restoreCallingIdentity(callingId);
4902        }
4903    }
4904
4905    @Override
4906    public void addPackageDependency(String packageName) {
4907        synchronized (this) {
4908            int callingPid = Binder.getCallingPid();
4909            if (callingPid == Process.myPid()) {
4910                //  Yeah, um, no.
4911                Slog.w(TAG, "Can't addPackageDependency on system process");
4912                return;
4913            }
4914            ProcessRecord proc;
4915            synchronized (mPidsSelfLocked) {
4916                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4917            }
4918            if (proc != null) {
4919                if (proc.pkgDeps == null) {
4920                    proc.pkgDeps = new ArraySet<String>(1);
4921                }
4922                proc.pkgDeps.add(packageName);
4923            }
4924        }
4925    }
4926
4927    /*
4928     * The pkg name and app id have to be specified.
4929     */
4930    @Override
4931    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4932        if (pkg == null) {
4933            return;
4934        }
4935        // Make sure the uid is valid.
4936        if (appid < 0) {
4937            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4938            return;
4939        }
4940        int callerUid = Binder.getCallingUid();
4941        // Only the system server can kill an application
4942        if (callerUid == Process.SYSTEM_UID) {
4943            // Post an aysnc message to kill the application
4944            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4945            msg.arg1 = appid;
4946            msg.arg2 = 0;
4947            Bundle bundle = new Bundle();
4948            bundle.putString("pkg", pkg);
4949            bundle.putString("reason", reason);
4950            msg.obj = bundle;
4951            mHandler.sendMessage(msg);
4952        } else {
4953            throw new SecurityException(callerUid + " cannot kill pkg: " +
4954                    pkg);
4955        }
4956    }
4957
4958    @Override
4959    public void closeSystemDialogs(String reason) {
4960        enforceNotIsolatedCaller("closeSystemDialogs");
4961
4962        final int pid = Binder.getCallingPid();
4963        final int uid = Binder.getCallingUid();
4964        final long origId = Binder.clearCallingIdentity();
4965        try {
4966            synchronized (this) {
4967                // Only allow this from foreground processes, so that background
4968                // applications can't abuse it to prevent system UI from being shown.
4969                if (uid >= Process.FIRST_APPLICATION_UID) {
4970                    ProcessRecord proc;
4971                    synchronized (mPidsSelfLocked) {
4972                        proc = mPidsSelfLocked.get(pid);
4973                    }
4974                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4975                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4976                                + " from background process " + proc);
4977                        return;
4978                    }
4979                }
4980                closeSystemDialogsLocked(reason);
4981            }
4982        } finally {
4983            Binder.restoreCallingIdentity(origId);
4984        }
4985    }
4986
4987    void closeSystemDialogsLocked(String reason) {
4988        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4989        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4990                | Intent.FLAG_RECEIVER_FOREGROUND);
4991        if (reason != null) {
4992            intent.putExtra("reason", reason);
4993        }
4994        mWindowManager.closeSystemDialogs(reason);
4995
4996        mStackSupervisor.closeSystemDialogsLocked();
4997
4998        broadcastIntentLocked(null, null, intent, null,
4999                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5000                Process.SYSTEM_UID, UserHandle.USER_ALL);
5001    }
5002
5003    @Override
5004    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5005        enforceNotIsolatedCaller("getProcessMemoryInfo");
5006        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5007        for (int i=pids.length-1; i>=0; i--) {
5008            ProcessRecord proc;
5009            int oomAdj;
5010            synchronized (this) {
5011                synchronized (mPidsSelfLocked) {
5012                    proc = mPidsSelfLocked.get(pids[i]);
5013                    oomAdj = proc != null ? proc.setAdj : 0;
5014                }
5015            }
5016            infos[i] = new Debug.MemoryInfo();
5017            Debug.getMemoryInfo(pids[i], infos[i]);
5018            if (proc != null) {
5019                synchronized (this) {
5020                    if (proc.thread != null && proc.setAdj == oomAdj) {
5021                        // Record this for posterity if the process has been stable.
5022                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5023                                infos[i].getTotalUss(), false, proc.pkgList);
5024                    }
5025                }
5026            }
5027        }
5028        return infos;
5029    }
5030
5031    @Override
5032    public long[] getProcessPss(int[] pids) {
5033        enforceNotIsolatedCaller("getProcessPss");
5034        long[] pss = new long[pids.length];
5035        for (int i=pids.length-1; i>=0; i--) {
5036            ProcessRecord proc;
5037            int oomAdj;
5038            synchronized (this) {
5039                synchronized (mPidsSelfLocked) {
5040                    proc = mPidsSelfLocked.get(pids[i]);
5041                    oomAdj = proc != null ? proc.setAdj : 0;
5042                }
5043            }
5044            long[] tmpUss = new long[1];
5045            pss[i] = Debug.getPss(pids[i], tmpUss);
5046            if (proc != null) {
5047                synchronized (this) {
5048                    if (proc.thread != null && proc.setAdj == oomAdj) {
5049                        // Record this for posterity if the process has been stable.
5050                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5051                    }
5052                }
5053            }
5054        }
5055        return pss;
5056    }
5057
5058    @Override
5059    public void killApplicationProcess(String processName, int uid) {
5060        if (processName == null) {
5061            return;
5062        }
5063
5064        int callerUid = Binder.getCallingUid();
5065        // Only the system server can kill an application
5066        if (callerUid == Process.SYSTEM_UID) {
5067            synchronized (this) {
5068                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5069                if (app != null && app.thread != null) {
5070                    try {
5071                        app.thread.scheduleSuicide();
5072                    } catch (RemoteException e) {
5073                        // If the other end already died, then our work here is done.
5074                    }
5075                } else {
5076                    Slog.w(TAG, "Process/uid not found attempting kill of "
5077                            + processName + " / " + uid);
5078                }
5079            }
5080        } else {
5081            throw new SecurityException(callerUid + " cannot kill app process: " +
5082                    processName);
5083        }
5084    }
5085
5086    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5087        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5088                false, true, false, false, UserHandle.getUserId(uid), reason);
5089        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5090                Uri.fromParts("package", packageName, null));
5091        if (!mProcessesReady) {
5092            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5093                    | Intent.FLAG_RECEIVER_FOREGROUND);
5094        }
5095        intent.putExtra(Intent.EXTRA_UID, uid);
5096        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5097        broadcastIntentLocked(null, null, intent,
5098                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5099                false, false,
5100                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5101    }
5102
5103    private void forceStopUserLocked(int userId, String reason) {
5104        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5105        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5106        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5107                | Intent.FLAG_RECEIVER_FOREGROUND);
5108        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5109        broadcastIntentLocked(null, null, intent,
5110                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5111                false, false,
5112                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5113    }
5114
5115    private final boolean killPackageProcessesLocked(String packageName, int appId,
5116            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5117            boolean doit, boolean evenPersistent, String reason) {
5118        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5119
5120        // Remove all processes this package may have touched: all with the
5121        // same UID (except for the system or root user), and all whose name
5122        // matches the package name.
5123        final int NP = mProcessNames.getMap().size();
5124        for (int ip=0; ip<NP; ip++) {
5125            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5126            final int NA = apps.size();
5127            for (int ia=0; ia<NA; ia++) {
5128                ProcessRecord app = apps.valueAt(ia);
5129                if (app.persistent && !evenPersistent) {
5130                    // we don't kill persistent processes
5131                    continue;
5132                }
5133                if (app.removed) {
5134                    if (doit) {
5135                        procs.add(app);
5136                    }
5137                    continue;
5138                }
5139
5140                // Skip process if it doesn't meet our oom adj requirement.
5141                if (app.setAdj < minOomAdj) {
5142                    continue;
5143                }
5144
5145                // If no package is specified, we call all processes under the
5146                // give user id.
5147                if (packageName == null) {
5148                    if (app.userId != userId) {
5149                        continue;
5150                    }
5151                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5152                        continue;
5153                    }
5154                // Package has been specified, we want to hit all processes
5155                // that match it.  We need to qualify this by the processes
5156                // that are running under the specified app and user ID.
5157                } else {
5158                    final boolean isDep = app.pkgDeps != null
5159                            && app.pkgDeps.contains(packageName);
5160                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5161                        continue;
5162                    }
5163                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5164                        continue;
5165                    }
5166                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5167                        continue;
5168                    }
5169                }
5170
5171                // Process has passed all conditions, kill it!
5172                if (!doit) {
5173                    return true;
5174                }
5175                app.removed = true;
5176                procs.add(app);
5177            }
5178        }
5179
5180        int N = procs.size();
5181        for (int i=0; i<N; i++) {
5182            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5183        }
5184        updateOomAdjLocked();
5185        return N > 0;
5186    }
5187
5188    private final boolean forceStopPackageLocked(String name, int appId,
5189            boolean callerWillRestart, boolean purgeCache, boolean doit,
5190            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5191        int i;
5192        int N;
5193
5194        if (userId == UserHandle.USER_ALL && name == null) {
5195            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5196        }
5197
5198        if (appId < 0 && name != null) {
5199            try {
5200                appId = UserHandle.getAppId(
5201                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5202            } catch (RemoteException e) {
5203            }
5204        }
5205
5206        if (doit) {
5207            if (name != null) {
5208                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5209                        + " user=" + userId + ": " + reason);
5210            } else {
5211                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5212            }
5213
5214            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5215            for (int ip=pmap.size()-1; ip>=0; ip--) {
5216                SparseArray<Long> ba = pmap.valueAt(ip);
5217                for (i=ba.size()-1; i>=0; i--) {
5218                    boolean remove = false;
5219                    final int entUid = ba.keyAt(i);
5220                    if (name != null) {
5221                        if (userId == UserHandle.USER_ALL) {
5222                            if (UserHandle.getAppId(entUid) == appId) {
5223                                remove = true;
5224                            }
5225                        } else {
5226                            if (entUid == UserHandle.getUid(userId, appId)) {
5227                                remove = true;
5228                            }
5229                        }
5230                    } else if (UserHandle.getUserId(entUid) == userId) {
5231                        remove = true;
5232                    }
5233                    if (remove) {
5234                        ba.removeAt(i);
5235                    }
5236                }
5237                if (ba.size() == 0) {
5238                    pmap.removeAt(ip);
5239                }
5240            }
5241        }
5242
5243        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5244                -100, callerWillRestart, true, doit, evenPersistent,
5245                name == null ? ("stop user " + userId) : ("stop " + name));
5246
5247        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5248            if (!doit) {
5249                return true;
5250            }
5251            didSomething = true;
5252        }
5253
5254        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5255            if (!doit) {
5256                return true;
5257            }
5258            didSomething = true;
5259        }
5260
5261        if (name == null) {
5262            // Remove all sticky broadcasts from this user.
5263            mStickyBroadcasts.remove(userId);
5264        }
5265
5266        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5267        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5268                userId, providers)) {
5269            if (!doit) {
5270                return true;
5271            }
5272            didSomething = true;
5273        }
5274        N = providers.size();
5275        for (i=0; i<N; i++) {
5276            removeDyingProviderLocked(null, providers.get(i), true);
5277        }
5278
5279        // Remove transient permissions granted from/to this package/user
5280        removeUriPermissionsForPackageLocked(name, userId, false);
5281
5282        if (name == null || uninstalling) {
5283            // Remove pending intents.  For now we only do this when force
5284            // stopping users, because we have some problems when doing this
5285            // for packages -- app widgets are not currently cleaned up for
5286            // such packages, so they can be left with bad pending intents.
5287            if (mIntentSenderRecords.size() > 0) {
5288                Iterator<WeakReference<PendingIntentRecord>> it
5289                        = mIntentSenderRecords.values().iterator();
5290                while (it.hasNext()) {
5291                    WeakReference<PendingIntentRecord> wpir = it.next();
5292                    if (wpir == null) {
5293                        it.remove();
5294                        continue;
5295                    }
5296                    PendingIntentRecord pir = wpir.get();
5297                    if (pir == null) {
5298                        it.remove();
5299                        continue;
5300                    }
5301                    if (name == null) {
5302                        // Stopping user, remove all objects for the user.
5303                        if (pir.key.userId != userId) {
5304                            // Not the same user, skip it.
5305                            continue;
5306                        }
5307                    } else {
5308                        if (UserHandle.getAppId(pir.uid) != appId) {
5309                            // Different app id, skip it.
5310                            continue;
5311                        }
5312                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5313                            // Different user, skip it.
5314                            continue;
5315                        }
5316                        if (!pir.key.packageName.equals(name)) {
5317                            // Different package, skip it.
5318                            continue;
5319                        }
5320                    }
5321                    if (!doit) {
5322                        return true;
5323                    }
5324                    didSomething = true;
5325                    it.remove();
5326                    pir.canceled = true;
5327                    if (pir.key.activity != null) {
5328                        pir.key.activity.pendingResults.remove(pir.ref);
5329                    }
5330                }
5331            }
5332        }
5333
5334        if (doit) {
5335            if (purgeCache && name != null) {
5336                AttributeCache ac = AttributeCache.instance();
5337                if (ac != null) {
5338                    ac.removePackage(name);
5339                }
5340            }
5341            if (mBooted) {
5342                mStackSupervisor.resumeTopActivitiesLocked();
5343                mStackSupervisor.scheduleIdleLocked();
5344            }
5345        }
5346
5347        return didSomething;
5348    }
5349
5350    private final boolean removeProcessLocked(ProcessRecord app,
5351            boolean callerWillRestart, boolean allowRestart, String reason) {
5352        final String name = app.processName;
5353        final int uid = app.uid;
5354        if (DEBUG_PROCESSES) Slog.d(
5355            TAG, "Force removing proc " + app.toShortString() + " (" + name
5356            + "/" + uid + ")");
5357
5358        mProcessNames.remove(name, uid);
5359        mIsolatedProcesses.remove(app.uid);
5360        if (mHeavyWeightProcess == app) {
5361            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5362                    mHeavyWeightProcess.userId, 0));
5363            mHeavyWeightProcess = null;
5364        }
5365        boolean needRestart = false;
5366        if (app.pid > 0 && app.pid != MY_PID) {
5367            int pid = app.pid;
5368            synchronized (mPidsSelfLocked) {
5369                mPidsSelfLocked.remove(pid);
5370                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5371            }
5372            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5373            if (app.isolated) {
5374                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5375            }
5376            killUnneededProcessLocked(app, reason);
5377            Process.killProcessGroup(app.info.uid, app.pid);
5378            handleAppDiedLocked(app, true, allowRestart);
5379            removeLruProcessLocked(app);
5380
5381            if (app.persistent && !app.isolated) {
5382                if (!callerWillRestart) {
5383                    addAppLocked(app.info, false, null /* ABI override */);
5384                } else {
5385                    needRestart = true;
5386                }
5387            }
5388        } else {
5389            mRemovedProcesses.add(app);
5390        }
5391
5392        return needRestart;
5393    }
5394
5395    private final void processStartTimedOutLocked(ProcessRecord app) {
5396        final int pid = app.pid;
5397        boolean gone = false;
5398        synchronized (mPidsSelfLocked) {
5399            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5400            if (knownApp != null && knownApp.thread == null) {
5401                mPidsSelfLocked.remove(pid);
5402                gone = true;
5403            }
5404        }
5405
5406        if (gone) {
5407            Slog.w(TAG, "Process " + app + " failed to attach");
5408            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5409                    pid, app.uid, app.processName);
5410            mProcessNames.remove(app.processName, app.uid);
5411            mIsolatedProcesses.remove(app.uid);
5412            if (mHeavyWeightProcess == app) {
5413                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5414                        mHeavyWeightProcess.userId, 0));
5415                mHeavyWeightProcess = null;
5416            }
5417            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5418            if (app.isolated) {
5419                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5420            }
5421            // Take care of any launching providers waiting for this process.
5422            checkAppInLaunchingProvidersLocked(app, true);
5423            // Take care of any services that are waiting for the process.
5424            mServices.processStartTimedOutLocked(app);
5425            killUnneededProcessLocked(app, "start timeout");
5426            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5427                Slog.w(TAG, "Unattached app died before backup, skipping");
5428                try {
5429                    IBackupManager bm = IBackupManager.Stub.asInterface(
5430                            ServiceManager.getService(Context.BACKUP_SERVICE));
5431                    bm.agentDisconnected(app.info.packageName);
5432                } catch (RemoteException e) {
5433                    // Can't happen; the backup manager is local
5434                }
5435            }
5436            if (isPendingBroadcastProcessLocked(pid)) {
5437                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5438                skipPendingBroadcastLocked(pid);
5439            }
5440        } else {
5441            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5442        }
5443    }
5444
5445    private final boolean attachApplicationLocked(IApplicationThread thread,
5446            int pid) {
5447
5448        // Find the application record that is being attached...  either via
5449        // the pid if we are running in multiple processes, or just pull the
5450        // next app record if we are emulating process with anonymous threads.
5451        ProcessRecord app;
5452        if (pid != MY_PID && pid >= 0) {
5453            synchronized (mPidsSelfLocked) {
5454                app = mPidsSelfLocked.get(pid);
5455            }
5456        } else {
5457            app = null;
5458        }
5459
5460        if (app == null) {
5461            Slog.w(TAG, "No pending application record for pid " + pid
5462                    + " (IApplicationThread " + thread + "); dropping process");
5463            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5464            if (pid > 0 && pid != MY_PID) {
5465                Process.killProcessQuiet(pid);
5466                //TODO: Process.killProcessGroup(app.info.uid, pid);
5467            } else {
5468                try {
5469                    thread.scheduleExit();
5470                } catch (Exception e) {
5471                    // Ignore exceptions.
5472                }
5473            }
5474            return false;
5475        }
5476
5477        // If this application record is still attached to a previous
5478        // process, clean it up now.
5479        if (app.thread != null) {
5480            handleAppDiedLocked(app, true, true);
5481        }
5482
5483        // Tell the process all about itself.
5484
5485        if (localLOGV) Slog.v(
5486                TAG, "Binding process pid " + pid + " to record " + app);
5487
5488        final String processName = app.processName;
5489        try {
5490            AppDeathRecipient adr = new AppDeathRecipient(
5491                    app, pid, thread);
5492            thread.asBinder().linkToDeath(adr, 0);
5493            app.deathRecipient = adr;
5494        } catch (RemoteException e) {
5495            app.resetPackageList(mProcessStats);
5496            startProcessLocked(app, "link fail", processName);
5497            return false;
5498        }
5499
5500        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5501
5502        app.makeActive(thread, mProcessStats);
5503        app.curAdj = app.setAdj = -100;
5504        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5505        app.forcingToForeground = null;
5506        updateProcessForegroundLocked(app, false, false);
5507        app.hasShownUi = false;
5508        app.debugging = false;
5509        app.cached = false;
5510
5511        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5512
5513        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5514        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5515
5516        if (!normalMode) {
5517            Slog.i(TAG, "Launching preboot mode app: " + app);
5518        }
5519
5520        if (localLOGV) Slog.v(
5521            TAG, "New app record " + app
5522            + " thread=" + thread.asBinder() + " pid=" + pid);
5523        try {
5524            int testMode = IApplicationThread.DEBUG_OFF;
5525            if (mDebugApp != null && mDebugApp.equals(processName)) {
5526                testMode = mWaitForDebugger
5527                    ? IApplicationThread.DEBUG_WAIT
5528                    : IApplicationThread.DEBUG_ON;
5529                app.debugging = true;
5530                if (mDebugTransient) {
5531                    mDebugApp = mOrigDebugApp;
5532                    mWaitForDebugger = mOrigWaitForDebugger;
5533                }
5534            }
5535            String profileFile = app.instrumentationProfileFile;
5536            ParcelFileDescriptor profileFd = null;
5537            boolean profileAutoStop = false;
5538            if (mProfileApp != null && mProfileApp.equals(processName)) {
5539                mProfileProc = app;
5540                profileFile = mProfileFile;
5541                profileFd = mProfileFd;
5542                profileAutoStop = mAutoStopProfiler;
5543            }
5544            boolean enableOpenGlTrace = false;
5545            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5546                enableOpenGlTrace = true;
5547                mOpenGlTraceApp = null;
5548            }
5549
5550            // If the app is being launched for restore or full backup, set it up specially
5551            boolean isRestrictedBackupMode = false;
5552            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5553                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5554                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5555                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5556            }
5557
5558            ensurePackageDexOpt(app.instrumentationInfo != null
5559                    ? app.instrumentationInfo.packageName
5560                    : app.info.packageName);
5561            if (app.instrumentationClass != null) {
5562                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5563            }
5564            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5565                    + processName + " with config " + mConfiguration);
5566            ApplicationInfo appInfo = app.instrumentationInfo != null
5567                    ? app.instrumentationInfo : app.info;
5568            app.compat = compatibilityInfoForPackageLocked(appInfo);
5569            if (profileFd != null) {
5570                profileFd = profileFd.dup();
5571            }
5572            thread.bindApplication(processName, appInfo, providers,
5573                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5574                    app.instrumentationArguments, app.instrumentationWatcher,
5575                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5576                    isRestrictedBackupMode || !normalMode, app.persistent,
5577                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5578                    mCoreSettingsObserver.getCoreSettingsLocked());
5579            updateLruProcessLocked(app, false, null);
5580            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5581        } catch (Exception e) {
5582            // todo: Yikes!  What should we do?  For now we will try to
5583            // start another process, but that could easily get us in
5584            // an infinite loop of restarting processes...
5585            Slog.w(TAG, "Exception thrown during bind!", e);
5586
5587            app.resetPackageList(mProcessStats);
5588            app.unlinkDeathRecipient();
5589            startProcessLocked(app, "bind fail", processName);
5590            return false;
5591        }
5592
5593        // Remove this record from the list of starting applications.
5594        mPersistentStartingProcesses.remove(app);
5595        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5596                "Attach application locked removing on hold: " + app);
5597        mProcessesOnHold.remove(app);
5598
5599        boolean badApp = false;
5600        boolean didSomething = false;
5601
5602        // See if the top visible activity is waiting to run in this process...
5603        if (normalMode) {
5604            try {
5605                if (mStackSupervisor.attachApplicationLocked(app)) {
5606                    didSomething = true;
5607                }
5608            } catch (Exception e) {
5609                badApp = true;
5610            }
5611        }
5612
5613        // Find any services that should be running in this process...
5614        if (!badApp) {
5615            try {
5616                didSomething |= mServices.attachApplicationLocked(app, processName);
5617            } catch (Exception e) {
5618                badApp = true;
5619            }
5620        }
5621
5622        // Check if a next-broadcast receiver is in this process...
5623        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5624            try {
5625                didSomething |= sendPendingBroadcastsLocked(app);
5626            } catch (Exception e) {
5627                // If the app died trying to launch the receiver we declare it 'bad'
5628                badApp = true;
5629            }
5630        }
5631
5632        // Check whether the next backup agent is in this process...
5633        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5634            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5635            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5636            try {
5637                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5638                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5639                        mBackupTarget.backupMode);
5640            } catch (Exception e) {
5641                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5642                e.printStackTrace();
5643            }
5644        }
5645
5646        if (badApp) {
5647            // todo: Also need to kill application to deal with all
5648            // kinds of exceptions.
5649            handleAppDiedLocked(app, false, true);
5650            return false;
5651        }
5652
5653        if (!didSomething) {
5654            updateOomAdjLocked();
5655        }
5656
5657        return true;
5658    }
5659
5660    @Override
5661    public final void attachApplication(IApplicationThread thread) {
5662        synchronized (this) {
5663            int callingPid = Binder.getCallingPid();
5664            final long origId = Binder.clearCallingIdentity();
5665            attachApplicationLocked(thread, callingPid);
5666            Binder.restoreCallingIdentity(origId);
5667        }
5668    }
5669
5670    @Override
5671    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5672        final long origId = Binder.clearCallingIdentity();
5673        synchronized (this) {
5674            ActivityStack stack = ActivityRecord.getStackLocked(token);
5675            if (stack != null) {
5676                ActivityRecord r =
5677                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5678                if (stopProfiling) {
5679                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5680                        try {
5681                            mProfileFd.close();
5682                        } catch (IOException e) {
5683                        }
5684                        clearProfilerLocked();
5685                    }
5686                }
5687            }
5688        }
5689        Binder.restoreCallingIdentity(origId);
5690    }
5691
5692    void postEnableScreenAfterBootLocked() {
5693        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
5694    }
5695
5696    void enableScreenAfterBoot() {
5697        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5698                SystemClock.uptimeMillis());
5699        mWindowManager.enableScreenAfterBoot();
5700
5701        synchronized (this) {
5702            updateEventDispatchingLocked();
5703        }
5704    }
5705
5706    @Override
5707    public void showBootMessage(final CharSequence msg, final boolean always) {
5708        enforceNotIsolatedCaller("showBootMessage");
5709        mWindowManager.showBootMessage(msg, always);
5710    }
5711
5712    @Override
5713    public void keyguardWaitingForActivityDrawn() {
5714        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
5715        final long token = Binder.clearCallingIdentity();
5716        try {
5717            synchronized (this) {
5718                if (DEBUG_LOCKSCREEN) logLockScreen("");
5719                mWindowManager.keyguardWaitingForActivityDrawn();
5720            }
5721        } finally {
5722            Binder.restoreCallingIdentity(token);
5723        }
5724    }
5725
5726    final void finishBooting() {
5727        // Register receivers to handle package update events
5728        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5729
5730        // Let system services know.
5731        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
5732
5733        synchronized (this) {
5734            // Ensure that any processes we had put on hold are now started
5735            // up.
5736            final int NP = mProcessesOnHold.size();
5737            if (NP > 0) {
5738                ArrayList<ProcessRecord> procs =
5739                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5740                for (int ip=0; ip<NP; ip++) {
5741                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5742                            + procs.get(ip));
5743                    startProcessLocked(procs.get(ip), "on-hold", null);
5744                }
5745            }
5746
5747            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5748                // Start looking for apps that are abusing wake locks.
5749                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5750                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5751                // Tell anyone interested that we are done booting!
5752                SystemProperties.set("sys.boot_completed", "1");
5753                SystemProperties.set("dev.bootcomplete", "1");
5754                for (int i=0; i<mStartedUsers.size(); i++) {
5755                    UserStartedState uss = mStartedUsers.valueAt(i);
5756                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5757                        uss.mState = UserStartedState.STATE_RUNNING;
5758                        final int userId = mStartedUsers.keyAt(i);
5759                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5760                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5761                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5762                        broadcastIntentLocked(null, null, intent, null,
5763                                new IIntentReceiver.Stub() {
5764                                    @Override
5765                                    public void performReceive(Intent intent, int resultCode,
5766                                            String data, Bundle extras, boolean ordered,
5767                                            boolean sticky, int sendingUser) {
5768                                        synchronized (ActivityManagerService.this) {
5769                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5770                                                    true, false);
5771                                        }
5772                                    }
5773                                },
5774                                0, null, null,
5775                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5776                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5777                                userId);
5778                    }
5779                }
5780                scheduleStartProfilesLocked();
5781            }
5782        }
5783    }
5784
5785    final void ensureBootCompleted() {
5786        boolean booting;
5787        boolean enableScreen;
5788        synchronized (this) {
5789            booting = mBooting;
5790            mBooting = false;
5791            enableScreen = !mBooted;
5792            mBooted = true;
5793        }
5794
5795        if (booting) {
5796            finishBooting();
5797        }
5798
5799        if (enableScreen) {
5800            enableScreenAfterBoot();
5801        }
5802    }
5803
5804    @Override
5805    public final void activityResumed(IBinder token) {
5806        final long origId = Binder.clearCallingIdentity();
5807        synchronized(this) {
5808            ActivityStack stack = ActivityRecord.getStackLocked(token);
5809            if (stack != null) {
5810                ActivityRecord.activityResumedLocked(token);
5811            }
5812        }
5813        Binder.restoreCallingIdentity(origId);
5814    }
5815
5816    @Override
5817    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5818        final long origId = Binder.clearCallingIdentity();
5819        synchronized(this) {
5820            ActivityStack stack = ActivityRecord.getStackLocked(token);
5821            if (stack != null) {
5822                stack.activityPausedLocked(token, false, persistentState);
5823            }
5824        }
5825        Binder.restoreCallingIdentity(origId);
5826    }
5827
5828    @Override
5829    public final void activityStopped(IBinder token, Bundle icicle,
5830            PersistableBundle persistentState, CharSequence description) {
5831        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5832
5833        // Refuse possible leaked file descriptors
5834        if (icicle != null && icicle.hasFileDescriptors()) {
5835            throw new IllegalArgumentException("File descriptors passed in Bundle");
5836        }
5837
5838        final long origId = Binder.clearCallingIdentity();
5839
5840        synchronized (this) {
5841            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5842            if (r != null) {
5843                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5844            }
5845        }
5846
5847        trimApplications();
5848
5849        Binder.restoreCallingIdentity(origId);
5850    }
5851
5852    @Override
5853    public final void activityDestroyed(IBinder token) {
5854        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5855        synchronized (this) {
5856            ActivityStack stack = ActivityRecord.getStackLocked(token);
5857            if (stack != null) {
5858                stack.activityDestroyedLocked(token);
5859            }
5860        }
5861    }
5862
5863    @Override
5864    public final void backgroundResourcesReleased(IBinder token) {
5865        final long origId = Binder.clearCallingIdentity();
5866        try {
5867            synchronized (this) {
5868                ActivityStack stack = ActivityRecord.getStackLocked(token);
5869                if (stack != null) {
5870                    stack.backgroundResourcesReleased(token);
5871                }
5872            }
5873        } finally {
5874            Binder.restoreCallingIdentity(origId);
5875        }
5876    }
5877
5878    @Override
5879    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5880        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5881    }
5882
5883    @Override
5884    public final void notifyEnterAnimationComplete(IBinder token) {
5885        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5886    }
5887
5888    @Override
5889    public String getCallingPackage(IBinder token) {
5890        synchronized (this) {
5891            ActivityRecord r = getCallingRecordLocked(token);
5892            return r != null ? r.info.packageName : null;
5893        }
5894    }
5895
5896    @Override
5897    public ComponentName getCallingActivity(IBinder token) {
5898        synchronized (this) {
5899            ActivityRecord r = getCallingRecordLocked(token);
5900            return r != null ? r.intent.getComponent() : null;
5901        }
5902    }
5903
5904    private ActivityRecord getCallingRecordLocked(IBinder token) {
5905        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5906        if (r == null) {
5907            return null;
5908        }
5909        return r.resultTo;
5910    }
5911
5912    @Override
5913    public ComponentName getActivityClassForToken(IBinder token) {
5914        synchronized(this) {
5915            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5916            if (r == null) {
5917                return null;
5918            }
5919            return r.intent.getComponent();
5920        }
5921    }
5922
5923    @Override
5924    public String getPackageForToken(IBinder token) {
5925        synchronized(this) {
5926            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5927            if (r == null) {
5928                return null;
5929            }
5930            return r.packageName;
5931        }
5932    }
5933
5934    @Override
5935    public IIntentSender getIntentSender(int type,
5936            String packageName, IBinder token, String resultWho,
5937            int requestCode, Intent[] intents, String[] resolvedTypes,
5938            int flags, Bundle options, int userId) {
5939        enforceNotIsolatedCaller("getIntentSender");
5940        // Refuse possible leaked file descriptors
5941        if (intents != null) {
5942            if (intents.length < 1) {
5943                throw new IllegalArgumentException("Intents array length must be >= 1");
5944            }
5945            for (int i=0; i<intents.length; i++) {
5946                Intent intent = intents[i];
5947                if (intent != null) {
5948                    if (intent.hasFileDescriptors()) {
5949                        throw new IllegalArgumentException("File descriptors passed in Intent");
5950                    }
5951                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5952                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5953                        throw new IllegalArgumentException(
5954                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5955                    }
5956                    intents[i] = new Intent(intent);
5957                }
5958            }
5959            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5960                throw new IllegalArgumentException(
5961                        "Intent array length does not match resolvedTypes length");
5962            }
5963        }
5964        if (options != null) {
5965            if (options.hasFileDescriptors()) {
5966                throw new IllegalArgumentException("File descriptors passed in options");
5967            }
5968        }
5969
5970        synchronized(this) {
5971            int callingUid = Binder.getCallingUid();
5972            int origUserId = userId;
5973            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5974                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5975                    ALLOW_NON_FULL, "getIntentSender", null);
5976            if (origUserId == UserHandle.USER_CURRENT) {
5977                // We don't want to evaluate this until the pending intent is
5978                // actually executed.  However, we do want to always do the
5979                // security checking for it above.
5980                userId = UserHandle.USER_CURRENT;
5981            }
5982            try {
5983                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5984                    int uid = AppGlobals.getPackageManager()
5985                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5986                    if (!UserHandle.isSameApp(callingUid, uid)) {
5987                        String msg = "Permission Denial: getIntentSender() from pid="
5988                            + Binder.getCallingPid()
5989                            + ", uid=" + Binder.getCallingUid()
5990                            + ", (need uid=" + uid + ")"
5991                            + " is not allowed to send as package " + packageName;
5992                        Slog.w(TAG, msg);
5993                        throw new SecurityException(msg);
5994                    }
5995                }
5996
5997                return getIntentSenderLocked(type, packageName, callingUid, userId,
5998                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5999
6000            } catch (RemoteException e) {
6001                throw new SecurityException(e);
6002            }
6003        }
6004    }
6005
6006    IIntentSender getIntentSenderLocked(int type, String packageName,
6007            int callingUid, int userId, IBinder token, String resultWho,
6008            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6009            Bundle options) {
6010        if (DEBUG_MU)
6011            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6012        ActivityRecord activity = null;
6013        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6014            activity = ActivityRecord.isInStackLocked(token);
6015            if (activity == null) {
6016                return null;
6017            }
6018            if (activity.finishing) {
6019                return null;
6020            }
6021        }
6022
6023        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6024        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6025        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6026        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6027                |PendingIntent.FLAG_UPDATE_CURRENT);
6028
6029        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6030                type, packageName, activity, resultWho,
6031                requestCode, intents, resolvedTypes, flags, options, userId);
6032        WeakReference<PendingIntentRecord> ref;
6033        ref = mIntentSenderRecords.get(key);
6034        PendingIntentRecord rec = ref != null ? ref.get() : null;
6035        if (rec != null) {
6036            if (!cancelCurrent) {
6037                if (updateCurrent) {
6038                    if (rec.key.requestIntent != null) {
6039                        rec.key.requestIntent.replaceExtras(intents != null ?
6040                                intents[intents.length - 1] : null);
6041                    }
6042                    if (intents != null) {
6043                        intents[intents.length-1] = rec.key.requestIntent;
6044                        rec.key.allIntents = intents;
6045                        rec.key.allResolvedTypes = resolvedTypes;
6046                    } else {
6047                        rec.key.allIntents = null;
6048                        rec.key.allResolvedTypes = null;
6049                    }
6050                }
6051                return rec;
6052            }
6053            rec.canceled = true;
6054            mIntentSenderRecords.remove(key);
6055        }
6056        if (noCreate) {
6057            return rec;
6058        }
6059        rec = new PendingIntentRecord(this, key, callingUid);
6060        mIntentSenderRecords.put(key, rec.ref);
6061        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6062            if (activity.pendingResults == null) {
6063                activity.pendingResults
6064                        = new HashSet<WeakReference<PendingIntentRecord>>();
6065            }
6066            activity.pendingResults.add(rec.ref);
6067        }
6068        return rec;
6069    }
6070
6071    @Override
6072    public void cancelIntentSender(IIntentSender sender) {
6073        if (!(sender instanceof PendingIntentRecord)) {
6074            return;
6075        }
6076        synchronized(this) {
6077            PendingIntentRecord rec = (PendingIntentRecord)sender;
6078            try {
6079                int uid = AppGlobals.getPackageManager()
6080                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6081                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6082                    String msg = "Permission Denial: cancelIntentSender() from pid="
6083                        + Binder.getCallingPid()
6084                        + ", uid=" + Binder.getCallingUid()
6085                        + " is not allowed to cancel packges "
6086                        + rec.key.packageName;
6087                    Slog.w(TAG, msg);
6088                    throw new SecurityException(msg);
6089                }
6090            } catch (RemoteException e) {
6091                throw new SecurityException(e);
6092            }
6093            cancelIntentSenderLocked(rec, true);
6094        }
6095    }
6096
6097    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6098        rec.canceled = true;
6099        mIntentSenderRecords.remove(rec.key);
6100        if (cleanActivity && rec.key.activity != null) {
6101            rec.key.activity.pendingResults.remove(rec.ref);
6102        }
6103    }
6104
6105    @Override
6106    public String getPackageForIntentSender(IIntentSender pendingResult) {
6107        if (!(pendingResult instanceof PendingIntentRecord)) {
6108            return null;
6109        }
6110        try {
6111            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6112            return res.key.packageName;
6113        } catch (ClassCastException e) {
6114        }
6115        return null;
6116    }
6117
6118    @Override
6119    public int getUidForIntentSender(IIntentSender sender) {
6120        if (sender instanceof PendingIntentRecord) {
6121            try {
6122                PendingIntentRecord res = (PendingIntentRecord)sender;
6123                return res.uid;
6124            } catch (ClassCastException e) {
6125            }
6126        }
6127        return -1;
6128    }
6129
6130    @Override
6131    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6132        if (!(pendingResult instanceof PendingIntentRecord)) {
6133            return false;
6134        }
6135        try {
6136            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6137            if (res.key.allIntents == null) {
6138                return false;
6139            }
6140            for (int i=0; i<res.key.allIntents.length; i++) {
6141                Intent intent = res.key.allIntents[i];
6142                if (intent.getPackage() != null && intent.getComponent() != null) {
6143                    return false;
6144                }
6145            }
6146            return true;
6147        } catch (ClassCastException e) {
6148        }
6149        return false;
6150    }
6151
6152    @Override
6153    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6154        if (!(pendingResult instanceof PendingIntentRecord)) {
6155            return false;
6156        }
6157        try {
6158            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6159            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6160                return true;
6161            }
6162            return false;
6163        } catch (ClassCastException e) {
6164        }
6165        return false;
6166    }
6167
6168    @Override
6169    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6170        if (!(pendingResult instanceof PendingIntentRecord)) {
6171            return null;
6172        }
6173        try {
6174            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6175            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6176        } catch (ClassCastException e) {
6177        }
6178        return null;
6179    }
6180
6181    @Override
6182    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6183        if (!(pendingResult instanceof PendingIntentRecord)) {
6184            return null;
6185        }
6186        try {
6187            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6188            Intent intent = res.key.requestIntent;
6189            if (intent != null) {
6190                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6191                        || res.lastTagPrefix.equals(prefix))) {
6192                    return res.lastTag;
6193                }
6194                res.lastTagPrefix = prefix;
6195                StringBuilder sb = new StringBuilder(128);
6196                if (prefix != null) {
6197                    sb.append(prefix);
6198                }
6199                if (intent.getAction() != null) {
6200                    sb.append(intent.getAction());
6201                } else if (intent.getComponent() != null) {
6202                    intent.getComponent().appendShortString(sb);
6203                } else {
6204                    sb.append("?");
6205                }
6206                return res.lastTag = sb.toString();
6207            }
6208        } catch (ClassCastException e) {
6209        }
6210        return null;
6211    }
6212
6213    @Override
6214    public void setProcessLimit(int max) {
6215        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6216                "setProcessLimit()");
6217        synchronized (this) {
6218            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6219            mProcessLimitOverride = max;
6220        }
6221        trimApplications();
6222    }
6223
6224    @Override
6225    public int getProcessLimit() {
6226        synchronized (this) {
6227            return mProcessLimitOverride;
6228        }
6229    }
6230
6231    void foregroundTokenDied(ForegroundToken token) {
6232        synchronized (ActivityManagerService.this) {
6233            synchronized (mPidsSelfLocked) {
6234                ForegroundToken cur
6235                    = mForegroundProcesses.get(token.pid);
6236                if (cur != token) {
6237                    return;
6238                }
6239                mForegroundProcesses.remove(token.pid);
6240                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6241                if (pr == null) {
6242                    return;
6243                }
6244                pr.forcingToForeground = null;
6245                updateProcessForegroundLocked(pr, false, false);
6246            }
6247            updateOomAdjLocked();
6248        }
6249    }
6250
6251    @Override
6252    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6253        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6254                "setProcessForeground()");
6255        synchronized(this) {
6256            boolean changed = false;
6257
6258            synchronized (mPidsSelfLocked) {
6259                ProcessRecord pr = mPidsSelfLocked.get(pid);
6260                if (pr == null && isForeground) {
6261                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6262                    return;
6263                }
6264                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6265                if (oldToken != null) {
6266                    oldToken.token.unlinkToDeath(oldToken, 0);
6267                    mForegroundProcesses.remove(pid);
6268                    if (pr != null) {
6269                        pr.forcingToForeground = null;
6270                    }
6271                    changed = true;
6272                }
6273                if (isForeground && token != null) {
6274                    ForegroundToken newToken = new ForegroundToken() {
6275                        @Override
6276                        public void binderDied() {
6277                            foregroundTokenDied(this);
6278                        }
6279                    };
6280                    newToken.pid = pid;
6281                    newToken.token = token;
6282                    try {
6283                        token.linkToDeath(newToken, 0);
6284                        mForegroundProcesses.put(pid, newToken);
6285                        pr.forcingToForeground = token;
6286                        changed = true;
6287                    } catch (RemoteException e) {
6288                        // If the process died while doing this, we will later
6289                        // do the cleanup with the process death link.
6290                    }
6291                }
6292            }
6293
6294            if (changed) {
6295                updateOomAdjLocked();
6296            }
6297        }
6298    }
6299
6300    // =========================================================
6301    // PERMISSIONS
6302    // =========================================================
6303
6304    static class PermissionController extends IPermissionController.Stub {
6305        ActivityManagerService mActivityManagerService;
6306        PermissionController(ActivityManagerService activityManagerService) {
6307            mActivityManagerService = activityManagerService;
6308        }
6309
6310        @Override
6311        public boolean checkPermission(String permission, int pid, int uid) {
6312            return mActivityManagerService.checkPermission(permission, pid,
6313                    uid) == PackageManager.PERMISSION_GRANTED;
6314        }
6315    }
6316
6317    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6318        @Override
6319        public int checkComponentPermission(String permission, int pid, int uid,
6320                int owningUid, boolean exported) {
6321            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6322                    owningUid, exported);
6323        }
6324
6325        @Override
6326        public Object getAMSLock() {
6327            return ActivityManagerService.this;
6328        }
6329    }
6330
6331    /**
6332     * This can be called with or without the global lock held.
6333     */
6334    int checkComponentPermission(String permission, int pid, int uid,
6335            int owningUid, boolean exported) {
6336        // We might be performing an operation on behalf of an indirect binder
6337        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6338        // client identity accordingly before proceeding.
6339        Identity tlsIdentity = sCallerIdentity.get();
6340        if (tlsIdentity != null) {
6341            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6342                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6343            uid = tlsIdentity.uid;
6344            pid = tlsIdentity.pid;
6345        }
6346
6347        if (pid == MY_PID) {
6348            return PackageManager.PERMISSION_GRANTED;
6349        }
6350
6351        return ActivityManager.checkComponentPermission(permission, uid,
6352                owningUid, exported);
6353    }
6354
6355    /**
6356     * As the only public entry point for permissions checking, this method
6357     * can enforce the semantic that requesting a check on a null global
6358     * permission is automatically denied.  (Internally a null permission
6359     * string is used when calling {@link #checkComponentPermission} in cases
6360     * when only uid-based security is needed.)
6361     *
6362     * This can be called with or without the global lock held.
6363     */
6364    @Override
6365    public int checkPermission(String permission, int pid, int uid) {
6366        if (permission == null) {
6367            return PackageManager.PERMISSION_DENIED;
6368        }
6369        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6370    }
6371
6372    /**
6373     * Binder IPC calls go through the public entry point.
6374     * This can be called with or without the global lock held.
6375     */
6376    int checkCallingPermission(String permission) {
6377        return checkPermission(permission,
6378                Binder.getCallingPid(),
6379                UserHandle.getAppId(Binder.getCallingUid()));
6380    }
6381
6382    /**
6383     * This can be called with or without the global lock held.
6384     */
6385    void enforceCallingPermission(String permission, String func) {
6386        if (checkCallingPermission(permission)
6387                == PackageManager.PERMISSION_GRANTED) {
6388            return;
6389        }
6390
6391        String msg = "Permission Denial: " + func + " from pid="
6392                + Binder.getCallingPid()
6393                + ", uid=" + Binder.getCallingUid()
6394                + " requires " + permission;
6395        Slog.w(TAG, msg);
6396        throw new SecurityException(msg);
6397    }
6398
6399    /**
6400     * Determine if UID is holding permissions required to access {@link Uri} in
6401     * the given {@link ProviderInfo}. Final permission checking is always done
6402     * in {@link ContentProvider}.
6403     */
6404    private final boolean checkHoldingPermissionsLocked(
6405            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6406        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6407                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6408        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6409            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6410                    != PERMISSION_GRANTED) {
6411                return false;
6412            }
6413        }
6414        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6415    }
6416
6417    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6418            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6419        if (pi.applicationInfo.uid == uid) {
6420            return true;
6421        } else if (!pi.exported) {
6422            return false;
6423        }
6424
6425        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6426        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6427        try {
6428            // check if target holds top-level <provider> permissions
6429            if (!readMet && pi.readPermission != null && considerUidPermissions
6430                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6431                readMet = true;
6432            }
6433            if (!writeMet && pi.writePermission != null && considerUidPermissions
6434                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6435                writeMet = true;
6436            }
6437
6438            // track if unprotected read/write is allowed; any denied
6439            // <path-permission> below removes this ability
6440            boolean allowDefaultRead = pi.readPermission == null;
6441            boolean allowDefaultWrite = pi.writePermission == null;
6442
6443            // check if target holds any <path-permission> that match uri
6444            final PathPermission[] pps = pi.pathPermissions;
6445            if (pps != null) {
6446                final String path = grantUri.uri.getPath();
6447                int i = pps.length;
6448                while (i > 0 && (!readMet || !writeMet)) {
6449                    i--;
6450                    PathPermission pp = pps[i];
6451                    if (pp.match(path)) {
6452                        if (!readMet) {
6453                            final String pprperm = pp.getReadPermission();
6454                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6455                                    + pprperm + " for " + pp.getPath()
6456                                    + ": match=" + pp.match(path)
6457                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6458                            if (pprperm != null) {
6459                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6460                                        == PERMISSION_GRANTED) {
6461                                    readMet = true;
6462                                } else {
6463                                    allowDefaultRead = false;
6464                                }
6465                            }
6466                        }
6467                        if (!writeMet) {
6468                            final String ppwperm = pp.getWritePermission();
6469                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6470                                    + ppwperm + " for " + pp.getPath()
6471                                    + ": match=" + pp.match(path)
6472                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6473                            if (ppwperm != null) {
6474                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6475                                        == PERMISSION_GRANTED) {
6476                                    writeMet = true;
6477                                } else {
6478                                    allowDefaultWrite = false;
6479                                }
6480                            }
6481                        }
6482                    }
6483                }
6484            }
6485
6486            // grant unprotected <provider> read/write, if not blocked by
6487            // <path-permission> above
6488            if (allowDefaultRead) readMet = true;
6489            if (allowDefaultWrite) writeMet = true;
6490
6491        } catch (RemoteException e) {
6492            return false;
6493        }
6494
6495        return readMet && writeMet;
6496    }
6497
6498    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6499        ProviderInfo pi = null;
6500        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6501        if (cpr != null) {
6502            pi = cpr.info;
6503        } else {
6504            try {
6505                pi = AppGlobals.getPackageManager().resolveContentProvider(
6506                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6507            } catch (RemoteException ex) {
6508            }
6509        }
6510        return pi;
6511    }
6512
6513    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6514        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6515        if (targetUris != null) {
6516            return targetUris.get(grantUri);
6517        }
6518        return null;
6519    }
6520
6521    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6522            String targetPkg, int targetUid, GrantUri grantUri) {
6523        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6524        if (targetUris == null) {
6525            targetUris = Maps.newArrayMap();
6526            mGrantedUriPermissions.put(targetUid, targetUris);
6527        }
6528
6529        UriPermission perm = targetUris.get(grantUri);
6530        if (perm == null) {
6531            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6532            targetUris.put(grantUri, perm);
6533        }
6534
6535        return perm;
6536    }
6537
6538    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6539            final int modeFlags) {
6540        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6541        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6542                : UriPermission.STRENGTH_OWNED;
6543
6544        // Root gets to do everything.
6545        if (uid == 0) {
6546            return true;
6547        }
6548
6549        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6550        if (perms == null) return false;
6551
6552        // First look for exact match
6553        final UriPermission exactPerm = perms.get(grantUri);
6554        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6555            return true;
6556        }
6557
6558        // No exact match, look for prefixes
6559        final int N = perms.size();
6560        for (int i = 0; i < N; i++) {
6561            final UriPermission perm = perms.valueAt(i);
6562            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6563                    && perm.getStrength(modeFlags) >= minStrength) {
6564                return true;
6565            }
6566        }
6567
6568        return false;
6569    }
6570
6571    @Override
6572    public int checkUriPermission(Uri uri, int pid, int uid,
6573            final int modeFlags, int userId) {
6574        enforceNotIsolatedCaller("checkUriPermission");
6575
6576        // Another redirected-binder-call permissions check as in
6577        // {@link checkComponentPermission}.
6578        Identity tlsIdentity = sCallerIdentity.get();
6579        if (tlsIdentity != null) {
6580            uid = tlsIdentity.uid;
6581            pid = tlsIdentity.pid;
6582        }
6583
6584        // Our own process gets to do everything.
6585        if (pid == MY_PID) {
6586            return PackageManager.PERMISSION_GRANTED;
6587        }
6588        synchronized (this) {
6589            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6590                    ? PackageManager.PERMISSION_GRANTED
6591                    : PackageManager.PERMISSION_DENIED;
6592        }
6593    }
6594
6595    /**
6596     * Check if the targetPkg can be granted permission to access uri by
6597     * the callingUid using the given modeFlags.  Throws a security exception
6598     * if callingUid is not allowed to do this.  Returns the uid of the target
6599     * if the URI permission grant should be performed; returns -1 if it is not
6600     * needed (for example targetPkg already has permission to access the URI).
6601     * If you already know the uid of the target, you can supply it in
6602     * lastTargetUid else set that to -1.
6603     */
6604    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6605            final int modeFlags, int lastTargetUid) {
6606        if (!Intent.isAccessUriMode(modeFlags)) {
6607            return -1;
6608        }
6609
6610        if (targetPkg != null) {
6611            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6612                    "Checking grant " + targetPkg + " permission to " + grantUri);
6613        }
6614
6615        final IPackageManager pm = AppGlobals.getPackageManager();
6616
6617        // If this is not a content: uri, we can't do anything with it.
6618        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6619            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6620                    "Can't grant URI permission for non-content URI: " + grantUri);
6621            return -1;
6622        }
6623
6624        final String authority = grantUri.uri.getAuthority();
6625        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6626        if (pi == null) {
6627            Slog.w(TAG, "No content provider found for permission check: " +
6628                    grantUri.uri.toSafeString());
6629            return -1;
6630        }
6631
6632        int targetUid = lastTargetUid;
6633        if (targetUid < 0 && targetPkg != null) {
6634            try {
6635                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6636                if (targetUid < 0) {
6637                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6638                            "Can't grant URI permission no uid for: " + targetPkg);
6639                    return -1;
6640                }
6641            } catch (RemoteException ex) {
6642                return -1;
6643            }
6644        }
6645
6646        if (targetUid >= 0) {
6647            // First...  does the target actually need this permission?
6648            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6649                // No need to grant the target this permission.
6650                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6651                        "Target " + targetPkg + " already has full permission to " + grantUri);
6652                return -1;
6653            }
6654        } else {
6655            // First...  there is no target package, so can anyone access it?
6656            boolean allowed = pi.exported;
6657            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6658                if (pi.readPermission != null) {
6659                    allowed = false;
6660                }
6661            }
6662            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6663                if (pi.writePermission != null) {
6664                    allowed = false;
6665                }
6666            }
6667            if (allowed) {
6668                return -1;
6669            }
6670        }
6671
6672        /* There is a special cross user grant if:
6673         * - The target is on another user.
6674         * - Apps on the current user can access the uri without any uid permissions.
6675         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6676         * grant uri permissions.
6677         */
6678        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6679                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6680                modeFlags, false /*without considering the uid permissions*/);
6681
6682        // Second...  is the provider allowing granting of URI permissions?
6683        if (!specialCrossUserGrant) {
6684            if (!pi.grantUriPermissions) {
6685                throw new SecurityException("Provider " + pi.packageName
6686                        + "/" + pi.name
6687                        + " does not allow granting of Uri permissions (uri "
6688                        + grantUri + ")");
6689            }
6690            if (pi.uriPermissionPatterns != null) {
6691                final int N = pi.uriPermissionPatterns.length;
6692                boolean allowed = false;
6693                for (int i=0; i<N; i++) {
6694                    if (pi.uriPermissionPatterns[i] != null
6695                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6696                        allowed = true;
6697                        break;
6698                    }
6699                }
6700                if (!allowed) {
6701                    throw new SecurityException("Provider " + pi.packageName
6702                            + "/" + pi.name
6703                            + " does not allow granting of permission to path of Uri "
6704                            + grantUri);
6705                }
6706            }
6707        }
6708
6709        // Third...  does the caller itself have permission to access
6710        // this uri?
6711        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6712            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6713                // Require they hold a strong enough Uri permission
6714                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6715                    throw new SecurityException("Uid " + callingUid
6716                            + " does not have permission to uri " + grantUri);
6717                }
6718            }
6719        }
6720        return targetUid;
6721    }
6722
6723    @Override
6724    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6725            final int modeFlags, int userId) {
6726        enforceNotIsolatedCaller("checkGrantUriPermission");
6727        synchronized(this) {
6728            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6729                    new GrantUri(userId, uri, false), modeFlags, -1);
6730        }
6731    }
6732
6733    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6734            final int modeFlags, UriPermissionOwner owner) {
6735        if (!Intent.isAccessUriMode(modeFlags)) {
6736            return;
6737        }
6738
6739        // So here we are: the caller has the assumed permission
6740        // to the uri, and the target doesn't.  Let's now give this to
6741        // the target.
6742
6743        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6744                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6745
6746        final String authority = grantUri.uri.getAuthority();
6747        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6748        if (pi == null) {
6749            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6750            return;
6751        }
6752
6753        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6754            grantUri.prefix = true;
6755        }
6756        final UriPermission perm = findOrCreateUriPermissionLocked(
6757                pi.packageName, targetPkg, targetUid, grantUri);
6758        perm.grantModes(modeFlags, owner);
6759    }
6760
6761    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6762            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6763        if (targetPkg == null) {
6764            throw new NullPointerException("targetPkg");
6765        }
6766        int targetUid;
6767        final IPackageManager pm = AppGlobals.getPackageManager();
6768        try {
6769            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6770        } catch (RemoteException ex) {
6771            return;
6772        }
6773
6774        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6775                targetUid);
6776        if (targetUid < 0) {
6777            return;
6778        }
6779
6780        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6781                owner);
6782    }
6783
6784    static class NeededUriGrants extends ArrayList<GrantUri> {
6785        final String targetPkg;
6786        final int targetUid;
6787        final int flags;
6788
6789        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6790            this.targetPkg = targetPkg;
6791            this.targetUid = targetUid;
6792            this.flags = flags;
6793        }
6794    }
6795
6796    /**
6797     * Like checkGrantUriPermissionLocked, but takes an Intent.
6798     */
6799    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6800            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6801        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6802                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6803                + " clip=" + (intent != null ? intent.getClipData() : null)
6804                + " from " + intent + "; flags=0x"
6805                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6806
6807        if (targetPkg == null) {
6808            throw new NullPointerException("targetPkg");
6809        }
6810
6811        if (intent == null) {
6812            return null;
6813        }
6814        Uri data = intent.getData();
6815        ClipData clip = intent.getClipData();
6816        if (data == null && clip == null) {
6817            return null;
6818        }
6819        // Default userId for uris in the intent (if they don't specify it themselves)
6820        int contentUserHint = intent.getContentUserHint();
6821        if (contentUserHint == UserHandle.USER_CURRENT) {
6822            contentUserHint = UserHandle.getUserId(callingUid);
6823        }
6824        final IPackageManager pm = AppGlobals.getPackageManager();
6825        int targetUid;
6826        if (needed != null) {
6827            targetUid = needed.targetUid;
6828        } else {
6829            try {
6830                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6831            } catch (RemoteException ex) {
6832                return null;
6833            }
6834            if (targetUid < 0) {
6835                if (DEBUG_URI_PERMISSION) {
6836                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6837                            + " on user " + targetUserId);
6838                }
6839                return null;
6840            }
6841        }
6842        if (data != null) {
6843            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6844            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6845                    targetUid);
6846            if (targetUid > 0) {
6847                if (needed == null) {
6848                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6849                }
6850                needed.add(grantUri);
6851            }
6852        }
6853        if (clip != null) {
6854            for (int i=0; i<clip.getItemCount(); i++) {
6855                Uri uri = clip.getItemAt(i).getUri();
6856                if (uri != null) {
6857                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6858                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6859                            targetUid);
6860                    if (targetUid > 0) {
6861                        if (needed == null) {
6862                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6863                        }
6864                        needed.add(grantUri);
6865                    }
6866                } else {
6867                    Intent clipIntent = clip.getItemAt(i).getIntent();
6868                    if (clipIntent != null) {
6869                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6870                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6871                        if (newNeeded != null) {
6872                            needed = newNeeded;
6873                        }
6874                    }
6875                }
6876            }
6877        }
6878
6879        return needed;
6880    }
6881
6882    /**
6883     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6884     */
6885    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6886            UriPermissionOwner owner) {
6887        if (needed != null) {
6888            for (int i=0; i<needed.size(); i++) {
6889                GrantUri grantUri = needed.get(i);
6890                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6891                        grantUri, needed.flags, owner);
6892            }
6893        }
6894    }
6895
6896    void grantUriPermissionFromIntentLocked(int callingUid,
6897            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6898        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6899                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6900        if (needed == null) {
6901            return;
6902        }
6903
6904        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6905    }
6906
6907    @Override
6908    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6909            final int modeFlags, int userId) {
6910        enforceNotIsolatedCaller("grantUriPermission");
6911        GrantUri grantUri = new GrantUri(userId, uri, false);
6912        synchronized(this) {
6913            final ProcessRecord r = getRecordForAppLocked(caller);
6914            if (r == null) {
6915                throw new SecurityException("Unable to find app for caller "
6916                        + caller
6917                        + " when granting permission to uri " + grantUri);
6918            }
6919            if (targetPkg == null) {
6920                throw new IllegalArgumentException("null target");
6921            }
6922            if (grantUri == null) {
6923                throw new IllegalArgumentException("null uri");
6924            }
6925
6926            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6927                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6928                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6929                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6930
6931            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6932                    UserHandle.getUserId(r.uid));
6933        }
6934    }
6935
6936    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6937        if (perm.modeFlags == 0) {
6938            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6939                    perm.targetUid);
6940            if (perms != null) {
6941                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6942                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6943
6944                perms.remove(perm.uri);
6945                if (perms.isEmpty()) {
6946                    mGrantedUriPermissions.remove(perm.targetUid);
6947                }
6948            }
6949        }
6950    }
6951
6952    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6953        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6954
6955        final IPackageManager pm = AppGlobals.getPackageManager();
6956        final String authority = grantUri.uri.getAuthority();
6957        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6958        if (pi == null) {
6959            Slog.w(TAG, "No content provider found for permission revoke: "
6960                    + grantUri.toSafeString());
6961            return;
6962        }
6963
6964        // Does the caller have this permission on the URI?
6965        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6966            // Right now, if you are not the original owner of the permission,
6967            // you are not allowed to revoke it.
6968            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6969                throw new SecurityException("Uid " + callingUid
6970                        + " does not have permission to uri " + grantUri);
6971            //}
6972        }
6973
6974        boolean persistChanged = false;
6975
6976        // Go through all of the permissions and remove any that match.
6977        int N = mGrantedUriPermissions.size();
6978        for (int i = 0; i < N; i++) {
6979            final int targetUid = mGrantedUriPermissions.keyAt(i);
6980            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6981
6982            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6983                final UriPermission perm = it.next();
6984                if (perm.uri.sourceUserId == grantUri.sourceUserId
6985                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6986                    if (DEBUG_URI_PERMISSION)
6987                        Slog.v(TAG,
6988                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6989                    persistChanged |= perm.revokeModes(
6990                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6991                    if (perm.modeFlags == 0) {
6992                        it.remove();
6993                    }
6994                }
6995            }
6996
6997            if (perms.isEmpty()) {
6998                mGrantedUriPermissions.remove(targetUid);
6999                N--;
7000                i--;
7001            }
7002        }
7003
7004        if (persistChanged) {
7005            schedulePersistUriGrants();
7006        }
7007    }
7008
7009    @Override
7010    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7011            int userId) {
7012        enforceNotIsolatedCaller("revokeUriPermission");
7013        synchronized(this) {
7014            final ProcessRecord r = getRecordForAppLocked(caller);
7015            if (r == null) {
7016                throw new SecurityException("Unable to find app for caller "
7017                        + caller
7018                        + " when revoking permission to uri " + uri);
7019            }
7020            if (uri == null) {
7021                Slog.w(TAG, "revokeUriPermission: null uri");
7022                return;
7023            }
7024
7025            if (!Intent.isAccessUriMode(modeFlags)) {
7026                return;
7027            }
7028
7029            final IPackageManager pm = AppGlobals.getPackageManager();
7030            final String authority = uri.getAuthority();
7031            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7032            if (pi == null) {
7033                Slog.w(TAG, "No content provider found for permission revoke: "
7034                        + uri.toSafeString());
7035                return;
7036            }
7037
7038            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7039        }
7040    }
7041
7042    /**
7043     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7044     * given package.
7045     *
7046     * @param packageName Package name to match, or {@code null} to apply to all
7047     *            packages.
7048     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7049     *            to all users.
7050     * @param persistable If persistable grants should be removed.
7051     */
7052    private void removeUriPermissionsForPackageLocked(
7053            String packageName, int userHandle, boolean persistable) {
7054        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7055            throw new IllegalArgumentException("Must narrow by either package or user");
7056        }
7057
7058        boolean persistChanged = false;
7059
7060        int N = mGrantedUriPermissions.size();
7061        for (int i = 0; i < N; i++) {
7062            final int targetUid = mGrantedUriPermissions.keyAt(i);
7063            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7064
7065            // Only inspect grants matching user
7066            if (userHandle == UserHandle.USER_ALL
7067                    || userHandle == UserHandle.getUserId(targetUid)) {
7068                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7069                    final UriPermission perm = it.next();
7070
7071                    // Only inspect grants matching package
7072                    if (packageName == null || perm.sourcePkg.equals(packageName)
7073                            || perm.targetPkg.equals(packageName)) {
7074                        persistChanged |= perm.revokeModes(
7075                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7076
7077                        // Only remove when no modes remain; any persisted grants
7078                        // will keep this alive.
7079                        if (perm.modeFlags == 0) {
7080                            it.remove();
7081                        }
7082                    }
7083                }
7084
7085                if (perms.isEmpty()) {
7086                    mGrantedUriPermissions.remove(targetUid);
7087                    N--;
7088                    i--;
7089                }
7090            }
7091        }
7092
7093        if (persistChanged) {
7094            schedulePersistUriGrants();
7095        }
7096    }
7097
7098    @Override
7099    public IBinder newUriPermissionOwner(String name) {
7100        enforceNotIsolatedCaller("newUriPermissionOwner");
7101        synchronized(this) {
7102            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7103            return owner.getExternalTokenLocked();
7104        }
7105    }
7106
7107    @Override
7108    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7109            final int modeFlags, int sourceUserId, int targetUserId) {
7110        synchronized(this) {
7111            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7112            if (owner == null) {
7113                throw new IllegalArgumentException("Unknown owner: " + token);
7114            }
7115            if (fromUid != Binder.getCallingUid()) {
7116                if (Binder.getCallingUid() != Process.myUid()) {
7117                    // Only system code can grant URI permissions on behalf
7118                    // of other users.
7119                    throw new SecurityException("nice try");
7120                }
7121            }
7122            if (targetPkg == null) {
7123                throw new IllegalArgumentException("null target");
7124            }
7125            if (uri == null) {
7126                throw new IllegalArgumentException("null uri");
7127            }
7128
7129            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7130                    modeFlags, owner, targetUserId);
7131        }
7132    }
7133
7134    @Override
7135    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7136        synchronized(this) {
7137            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7138            if (owner == null) {
7139                throw new IllegalArgumentException("Unknown owner: " + token);
7140            }
7141
7142            if (uri == null) {
7143                owner.removeUriPermissionsLocked(mode);
7144            } else {
7145                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7146            }
7147        }
7148    }
7149
7150    private void schedulePersistUriGrants() {
7151        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7152            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7153                    10 * DateUtils.SECOND_IN_MILLIS);
7154        }
7155    }
7156
7157    private void writeGrantedUriPermissions() {
7158        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7159
7160        // Snapshot permissions so we can persist without lock
7161        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7162        synchronized (this) {
7163            final int size = mGrantedUriPermissions.size();
7164            for (int i = 0; i < size; i++) {
7165                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7166                for (UriPermission perm : perms.values()) {
7167                    if (perm.persistedModeFlags != 0) {
7168                        persist.add(perm.snapshot());
7169                    }
7170                }
7171            }
7172        }
7173
7174        FileOutputStream fos = null;
7175        try {
7176            fos = mGrantFile.startWrite();
7177
7178            XmlSerializer out = new FastXmlSerializer();
7179            out.setOutput(fos, "utf-8");
7180            out.startDocument(null, true);
7181            out.startTag(null, TAG_URI_GRANTS);
7182            for (UriPermission.Snapshot perm : persist) {
7183                out.startTag(null, TAG_URI_GRANT);
7184                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7185                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7186                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7187                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7188                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7189                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7190                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7191                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7192                out.endTag(null, TAG_URI_GRANT);
7193            }
7194            out.endTag(null, TAG_URI_GRANTS);
7195            out.endDocument();
7196
7197            mGrantFile.finishWrite(fos);
7198        } catch (IOException e) {
7199            if (fos != null) {
7200                mGrantFile.failWrite(fos);
7201            }
7202        }
7203    }
7204
7205    private void readGrantedUriPermissionsLocked() {
7206        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7207
7208        final long now = System.currentTimeMillis();
7209
7210        FileInputStream fis = null;
7211        try {
7212            fis = mGrantFile.openRead();
7213            final XmlPullParser in = Xml.newPullParser();
7214            in.setInput(fis, null);
7215
7216            int type;
7217            while ((type = in.next()) != END_DOCUMENT) {
7218                final String tag = in.getName();
7219                if (type == START_TAG) {
7220                    if (TAG_URI_GRANT.equals(tag)) {
7221                        final int sourceUserId;
7222                        final int targetUserId;
7223                        final int userHandle = readIntAttribute(in,
7224                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7225                        if (userHandle != UserHandle.USER_NULL) {
7226                            // For backwards compatibility.
7227                            sourceUserId = userHandle;
7228                            targetUserId = userHandle;
7229                        } else {
7230                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7231                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7232                        }
7233                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7234                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7235                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7236                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7237                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7238                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7239
7240                        // Sanity check that provider still belongs to source package
7241                        final ProviderInfo pi = getProviderInfoLocked(
7242                                uri.getAuthority(), sourceUserId);
7243                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7244                            int targetUid = -1;
7245                            try {
7246                                targetUid = AppGlobals.getPackageManager()
7247                                        .getPackageUid(targetPkg, targetUserId);
7248                            } catch (RemoteException e) {
7249                            }
7250                            if (targetUid != -1) {
7251                                final UriPermission perm = findOrCreateUriPermissionLocked(
7252                                        sourcePkg, targetPkg, targetUid,
7253                                        new GrantUri(sourceUserId, uri, prefix));
7254                                perm.initPersistedModes(modeFlags, createdTime);
7255                            }
7256                        } else {
7257                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7258                                    + " but instead found " + pi);
7259                        }
7260                    }
7261                }
7262            }
7263        } catch (FileNotFoundException e) {
7264            // Missing grants is okay
7265        } catch (IOException e) {
7266            Log.wtf(TAG, "Failed reading Uri grants", e);
7267        } catch (XmlPullParserException e) {
7268            Log.wtf(TAG, "Failed reading Uri grants", e);
7269        } finally {
7270            IoUtils.closeQuietly(fis);
7271        }
7272    }
7273
7274    @Override
7275    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7276        enforceNotIsolatedCaller("takePersistableUriPermission");
7277
7278        Preconditions.checkFlagsArgument(modeFlags,
7279                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7280
7281        synchronized (this) {
7282            final int callingUid = Binder.getCallingUid();
7283            boolean persistChanged = false;
7284            GrantUri grantUri = new GrantUri(userId, uri, false);
7285
7286            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7287                    new GrantUri(userId, uri, false));
7288            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7289                    new GrantUri(userId, uri, true));
7290
7291            final boolean exactValid = (exactPerm != null)
7292                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7293            final boolean prefixValid = (prefixPerm != null)
7294                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7295
7296            if (!(exactValid || prefixValid)) {
7297                throw new SecurityException("No persistable permission grants found for UID "
7298                        + callingUid + " and Uri " + grantUri.toSafeString());
7299            }
7300
7301            if (exactValid) {
7302                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7303            }
7304            if (prefixValid) {
7305                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7306            }
7307
7308            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7309
7310            if (persistChanged) {
7311                schedulePersistUriGrants();
7312            }
7313        }
7314    }
7315
7316    @Override
7317    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7318        enforceNotIsolatedCaller("releasePersistableUriPermission");
7319
7320        Preconditions.checkFlagsArgument(modeFlags,
7321                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7322
7323        synchronized (this) {
7324            final int callingUid = Binder.getCallingUid();
7325            boolean persistChanged = false;
7326
7327            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7328                    new GrantUri(userId, uri, false));
7329            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7330                    new GrantUri(userId, uri, true));
7331            if (exactPerm == null && prefixPerm == null) {
7332                throw new SecurityException("No permission grants found for UID " + callingUid
7333                        + " and Uri " + uri.toSafeString());
7334            }
7335
7336            if (exactPerm != null) {
7337                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7338                removeUriPermissionIfNeededLocked(exactPerm);
7339            }
7340            if (prefixPerm != null) {
7341                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7342                removeUriPermissionIfNeededLocked(prefixPerm);
7343            }
7344
7345            if (persistChanged) {
7346                schedulePersistUriGrants();
7347            }
7348        }
7349    }
7350
7351    /**
7352     * Prune any older {@link UriPermission} for the given UID until outstanding
7353     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7354     *
7355     * @return if any mutations occured that require persisting.
7356     */
7357    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7358        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7359        if (perms == null) return false;
7360        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7361
7362        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7363        for (UriPermission perm : perms.values()) {
7364            if (perm.persistedModeFlags != 0) {
7365                persisted.add(perm);
7366            }
7367        }
7368
7369        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7370        if (trimCount <= 0) return false;
7371
7372        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7373        for (int i = 0; i < trimCount; i++) {
7374            final UriPermission perm = persisted.get(i);
7375
7376            if (DEBUG_URI_PERMISSION) {
7377                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7378            }
7379
7380            perm.releasePersistableModes(~0);
7381            removeUriPermissionIfNeededLocked(perm);
7382        }
7383
7384        return true;
7385    }
7386
7387    @Override
7388    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7389            String packageName, boolean incoming) {
7390        enforceNotIsolatedCaller("getPersistedUriPermissions");
7391        Preconditions.checkNotNull(packageName, "packageName");
7392
7393        final int callingUid = Binder.getCallingUid();
7394        final IPackageManager pm = AppGlobals.getPackageManager();
7395        try {
7396            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7397            if (packageUid != callingUid) {
7398                throw new SecurityException(
7399                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7400            }
7401        } catch (RemoteException e) {
7402            throw new SecurityException("Failed to verify package name ownership");
7403        }
7404
7405        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7406        synchronized (this) {
7407            if (incoming) {
7408                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7409                        callingUid);
7410                if (perms == null) {
7411                    Slog.w(TAG, "No permission grants found for " + packageName);
7412                } else {
7413                    for (UriPermission perm : perms.values()) {
7414                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7415                            result.add(perm.buildPersistedPublicApiObject());
7416                        }
7417                    }
7418                }
7419            } else {
7420                final int size = mGrantedUriPermissions.size();
7421                for (int i = 0; i < size; i++) {
7422                    final ArrayMap<GrantUri, UriPermission> perms =
7423                            mGrantedUriPermissions.valueAt(i);
7424                    for (UriPermission perm : perms.values()) {
7425                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7426                            result.add(perm.buildPersistedPublicApiObject());
7427                        }
7428                    }
7429                }
7430            }
7431        }
7432        return new ParceledListSlice<android.content.UriPermission>(result);
7433    }
7434
7435    @Override
7436    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7437        synchronized (this) {
7438            ProcessRecord app =
7439                who != null ? getRecordForAppLocked(who) : null;
7440            if (app == null) return;
7441
7442            Message msg = Message.obtain();
7443            msg.what = WAIT_FOR_DEBUGGER_MSG;
7444            msg.obj = app;
7445            msg.arg1 = waiting ? 1 : 0;
7446            mHandler.sendMessage(msg);
7447        }
7448    }
7449
7450    @Override
7451    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7452        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7453        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7454        outInfo.availMem = Process.getFreeMemory();
7455        outInfo.totalMem = Process.getTotalMemory();
7456        outInfo.threshold = homeAppMem;
7457        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7458        outInfo.hiddenAppThreshold = cachedAppMem;
7459        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7460                ProcessList.SERVICE_ADJ);
7461        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7462                ProcessList.VISIBLE_APP_ADJ);
7463        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7464                ProcessList.FOREGROUND_APP_ADJ);
7465    }
7466
7467    // =========================================================
7468    // TASK MANAGEMENT
7469    // =========================================================
7470
7471    @Override
7472    public List<IAppTask> getAppTasks() {
7473        final PackageManager pm = mContext.getPackageManager();
7474        int callingUid = Binder.getCallingUid();
7475        long ident = Binder.clearCallingIdentity();
7476
7477        // Compose the list of packages for this id to test against
7478        HashSet<String> packages = new HashSet<String>();
7479        String[] uidPackages = pm.getPackagesForUid(callingUid);
7480        for (int i = 0; i < uidPackages.length; i++) {
7481            packages.add(uidPackages[i]);
7482        }
7483
7484        synchronized(this) {
7485            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7486            try {
7487                if (localLOGV) Slog.v(TAG, "getAppTasks");
7488
7489                final int N = mRecentTasks.size();
7490                for (int i = 0; i < N; i++) {
7491                    TaskRecord tr = mRecentTasks.get(i);
7492                    // Skip tasks that do not match the package name
7493                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7494                        ActivityManager.RecentTaskInfo taskInfo =
7495                                createRecentTaskInfoFromTaskRecord(tr);
7496                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7497                        list.add(taskImpl);
7498                    }
7499                }
7500            } finally {
7501                Binder.restoreCallingIdentity(ident);
7502            }
7503            return list;
7504        }
7505    }
7506
7507    @Override
7508    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7509        final int callingUid = Binder.getCallingUid();
7510        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7511
7512        synchronized(this) {
7513            if (localLOGV) Slog.v(
7514                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7515
7516            final boolean allowed = checkCallingPermission(
7517                    android.Manifest.permission.GET_TASKS)
7518                    == PackageManager.PERMISSION_GRANTED;
7519            if (!allowed) {
7520                Slog.w(TAG, "getTasks: caller " + callingUid
7521                        + " does not hold GET_TASKS; limiting output");
7522            }
7523
7524            // TODO: Improve with MRU list from all ActivityStacks.
7525            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7526        }
7527
7528        return list;
7529    }
7530
7531    TaskRecord getMostRecentTask() {
7532        return mRecentTasks.get(0);
7533    }
7534
7535    /**
7536     * Creates a new RecentTaskInfo from a TaskRecord.
7537     */
7538    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7539        // Update the task description to reflect any changes in the task stack
7540        tr.updateTaskDescription();
7541
7542        // Compose the recent task info
7543        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7544        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7545        rti.persistentId = tr.taskId;
7546        rti.baseIntent = new Intent(tr.getBaseIntent());
7547        rti.origActivity = tr.origActivity;
7548        rti.description = tr.lastDescription;
7549        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7550        rti.userId = tr.userId;
7551        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7552        rti.firstActiveTime = tr.firstActiveTime;
7553        rti.lastActiveTime = tr.lastActiveTime;
7554        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7555        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
7556        return rti;
7557    }
7558
7559    @Override
7560    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7561        final int callingUid = Binder.getCallingUid();
7562        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7563                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7564
7565        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7566        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7567        synchronized (this) {
7568            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7569                    == PackageManager.PERMISSION_GRANTED;
7570            if (!allowed) {
7571                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7572                        + " does not hold GET_TASKS; limiting output");
7573            }
7574            final boolean detailed = checkCallingPermission(
7575                    android.Manifest.permission.GET_DETAILED_TASKS)
7576                    == PackageManager.PERMISSION_GRANTED;
7577
7578            IPackageManager pm = AppGlobals.getPackageManager();
7579
7580            final int N = mRecentTasks.size();
7581            ArrayList<ActivityManager.RecentTaskInfo> res
7582                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7583                            maxNum < N ? maxNum : N);
7584
7585            final Set<Integer> includedUsers;
7586            if (includeProfiles) {
7587                includedUsers = getProfileIdsLocked(userId);
7588            } else {
7589                includedUsers = new HashSet<Integer>();
7590            }
7591            includedUsers.add(Integer.valueOf(userId));
7592
7593            // Regroup affiliated tasks together.
7594            for (int i = 0; i < N; ) {
7595                TaskRecord task = mRecentTasks.remove(i);
7596                if (mTmpRecents.contains(task)) {
7597                    continue;
7598                }
7599                int affiliatedTaskId = task.mAffiliatedTaskId;
7600                while (true) {
7601                    TaskRecord next = task.mNextAffiliate;
7602                    if (next == null) {
7603                        break;
7604                    }
7605                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7606                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7607                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7608                        task.setNextAffiliate(null);
7609                        if (next.mPrevAffiliate == task) {
7610                            next.setPrevAffiliate(null);
7611                        }
7612                        break;
7613                    }
7614                    if (next.mPrevAffiliate != task) {
7615                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7616                                next.mPrevAffiliate + " task=" + task);
7617                        next.setPrevAffiliate(null);
7618                        break;
7619                    }
7620                    if (!mRecentTasks.contains(next)) {
7621                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7622                        task.setNextAffiliate(null);
7623                        if (next.mPrevAffiliate == task) {
7624                            next.setPrevAffiliate(null);
7625                        }
7626                        break;
7627                    }
7628                    task = next;
7629                }
7630                // task is now the end of the list
7631                do {
7632                    mRecentTasks.remove(task);
7633                    mRecentTasks.add(i++, task);
7634                    mTmpRecents.add(task);
7635                } while ((task = task.mPrevAffiliate) != null);
7636            }
7637            mTmpRecents.clear();
7638            // mRecentTasks is now in sorted, affiliated order.
7639
7640            for (int i=0; i<N && maxNum > 0; i++) {
7641                TaskRecord tr = mRecentTasks.get(i);
7642                // Only add calling user or related users recent tasks
7643                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7644
7645                // Return the entry if desired by the caller.  We always return
7646                // the first entry, because callers always expect this to be the
7647                // foreground app.  We may filter others if the caller has
7648                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7649                // we should exclude the entry.
7650
7651                if (i == 0
7652                        || withExcluded
7653                        || (tr.intent == null)
7654                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7655                                == 0)) {
7656                    if (!allowed) {
7657                        // If the caller doesn't have the GET_TASKS permission, then only
7658                        // allow them to see a small subset of tasks -- their own and home.
7659                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7660                            continue;
7661                        }
7662                    }
7663                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7664                        // Don't include auto remove tasks that are finished or finishing.
7665                        continue;
7666                    }
7667
7668                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7669                    if (!detailed) {
7670                        rti.baseIntent.replaceExtras((Bundle)null);
7671                    }
7672
7673                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7674                        // Check whether this activity is currently available.
7675                        try {
7676                            if (rti.origActivity != null) {
7677                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7678                                        == null) {
7679                                    continue;
7680                                }
7681                            } else if (rti.baseIntent != null) {
7682                                if (pm.queryIntentActivities(rti.baseIntent,
7683                                        null, 0, userId) == null) {
7684                                    continue;
7685                                }
7686                            }
7687                        } catch (RemoteException e) {
7688                            // Will never happen.
7689                        }
7690                    }
7691
7692                    res.add(rti);
7693                    maxNum--;
7694                }
7695            }
7696            return res;
7697        }
7698    }
7699
7700    private TaskRecord recentTaskForIdLocked(int id) {
7701        final int N = mRecentTasks.size();
7702            for (int i=0; i<N; i++) {
7703                TaskRecord tr = mRecentTasks.get(i);
7704                if (tr.taskId == id) {
7705                    return tr;
7706                }
7707            }
7708            return null;
7709    }
7710
7711    @Override
7712    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7713        synchronized (this) {
7714            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7715                    "getTaskThumbnail()");
7716            TaskRecord tr = recentTaskForIdLocked(id);
7717            if (tr != null) {
7718                return tr.getTaskThumbnailLocked();
7719            }
7720        }
7721        return null;
7722    }
7723
7724    @Override
7725    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7726        synchronized (this) {
7727            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7728            if (r != null) {
7729                r.taskDescription = td;
7730                r.task.updateTaskDescription();
7731            }
7732        }
7733    }
7734
7735    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7736        if (!pr.killedByAm) {
7737            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7738            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7739                    pr.processName, pr.setAdj, reason);
7740            pr.killedByAm = true;
7741            Process.killProcessQuiet(pr.pid);
7742            Process.killProcessGroup(pr.info.uid, pr.pid);
7743        }
7744    }
7745
7746    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7747        tr.disposeThumbnail();
7748        mRecentTasks.remove(tr);
7749        tr.closeRecentsChain();
7750        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7751        Intent baseIntent = new Intent(
7752                tr.intent != null ? tr.intent : tr.affinityIntent);
7753        ComponentName component = baseIntent.getComponent();
7754        if (component == null) {
7755            Slog.w(TAG, "Now component for base intent of task: " + tr);
7756            return;
7757        }
7758
7759        // Find any running services associated with this app.
7760        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7761
7762        if (killProcesses) {
7763            // Find any running processes associated with this app.
7764            final String pkg = component.getPackageName();
7765            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7766            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7767            for (int i=0; i<pmap.size(); i++) {
7768                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7769                for (int j=0; j<uids.size(); j++) {
7770                    ProcessRecord proc = uids.valueAt(j);
7771                    if (proc.userId != tr.userId) {
7772                        continue;
7773                    }
7774                    if (!proc.pkgList.containsKey(pkg)) {
7775                        continue;
7776                    }
7777                    procs.add(proc);
7778                }
7779            }
7780
7781            // Kill the running processes.
7782            for (int i=0; i<procs.size(); i++) {
7783                ProcessRecord pr = procs.get(i);
7784                if (pr == mHomeProcess) {
7785                    // Don't kill the home process along with tasks from the same package.
7786                    continue;
7787                }
7788                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7789                    killUnneededProcessLocked(pr, "remove task");
7790                } else {
7791                    pr.waitingToKill = "remove task";
7792                }
7793            }
7794        }
7795    }
7796
7797    /**
7798     * Removes the task with the specified task id.
7799     *
7800     * @param taskId Identifier of the task to be removed.
7801     * @param flags Additional operational flags.  May be 0 or
7802     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7803     * @return Returns true if the given task was found and removed.
7804     */
7805    private boolean removeTaskByIdLocked(int taskId, int flags) {
7806        TaskRecord tr = recentTaskForIdLocked(taskId);
7807        if (tr != null) {
7808            tr.removeTaskActivitiesLocked();
7809            cleanUpRemovedTaskLocked(tr, flags);
7810            if (tr.isPersistable) {
7811                notifyTaskPersisterLocked(null, true);
7812            }
7813            return true;
7814        }
7815        return false;
7816    }
7817
7818    @Override
7819    public boolean removeTask(int taskId, int flags) {
7820        synchronized (this) {
7821            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7822                    "removeTask()");
7823            long ident = Binder.clearCallingIdentity();
7824            try {
7825                return removeTaskByIdLocked(taskId, flags);
7826            } finally {
7827                Binder.restoreCallingIdentity(ident);
7828            }
7829        }
7830    }
7831
7832    /**
7833     * TODO: Add mController hook
7834     */
7835    @Override
7836    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7837        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7838                "moveTaskToFront()");
7839
7840        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7841        synchronized(this) {
7842            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7843                    Binder.getCallingUid(), "Task to front")) {
7844                ActivityOptions.abort(options);
7845                return;
7846            }
7847            final long origId = Binder.clearCallingIdentity();
7848            try {
7849                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7850                if (task == null) {
7851                    return;
7852                }
7853                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7854                    mStackSupervisor.showLockTaskToast();
7855                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7856                    return;
7857                }
7858                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7859                if (prev != null && prev.isRecentsActivity()) {
7860                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7861                }
7862                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7863            } finally {
7864                Binder.restoreCallingIdentity(origId);
7865            }
7866            ActivityOptions.abort(options);
7867        }
7868    }
7869
7870    @Override
7871    public void moveTaskToBack(int taskId) {
7872        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7873                "moveTaskToBack()");
7874
7875        synchronized(this) {
7876            TaskRecord tr = recentTaskForIdLocked(taskId);
7877            if (tr != null) {
7878                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7879                ActivityStack stack = tr.stack;
7880                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7881                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7882                            Binder.getCallingUid(), "Task to back")) {
7883                        return;
7884                    }
7885                }
7886                final long origId = Binder.clearCallingIdentity();
7887                try {
7888                    stack.moveTaskToBackLocked(taskId, null);
7889                } finally {
7890                    Binder.restoreCallingIdentity(origId);
7891                }
7892            }
7893        }
7894    }
7895
7896    /**
7897     * Moves an activity, and all of the other activities within the same task, to the bottom
7898     * of the history stack.  The activity's order within the task is unchanged.
7899     *
7900     * @param token A reference to the activity we wish to move
7901     * @param nonRoot If false then this only works if the activity is the root
7902     *                of a task; if true it will work for any activity in a task.
7903     * @return Returns true if the move completed, false if not.
7904     */
7905    @Override
7906    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7907        enforceNotIsolatedCaller("moveActivityTaskToBack");
7908        synchronized(this) {
7909            final long origId = Binder.clearCallingIdentity();
7910            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7911            if (taskId >= 0) {
7912                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7913            }
7914            Binder.restoreCallingIdentity(origId);
7915        }
7916        return false;
7917    }
7918
7919    @Override
7920    public void moveTaskBackwards(int task) {
7921        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7922                "moveTaskBackwards()");
7923
7924        synchronized(this) {
7925            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7926                    Binder.getCallingUid(), "Task backwards")) {
7927                return;
7928            }
7929            final long origId = Binder.clearCallingIdentity();
7930            moveTaskBackwardsLocked(task);
7931            Binder.restoreCallingIdentity(origId);
7932        }
7933    }
7934
7935    private final void moveTaskBackwardsLocked(int task) {
7936        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7937    }
7938
7939    @Override
7940    public IBinder getHomeActivityToken() throws RemoteException {
7941        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7942                "getHomeActivityToken()");
7943        synchronized (this) {
7944            return mStackSupervisor.getHomeActivityToken();
7945        }
7946    }
7947
7948    @Override
7949    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7950            IActivityContainerCallback callback) throws RemoteException {
7951        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7952                "createActivityContainer()");
7953        synchronized (this) {
7954            if (parentActivityToken == null) {
7955                throw new IllegalArgumentException("parent token must not be null");
7956            }
7957            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7958            if (r == null) {
7959                return null;
7960            }
7961            if (callback == null) {
7962                throw new IllegalArgumentException("callback must not be null");
7963            }
7964            return mStackSupervisor.createActivityContainer(r, callback);
7965        }
7966    }
7967
7968    @Override
7969    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7970        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7971                "deleteActivityContainer()");
7972        synchronized (this) {
7973            mStackSupervisor.deleteActivityContainer(container);
7974        }
7975    }
7976
7977    @Override
7978    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7979            throws RemoteException {
7980        synchronized (this) {
7981            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7982            if (stack != null) {
7983                return stack.mActivityContainer;
7984            }
7985            return null;
7986        }
7987    }
7988
7989    @Override
7990    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7991        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7992                "moveTaskToStack()");
7993        if (stackId == HOME_STACK_ID) {
7994            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7995                    new RuntimeException("here").fillInStackTrace());
7996        }
7997        synchronized (this) {
7998            long ident = Binder.clearCallingIdentity();
7999            try {
8000                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8001                        + stackId + " toTop=" + toTop);
8002                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8003            } finally {
8004                Binder.restoreCallingIdentity(ident);
8005            }
8006        }
8007    }
8008
8009    @Override
8010    public void resizeStack(int stackBoxId, Rect bounds) {
8011        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8012                "resizeStackBox()");
8013        long ident = Binder.clearCallingIdentity();
8014        try {
8015            mWindowManager.resizeStack(stackBoxId, bounds);
8016        } finally {
8017            Binder.restoreCallingIdentity(ident);
8018        }
8019    }
8020
8021    @Override
8022    public List<StackInfo> getAllStackInfos() {
8023        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8024                "getAllStackInfos()");
8025        long ident = Binder.clearCallingIdentity();
8026        try {
8027            synchronized (this) {
8028                return mStackSupervisor.getAllStackInfosLocked();
8029            }
8030        } finally {
8031            Binder.restoreCallingIdentity(ident);
8032        }
8033    }
8034
8035    @Override
8036    public StackInfo getStackInfo(int stackId) {
8037        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8038                "getStackInfo()");
8039        long ident = Binder.clearCallingIdentity();
8040        try {
8041            synchronized (this) {
8042                return mStackSupervisor.getStackInfoLocked(stackId);
8043            }
8044        } finally {
8045            Binder.restoreCallingIdentity(ident);
8046        }
8047    }
8048
8049    @Override
8050    public boolean isInHomeStack(int taskId) {
8051        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8052                "getStackInfo()");
8053        long ident = Binder.clearCallingIdentity();
8054        try {
8055            synchronized (this) {
8056                TaskRecord tr = recentTaskForIdLocked(taskId);
8057                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8058            }
8059        } finally {
8060            Binder.restoreCallingIdentity(ident);
8061        }
8062    }
8063
8064    @Override
8065    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8066        synchronized(this) {
8067            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8068        }
8069    }
8070
8071    private boolean isLockTaskAuthorized(String pkg) {
8072        final DevicePolicyManager dpm = (DevicePolicyManager)
8073                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8074        try {
8075            int uid = mContext.getPackageManager().getPackageUid(pkg,
8076                    Binder.getCallingUserHandle().getIdentifier());
8077            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8078        } catch (NameNotFoundException e) {
8079            return false;
8080        }
8081    }
8082
8083    void startLockTaskMode(TaskRecord task) {
8084        final String pkg;
8085        synchronized (this) {
8086            pkg = task.intent.getComponent().getPackageName();
8087        }
8088        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8089        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8090            final TaskRecord taskRecord = task;
8091            mHandler.post(new Runnable() {
8092                @Override
8093                public void run() {
8094                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8095                }
8096            });
8097            return;
8098        }
8099        long ident = Binder.clearCallingIdentity();
8100        try {
8101            synchronized (this) {
8102                // Since we lost lock on task, make sure it is still there.
8103                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8104                if (task != null) {
8105                    if (!isSystemInitiated
8106                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8107                        throw new IllegalArgumentException("Invalid task, not in foreground");
8108                    }
8109                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8110                }
8111            }
8112        } finally {
8113            Binder.restoreCallingIdentity(ident);
8114        }
8115    }
8116
8117    @Override
8118    public void startLockTaskMode(int taskId) {
8119        final TaskRecord task;
8120        long ident = Binder.clearCallingIdentity();
8121        try {
8122            synchronized (this) {
8123                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8124            }
8125        } finally {
8126            Binder.restoreCallingIdentity(ident);
8127        }
8128        if (task != null) {
8129            startLockTaskMode(task);
8130        }
8131    }
8132
8133    @Override
8134    public void startLockTaskMode(IBinder token) {
8135        final TaskRecord task;
8136        long ident = Binder.clearCallingIdentity();
8137        try {
8138            synchronized (this) {
8139                final ActivityRecord r = ActivityRecord.forToken(token);
8140                if (r == null) {
8141                    return;
8142                }
8143                task = r.task;
8144            }
8145        } finally {
8146            Binder.restoreCallingIdentity(ident);
8147        }
8148        if (task != null) {
8149            startLockTaskMode(task);
8150        }
8151    }
8152
8153    @Override
8154    public void startLockTaskModeOnCurrent() throws RemoteException {
8155        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8156        ActivityRecord r = null;
8157        synchronized (this) {
8158            r = mStackSupervisor.topRunningActivityLocked();
8159        }
8160        startLockTaskMode(r.task);
8161    }
8162
8163    @Override
8164    public void stopLockTaskMode() {
8165        // Verify that the user matches the package of the intent for the TaskRecord
8166        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8167        // and stopLockTaskMode.
8168        final int callingUid = Binder.getCallingUid();
8169        if (callingUid != Process.SYSTEM_UID) {
8170            try {
8171                String pkg =
8172                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8173                int uid = mContext.getPackageManager().getPackageUid(pkg,
8174                        Binder.getCallingUserHandle().getIdentifier());
8175                if (uid != callingUid) {
8176                    throw new SecurityException("Invalid uid, expected " + uid);
8177                }
8178            } catch (NameNotFoundException e) {
8179                Log.d(TAG, "stopLockTaskMode " + e);
8180                return;
8181            }
8182        }
8183        long ident = Binder.clearCallingIdentity();
8184        try {
8185            Log.d(TAG, "stopLockTaskMode");
8186            // Stop lock task
8187            synchronized (this) {
8188                mStackSupervisor.setLockTaskModeLocked(null, false);
8189            }
8190        } finally {
8191            Binder.restoreCallingIdentity(ident);
8192        }
8193    }
8194
8195    @Override
8196    public void stopLockTaskModeOnCurrent() throws RemoteException {
8197        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8198        long ident = Binder.clearCallingIdentity();
8199        try {
8200            stopLockTaskMode();
8201        } finally {
8202            Binder.restoreCallingIdentity(ident);
8203        }
8204    }
8205
8206    @Override
8207    public boolean isInLockTaskMode() {
8208        synchronized (this) {
8209            return mStackSupervisor.isInLockTaskMode();
8210        }
8211    }
8212
8213    // =========================================================
8214    // CONTENT PROVIDERS
8215    // =========================================================
8216
8217    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8218        List<ProviderInfo> providers = null;
8219        try {
8220            providers = AppGlobals.getPackageManager().
8221                queryContentProviders(app.processName, app.uid,
8222                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8223        } catch (RemoteException ex) {
8224        }
8225        if (DEBUG_MU)
8226            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8227        int userId = app.userId;
8228        if (providers != null) {
8229            int N = providers.size();
8230            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8231            for (int i=0; i<N; i++) {
8232                ProviderInfo cpi =
8233                    (ProviderInfo)providers.get(i);
8234                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8235                        cpi.name, cpi.flags);
8236                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8237                    // This is a singleton provider, but a user besides the
8238                    // default user is asking to initialize a process it runs
8239                    // in...  well, no, it doesn't actually run in this process,
8240                    // it runs in the process of the default user.  Get rid of it.
8241                    providers.remove(i);
8242                    N--;
8243                    i--;
8244                    continue;
8245                }
8246
8247                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8248                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8249                if (cpr == null) {
8250                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8251                    mProviderMap.putProviderByClass(comp, cpr);
8252                }
8253                if (DEBUG_MU)
8254                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8255                app.pubProviders.put(cpi.name, cpr);
8256                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8257                    // Don't add this if it is a platform component that is marked
8258                    // to run in multiple processes, because this is actually
8259                    // part of the framework so doesn't make sense to track as a
8260                    // separate apk in the process.
8261                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8262                            mProcessStats);
8263                }
8264                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8265            }
8266        }
8267        return providers;
8268    }
8269
8270    /**
8271     * Check if {@link ProcessRecord} has a possible chance at accessing the
8272     * given {@link ProviderInfo}. Final permission checking is always done
8273     * in {@link ContentProvider}.
8274     */
8275    private final String checkContentProviderPermissionLocked(
8276            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8277        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8278        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8279        boolean checkedGrants = false;
8280        if (checkUser) {
8281            // Looking for cross-user grants before enforcing the typical cross-users permissions
8282            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8283            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8284                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8285                    return null;
8286                }
8287                checkedGrants = true;
8288            }
8289            userId = handleIncomingUser(callingPid, callingUid, userId,
8290                    false, ALLOW_NON_FULL,
8291                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8292            if (userId != tmpTargetUserId) {
8293                // When we actually went to determine the final targer user ID, this ended
8294                // up different than our initial check for the authority.  This is because
8295                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8296                // SELF.  So we need to re-check the grants again.
8297                checkedGrants = false;
8298            }
8299        }
8300        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8301                cpi.applicationInfo.uid, cpi.exported)
8302                == PackageManager.PERMISSION_GRANTED) {
8303            return null;
8304        }
8305        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8306                cpi.applicationInfo.uid, cpi.exported)
8307                == PackageManager.PERMISSION_GRANTED) {
8308            return null;
8309        }
8310
8311        PathPermission[] pps = cpi.pathPermissions;
8312        if (pps != null) {
8313            int i = pps.length;
8314            while (i > 0) {
8315                i--;
8316                PathPermission pp = pps[i];
8317                String pprperm = pp.getReadPermission();
8318                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8319                        cpi.applicationInfo.uid, cpi.exported)
8320                        == PackageManager.PERMISSION_GRANTED) {
8321                    return null;
8322                }
8323                String ppwperm = pp.getWritePermission();
8324                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8325                        cpi.applicationInfo.uid, cpi.exported)
8326                        == PackageManager.PERMISSION_GRANTED) {
8327                    return null;
8328                }
8329            }
8330        }
8331        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8332            return null;
8333        }
8334
8335        String msg;
8336        if (!cpi.exported) {
8337            msg = "Permission Denial: opening provider " + cpi.name
8338                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8339                    + ", uid=" + callingUid + ") that is not exported from uid "
8340                    + cpi.applicationInfo.uid;
8341        } else {
8342            msg = "Permission Denial: opening provider " + cpi.name
8343                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8344                    + ", uid=" + callingUid + ") requires "
8345                    + cpi.readPermission + " or " + cpi.writePermission;
8346        }
8347        Slog.w(TAG, msg);
8348        return msg;
8349    }
8350
8351    /**
8352     * Returns if the ContentProvider has granted a uri to callingUid
8353     */
8354    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8355        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8356        if (perms != null) {
8357            for (int i=perms.size()-1; i>=0; i--) {
8358                GrantUri grantUri = perms.keyAt(i);
8359                if (grantUri.sourceUserId == userId || !checkUser) {
8360                    if (matchesProvider(grantUri.uri, cpi)) {
8361                        return true;
8362                    }
8363                }
8364            }
8365        }
8366        return false;
8367    }
8368
8369    /**
8370     * Returns true if the uri authority is one of the authorities specified in the provider.
8371     */
8372    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8373        String uriAuth = uri.getAuthority();
8374        String cpiAuth = cpi.authority;
8375        if (cpiAuth.indexOf(';') == -1) {
8376            return cpiAuth.equals(uriAuth);
8377        }
8378        String[] cpiAuths = cpiAuth.split(";");
8379        int length = cpiAuths.length;
8380        for (int i = 0; i < length; i++) {
8381            if (cpiAuths[i].equals(uriAuth)) return true;
8382        }
8383        return false;
8384    }
8385
8386    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8387            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8388        if (r != null) {
8389            for (int i=0; i<r.conProviders.size(); i++) {
8390                ContentProviderConnection conn = r.conProviders.get(i);
8391                if (conn.provider == cpr) {
8392                    if (DEBUG_PROVIDER) Slog.v(TAG,
8393                            "Adding provider requested by "
8394                            + r.processName + " from process "
8395                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8396                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8397                    if (stable) {
8398                        conn.stableCount++;
8399                        conn.numStableIncs++;
8400                    } else {
8401                        conn.unstableCount++;
8402                        conn.numUnstableIncs++;
8403                    }
8404                    return conn;
8405                }
8406            }
8407            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8408            if (stable) {
8409                conn.stableCount = 1;
8410                conn.numStableIncs = 1;
8411            } else {
8412                conn.unstableCount = 1;
8413                conn.numUnstableIncs = 1;
8414            }
8415            cpr.connections.add(conn);
8416            r.conProviders.add(conn);
8417            return conn;
8418        }
8419        cpr.addExternalProcessHandleLocked(externalProcessToken);
8420        return null;
8421    }
8422
8423    boolean decProviderCountLocked(ContentProviderConnection conn,
8424            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8425        if (conn != null) {
8426            cpr = conn.provider;
8427            if (DEBUG_PROVIDER) Slog.v(TAG,
8428                    "Removing provider requested by "
8429                    + conn.client.processName + " from process "
8430                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8431                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8432            if (stable) {
8433                conn.stableCount--;
8434            } else {
8435                conn.unstableCount--;
8436            }
8437            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8438                cpr.connections.remove(conn);
8439                conn.client.conProviders.remove(conn);
8440                return true;
8441            }
8442            return false;
8443        }
8444        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8445        return false;
8446    }
8447
8448    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8449            String name, IBinder token, boolean stable, int userId) {
8450        ContentProviderRecord cpr;
8451        ContentProviderConnection conn = null;
8452        ProviderInfo cpi = null;
8453
8454        synchronized(this) {
8455            ProcessRecord r = null;
8456            if (caller != null) {
8457                r = getRecordForAppLocked(caller);
8458                if (r == null) {
8459                    throw new SecurityException(
8460                            "Unable to find app for caller " + caller
8461                          + " (pid=" + Binder.getCallingPid()
8462                          + ") when getting content provider " + name);
8463                }
8464            }
8465
8466            boolean checkCrossUser = true;
8467
8468            // First check if this content provider has been published...
8469            cpr = mProviderMap.getProviderByName(name, userId);
8470            // If that didn't work, check if it exists for user 0 and then
8471            // verify that it's a singleton provider before using it.
8472            if (cpr == null && userId != UserHandle.USER_OWNER) {
8473                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8474                if (cpr != null) {
8475                    cpi = cpr.info;
8476                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8477                            cpi.name, cpi.flags)
8478                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8479                        userId = UserHandle.USER_OWNER;
8480                        checkCrossUser = false;
8481                    } else {
8482                        cpr = null;
8483                        cpi = null;
8484                    }
8485                }
8486            }
8487
8488            boolean providerRunning = cpr != null;
8489            if (providerRunning) {
8490                cpi = cpr.info;
8491                String msg;
8492                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8493                        != null) {
8494                    throw new SecurityException(msg);
8495                }
8496
8497                if (r != null && cpr.canRunHere(r)) {
8498                    // This provider has been published or is in the process
8499                    // of being published...  but it is also allowed to run
8500                    // in the caller's process, so don't make a connection
8501                    // and just let the caller instantiate its own instance.
8502                    ContentProviderHolder holder = cpr.newHolder(null);
8503                    // don't give caller the provider object, it needs
8504                    // to make its own.
8505                    holder.provider = null;
8506                    return holder;
8507                }
8508
8509                final long origId = Binder.clearCallingIdentity();
8510
8511                // In this case the provider instance already exists, so we can
8512                // return it right away.
8513                conn = incProviderCountLocked(r, cpr, token, stable);
8514                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8515                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8516                        // If this is a perceptible app accessing the provider,
8517                        // make sure to count it as being accessed and thus
8518                        // back up on the LRU list.  This is good because
8519                        // content providers are often expensive to start.
8520                        updateLruProcessLocked(cpr.proc, false, null);
8521                    }
8522                }
8523
8524                if (cpr.proc != null) {
8525                    if (false) {
8526                        if (cpr.name.flattenToShortString().equals(
8527                                "com.android.providers.calendar/.CalendarProvider2")) {
8528                            Slog.v(TAG, "****************** KILLING "
8529                                + cpr.name.flattenToShortString());
8530                            Process.killProcess(cpr.proc.pid);
8531                        }
8532                    }
8533                    boolean success = updateOomAdjLocked(cpr.proc);
8534                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8535                    // NOTE: there is still a race here where a signal could be
8536                    // pending on the process even though we managed to update its
8537                    // adj level.  Not sure what to do about this, but at least
8538                    // the race is now smaller.
8539                    if (!success) {
8540                        // Uh oh...  it looks like the provider's process
8541                        // has been killed on us.  We need to wait for a new
8542                        // process to be started, and make sure its death
8543                        // doesn't kill our process.
8544                        Slog.i(TAG,
8545                                "Existing provider " + cpr.name.flattenToShortString()
8546                                + " is crashing; detaching " + r);
8547                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8548                        appDiedLocked(cpr.proc);
8549                        if (!lastRef) {
8550                            // This wasn't the last ref our process had on
8551                            // the provider...  we have now been killed, bail.
8552                            return null;
8553                        }
8554                        providerRunning = false;
8555                        conn = null;
8556                    }
8557                }
8558
8559                Binder.restoreCallingIdentity(origId);
8560            }
8561
8562            boolean singleton;
8563            if (!providerRunning) {
8564                try {
8565                    cpi = AppGlobals.getPackageManager().
8566                        resolveContentProvider(name,
8567                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8568                } catch (RemoteException ex) {
8569                }
8570                if (cpi == null) {
8571                    return null;
8572                }
8573                // If the provider is a singleton AND
8574                // (it's a call within the same user || the provider is a
8575                // privileged app)
8576                // Then allow connecting to the singleton provider
8577                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8578                        cpi.name, cpi.flags)
8579                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8580                if (singleton) {
8581                    userId = UserHandle.USER_OWNER;
8582                }
8583                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8584
8585                String msg;
8586                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8587                        != null) {
8588                    throw new SecurityException(msg);
8589                }
8590
8591                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8592                        && !cpi.processName.equals("system")) {
8593                    // If this content provider does not run in the system
8594                    // process, and the system is not yet ready to run other
8595                    // processes, then fail fast instead of hanging.
8596                    throw new IllegalArgumentException(
8597                            "Attempt to launch content provider before system ready");
8598                }
8599
8600                // Make sure that the user who owns this provider is started.  If not,
8601                // we don't want to allow it to run.
8602                if (mStartedUsers.get(userId) == null) {
8603                    Slog.w(TAG, "Unable to launch app "
8604                            + cpi.applicationInfo.packageName + "/"
8605                            + cpi.applicationInfo.uid + " for provider "
8606                            + name + ": user " + userId + " is stopped");
8607                    return null;
8608                }
8609
8610                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8611                cpr = mProviderMap.getProviderByClass(comp, userId);
8612                final boolean firstClass = cpr == null;
8613                if (firstClass) {
8614                    try {
8615                        ApplicationInfo ai =
8616                            AppGlobals.getPackageManager().
8617                                getApplicationInfo(
8618                                        cpi.applicationInfo.packageName,
8619                                        STOCK_PM_FLAGS, userId);
8620                        if (ai == null) {
8621                            Slog.w(TAG, "No package info for content provider "
8622                                    + cpi.name);
8623                            return null;
8624                        }
8625                        ai = getAppInfoForUser(ai, userId);
8626                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8627                    } catch (RemoteException ex) {
8628                        // pm is in same process, this will never happen.
8629                    }
8630                }
8631
8632                if (r != null && cpr.canRunHere(r)) {
8633                    // If this is a multiprocess provider, then just return its
8634                    // info and allow the caller to instantiate it.  Only do
8635                    // this if the provider is the same user as the caller's
8636                    // process, or can run as root (so can be in any process).
8637                    return cpr.newHolder(null);
8638                }
8639
8640                if (DEBUG_PROVIDER) {
8641                    RuntimeException e = new RuntimeException("here");
8642                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8643                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8644                }
8645
8646                // This is single process, and our app is now connecting to it.
8647                // See if we are already in the process of launching this
8648                // provider.
8649                final int N = mLaunchingProviders.size();
8650                int i;
8651                for (i=0; i<N; i++) {
8652                    if (mLaunchingProviders.get(i) == cpr) {
8653                        break;
8654                    }
8655                }
8656
8657                // If the provider is not already being launched, then get it
8658                // started.
8659                if (i >= N) {
8660                    final long origId = Binder.clearCallingIdentity();
8661
8662                    try {
8663                        // Content provider is now in use, its package can't be stopped.
8664                        try {
8665                            AppGlobals.getPackageManager().setPackageStoppedState(
8666                                    cpr.appInfo.packageName, false, userId);
8667                        } catch (RemoteException e) {
8668                        } catch (IllegalArgumentException e) {
8669                            Slog.w(TAG, "Failed trying to unstop package "
8670                                    + cpr.appInfo.packageName + ": " + e);
8671                        }
8672
8673                        // Use existing process if already started
8674                        ProcessRecord proc = getProcessRecordLocked(
8675                                cpi.processName, cpr.appInfo.uid, false);
8676                        if (proc != null && proc.thread != null) {
8677                            if (DEBUG_PROVIDER) {
8678                                Slog.d(TAG, "Installing in existing process " + proc);
8679                            }
8680                            proc.pubProviders.put(cpi.name, cpr);
8681                            try {
8682                                proc.thread.scheduleInstallProvider(cpi);
8683                            } catch (RemoteException e) {
8684                            }
8685                        } else {
8686                            proc = startProcessLocked(cpi.processName,
8687                                    cpr.appInfo, false, 0, "content provider",
8688                                    new ComponentName(cpi.applicationInfo.packageName,
8689                                            cpi.name), false, false, false);
8690                            if (proc == null) {
8691                                Slog.w(TAG, "Unable to launch app "
8692                                        + cpi.applicationInfo.packageName + "/"
8693                                        + cpi.applicationInfo.uid + " for provider "
8694                                        + name + ": process is bad");
8695                                return null;
8696                            }
8697                        }
8698                        cpr.launchingApp = proc;
8699                        mLaunchingProviders.add(cpr);
8700                    } finally {
8701                        Binder.restoreCallingIdentity(origId);
8702                    }
8703                }
8704
8705                // Make sure the provider is published (the same provider class
8706                // may be published under multiple names).
8707                if (firstClass) {
8708                    mProviderMap.putProviderByClass(comp, cpr);
8709                }
8710
8711                mProviderMap.putProviderByName(name, cpr);
8712                conn = incProviderCountLocked(r, cpr, token, stable);
8713                if (conn != null) {
8714                    conn.waiting = true;
8715                }
8716            }
8717        }
8718
8719        // Wait for the provider to be published...
8720        synchronized (cpr) {
8721            while (cpr.provider == null) {
8722                if (cpr.launchingApp == null) {
8723                    Slog.w(TAG, "Unable to launch app "
8724                            + cpi.applicationInfo.packageName + "/"
8725                            + cpi.applicationInfo.uid + " for provider "
8726                            + name + ": launching app became null");
8727                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8728                            UserHandle.getUserId(cpi.applicationInfo.uid),
8729                            cpi.applicationInfo.packageName,
8730                            cpi.applicationInfo.uid, name);
8731                    return null;
8732                }
8733                try {
8734                    if (DEBUG_MU) {
8735                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8736                                + cpr.launchingApp);
8737                    }
8738                    if (conn != null) {
8739                        conn.waiting = true;
8740                    }
8741                    cpr.wait();
8742                } catch (InterruptedException ex) {
8743                } finally {
8744                    if (conn != null) {
8745                        conn.waiting = false;
8746                    }
8747                }
8748            }
8749        }
8750        return cpr != null ? cpr.newHolder(conn) : null;
8751    }
8752
8753    @Override
8754    public final ContentProviderHolder getContentProvider(
8755            IApplicationThread caller, String name, int userId, boolean stable) {
8756        enforceNotIsolatedCaller("getContentProvider");
8757        if (caller == null) {
8758            String msg = "null IApplicationThread when getting content provider "
8759                    + name;
8760            Slog.w(TAG, msg);
8761            throw new SecurityException(msg);
8762        }
8763        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8764        // with cross-user grant.
8765        return getContentProviderImpl(caller, name, null, stable, userId);
8766    }
8767
8768    public ContentProviderHolder getContentProviderExternal(
8769            String name, int userId, IBinder token) {
8770        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8771            "Do not have permission in call getContentProviderExternal()");
8772        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8773                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8774        return getContentProviderExternalUnchecked(name, token, userId);
8775    }
8776
8777    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8778            IBinder token, int userId) {
8779        return getContentProviderImpl(null, name, token, true, userId);
8780    }
8781
8782    /**
8783     * Drop a content provider from a ProcessRecord's bookkeeping
8784     */
8785    public void removeContentProvider(IBinder connection, boolean stable) {
8786        enforceNotIsolatedCaller("removeContentProvider");
8787        long ident = Binder.clearCallingIdentity();
8788        try {
8789            synchronized (this) {
8790                ContentProviderConnection conn;
8791                try {
8792                    conn = (ContentProviderConnection)connection;
8793                } catch (ClassCastException e) {
8794                    String msg ="removeContentProvider: " + connection
8795                            + " not a ContentProviderConnection";
8796                    Slog.w(TAG, msg);
8797                    throw new IllegalArgumentException(msg);
8798                }
8799                if (conn == null) {
8800                    throw new NullPointerException("connection is null");
8801                }
8802                if (decProviderCountLocked(conn, null, null, stable)) {
8803                    updateOomAdjLocked();
8804                }
8805            }
8806        } finally {
8807            Binder.restoreCallingIdentity(ident);
8808        }
8809    }
8810
8811    public void removeContentProviderExternal(String name, IBinder token) {
8812        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8813            "Do not have permission in call removeContentProviderExternal()");
8814        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8815    }
8816
8817    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8818        synchronized (this) {
8819            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8820            if(cpr == null) {
8821                //remove from mProvidersByClass
8822                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8823                return;
8824            }
8825
8826            //update content provider record entry info
8827            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8828            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8829            if (localCpr.hasExternalProcessHandles()) {
8830                if (localCpr.removeExternalProcessHandleLocked(token)) {
8831                    updateOomAdjLocked();
8832                } else {
8833                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8834                            + " with no external reference for token: "
8835                            + token + ".");
8836                }
8837            } else {
8838                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8839                        + " with no external references.");
8840            }
8841        }
8842    }
8843
8844    public final void publishContentProviders(IApplicationThread caller,
8845            List<ContentProviderHolder> providers) {
8846        if (providers == null) {
8847            return;
8848        }
8849
8850        enforceNotIsolatedCaller("publishContentProviders");
8851        synchronized (this) {
8852            final ProcessRecord r = getRecordForAppLocked(caller);
8853            if (DEBUG_MU)
8854                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8855            if (r == null) {
8856                throw new SecurityException(
8857                        "Unable to find app for caller " + caller
8858                      + " (pid=" + Binder.getCallingPid()
8859                      + ") when publishing content providers");
8860            }
8861
8862            final long origId = Binder.clearCallingIdentity();
8863
8864            final int N = providers.size();
8865            for (int i=0; i<N; i++) {
8866                ContentProviderHolder src = providers.get(i);
8867                if (src == null || src.info == null || src.provider == null) {
8868                    continue;
8869                }
8870                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8871                if (DEBUG_MU)
8872                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8873                if (dst != null) {
8874                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8875                    mProviderMap.putProviderByClass(comp, dst);
8876                    String names[] = dst.info.authority.split(";");
8877                    for (int j = 0; j < names.length; j++) {
8878                        mProviderMap.putProviderByName(names[j], dst);
8879                    }
8880
8881                    int NL = mLaunchingProviders.size();
8882                    int j;
8883                    for (j=0; j<NL; j++) {
8884                        if (mLaunchingProviders.get(j) == dst) {
8885                            mLaunchingProviders.remove(j);
8886                            j--;
8887                            NL--;
8888                        }
8889                    }
8890                    synchronized (dst) {
8891                        dst.provider = src.provider;
8892                        dst.proc = r;
8893                        dst.notifyAll();
8894                    }
8895                    updateOomAdjLocked(r);
8896                }
8897            }
8898
8899            Binder.restoreCallingIdentity(origId);
8900        }
8901    }
8902
8903    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8904        ContentProviderConnection conn;
8905        try {
8906            conn = (ContentProviderConnection)connection;
8907        } catch (ClassCastException e) {
8908            String msg ="refContentProvider: " + connection
8909                    + " not a ContentProviderConnection";
8910            Slog.w(TAG, msg);
8911            throw new IllegalArgumentException(msg);
8912        }
8913        if (conn == null) {
8914            throw new NullPointerException("connection is null");
8915        }
8916
8917        synchronized (this) {
8918            if (stable > 0) {
8919                conn.numStableIncs += stable;
8920            }
8921            stable = conn.stableCount + stable;
8922            if (stable < 0) {
8923                throw new IllegalStateException("stableCount < 0: " + stable);
8924            }
8925
8926            if (unstable > 0) {
8927                conn.numUnstableIncs += unstable;
8928            }
8929            unstable = conn.unstableCount + unstable;
8930            if (unstable < 0) {
8931                throw new IllegalStateException("unstableCount < 0: " + unstable);
8932            }
8933
8934            if ((stable+unstable) <= 0) {
8935                throw new IllegalStateException("ref counts can't go to zero here: stable="
8936                        + stable + " unstable=" + unstable);
8937            }
8938            conn.stableCount = stable;
8939            conn.unstableCount = unstable;
8940            return !conn.dead;
8941        }
8942    }
8943
8944    public void unstableProviderDied(IBinder connection) {
8945        ContentProviderConnection conn;
8946        try {
8947            conn = (ContentProviderConnection)connection;
8948        } catch (ClassCastException e) {
8949            String msg ="refContentProvider: " + connection
8950                    + " not a ContentProviderConnection";
8951            Slog.w(TAG, msg);
8952            throw new IllegalArgumentException(msg);
8953        }
8954        if (conn == null) {
8955            throw new NullPointerException("connection is null");
8956        }
8957
8958        // Safely retrieve the content provider associated with the connection.
8959        IContentProvider provider;
8960        synchronized (this) {
8961            provider = conn.provider.provider;
8962        }
8963
8964        if (provider == null) {
8965            // Um, yeah, we're way ahead of you.
8966            return;
8967        }
8968
8969        // Make sure the caller is being honest with us.
8970        if (provider.asBinder().pingBinder()) {
8971            // Er, no, still looks good to us.
8972            synchronized (this) {
8973                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8974                        + " says " + conn + " died, but we don't agree");
8975                return;
8976            }
8977        }
8978
8979        // Well look at that!  It's dead!
8980        synchronized (this) {
8981            if (conn.provider.provider != provider) {
8982                // But something changed...  good enough.
8983                return;
8984            }
8985
8986            ProcessRecord proc = conn.provider.proc;
8987            if (proc == null || proc.thread == null) {
8988                // Seems like the process is already cleaned up.
8989                return;
8990            }
8991
8992            // As far as we're concerned, this is just like receiving a
8993            // death notification...  just a bit prematurely.
8994            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8995                    + ") early provider death");
8996            final long ident = Binder.clearCallingIdentity();
8997            try {
8998                appDiedLocked(proc);
8999            } finally {
9000                Binder.restoreCallingIdentity(ident);
9001            }
9002        }
9003    }
9004
9005    @Override
9006    public void appNotRespondingViaProvider(IBinder connection) {
9007        enforceCallingPermission(
9008                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9009
9010        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9011        if (conn == null) {
9012            Slog.w(TAG, "ContentProviderConnection is null");
9013            return;
9014        }
9015
9016        final ProcessRecord host = conn.provider.proc;
9017        if (host == null) {
9018            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9019            return;
9020        }
9021
9022        final long token = Binder.clearCallingIdentity();
9023        try {
9024            appNotResponding(host, null, null, false, "ContentProvider not responding");
9025        } finally {
9026            Binder.restoreCallingIdentity(token);
9027        }
9028    }
9029
9030    public final void installSystemProviders() {
9031        List<ProviderInfo> providers;
9032        synchronized (this) {
9033            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9034            providers = generateApplicationProvidersLocked(app);
9035            if (providers != null) {
9036                for (int i=providers.size()-1; i>=0; i--) {
9037                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9038                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9039                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9040                                + ": not system .apk");
9041                        providers.remove(i);
9042                    }
9043                }
9044            }
9045        }
9046        if (providers != null) {
9047            mSystemThread.installSystemProviders(providers);
9048        }
9049
9050        mCoreSettingsObserver = new CoreSettingsObserver(this);
9051
9052        //mUsageStatsService.monitorPackages();
9053    }
9054
9055    /**
9056     * Allows apps to retrieve the MIME type of a URI.
9057     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9058     * users, then it does not need permission to access the ContentProvider.
9059     * Either, it needs cross-user uri grants.
9060     *
9061     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9062     *
9063     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9064     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9065     */
9066    public String getProviderMimeType(Uri uri, int userId) {
9067        enforceNotIsolatedCaller("getProviderMimeType");
9068        final String name = uri.getAuthority();
9069        int callingUid = Binder.getCallingUid();
9070        int callingPid = Binder.getCallingPid();
9071        long ident = 0;
9072        boolean clearedIdentity = false;
9073        userId = unsafeConvertIncomingUser(userId);
9074        if (UserHandle.getUserId(callingUid) != userId) {
9075            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9076                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9077                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9078                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9079                clearedIdentity = true;
9080                ident = Binder.clearCallingIdentity();
9081            }
9082        }
9083        ContentProviderHolder holder = null;
9084        try {
9085            holder = getContentProviderExternalUnchecked(name, null, userId);
9086            if (holder != null) {
9087                return holder.provider.getType(uri);
9088            }
9089        } catch (RemoteException e) {
9090            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9091            return null;
9092        } finally {
9093            // We need to clear the identity to call removeContentProviderExternalUnchecked
9094            if (!clearedIdentity) {
9095                ident = Binder.clearCallingIdentity();
9096            }
9097            try {
9098                if (holder != null) {
9099                    removeContentProviderExternalUnchecked(name, null, userId);
9100                }
9101            } finally {
9102                Binder.restoreCallingIdentity(ident);
9103            }
9104        }
9105
9106        return null;
9107    }
9108
9109    // =========================================================
9110    // GLOBAL MANAGEMENT
9111    // =========================================================
9112
9113    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9114            boolean isolated, int isolatedUid) {
9115        String proc = customProcess != null ? customProcess : info.processName;
9116        BatteryStatsImpl.Uid.Proc ps = null;
9117        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9118        int uid = info.uid;
9119        if (isolated) {
9120            if (isolatedUid == 0) {
9121                int userId = UserHandle.getUserId(uid);
9122                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9123                while (true) {
9124                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9125                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9126                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9127                    }
9128                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9129                    mNextIsolatedProcessUid++;
9130                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9131                        // No process for this uid, use it.
9132                        break;
9133                    }
9134                    stepsLeft--;
9135                    if (stepsLeft <= 0) {
9136                        return null;
9137                    }
9138                }
9139            } else {
9140                // Special case for startIsolatedProcess (internal only), where
9141                // the uid of the isolated process is specified by the caller.
9142                uid = isolatedUid;
9143            }
9144        }
9145        return new ProcessRecord(stats, info, proc, uid);
9146    }
9147
9148    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9149            String abiOverride) {
9150        ProcessRecord app;
9151        if (!isolated) {
9152            app = getProcessRecordLocked(info.processName, info.uid, true);
9153        } else {
9154            app = null;
9155        }
9156
9157        if (app == null) {
9158            app = newProcessRecordLocked(info, null, isolated, 0);
9159            mProcessNames.put(info.processName, app.uid, app);
9160            if (isolated) {
9161                mIsolatedProcesses.put(app.uid, app);
9162            }
9163            updateLruProcessLocked(app, false, null);
9164            updateOomAdjLocked();
9165        }
9166
9167        // This package really, really can not be stopped.
9168        try {
9169            AppGlobals.getPackageManager().setPackageStoppedState(
9170                    info.packageName, false, UserHandle.getUserId(app.uid));
9171        } catch (RemoteException e) {
9172        } catch (IllegalArgumentException e) {
9173            Slog.w(TAG, "Failed trying to unstop package "
9174                    + info.packageName + ": " + e);
9175        }
9176
9177        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9178                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9179            app.persistent = true;
9180            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9181        }
9182        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9183            mPersistentStartingProcesses.add(app);
9184            startProcessLocked(app, "added application", app.processName, abiOverride,
9185                    null /* entryPoint */, null /* entryPointArgs */);
9186        }
9187
9188        return app;
9189    }
9190
9191    public void unhandledBack() {
9192        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9193                "unhandledBack()");
9194
9195        synchronized(this) {
9196            final long origId = Binder.clearCallingIdentity();
9197            try {
9198                getFocusedStack().unhandledBackLocked();
9199            } finally {
9200                Binder.restoreCallingIdentity(origId);
9201            }
9202        }
9203    }
9204
9205    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9206        enforceNotIsolatedCaller("openContentUri");
9207        final int userId = UserHandle.getCallingUserId();
9208        String name = uri.getAuthority();
9209        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9210        ParcelFileDescriptor pfd = null;
9211        if (cph != null) {
9212            // We record the binder invoker's uid in thread-local storage before
9213            // going to the content provider to open the file.  Later, in the code
9214            // that handles all permissions checks, we look for this uid and use
9215            // that rather than the Activity Manager's own uid.  The effect is that
9216            // we do the check against the caller's permissions even though it looks
9217            // to the content provider like the Activity Manager itself is making
9218            // the request.
9219            sCallerIdentity.set(new Identity(
9220                    Binder.getCallingPid(), Binder.getCallingUid()));
9221            try {
9222                pfd = cph.provider.openFile(null, uri, "r", null);
9223            } catch (FileNotFoundException e) {
9224                // do nothing; pfd will be returned null
9225            } finally {
9226                // Ensure that whatever happens, we clean up the identity state
9227                sCallerIdentity.remove();
9228            }
9229
9230            // We've got the fd now, so we're done with the provider.
9231            removeContentProviderExternalUnchecked(name, null, userId);
9232        } else {
9233            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9234        }
9235        return pfd;
9236    }
9237
9238    // Actually is sleeping or shutting down or whatever else in the future
9239    // is an inactive state.
9240    public boolean isSleepingOrShuttingDown() {
9241        return mSleeping || mShuttingDown;
9242    }
9243
9244    public boolean isSleeping() {
9245        return mSleeping;
9246    }
9247
9248    void goingToSleep() {
9249        synchronized(this) {
9250            mWentToSleep = true;
9251            updateEventDispatchingLocked();
9252            goToSleepIfNeededLocked();
9253        }
9254    }
9255
9256    void finishRunningVoiceLocked() {
9257        if (mRunningVoice) {
9258            mRunningVoice = false;
9259            goToSleepIfNeededLocked();
9260        }
9261    }
9262
9263    void goToSleepIfNeededLocked() {
9264        if (mWentToSleep && !mRunningVoice) {
9265            if (!mSleeping) {
9266                mSleeping = true;
9267                mStackSupervisor.goingToSleepLocked();
9268
9269                // Initialize the wake times of all processes.
9270                checkExcessivePowerUsageLocked(false);
9271                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9272                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9273                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9274            }
9275        }
9276    }
9277
9278    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9279        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9280            // Never persist the home stack.
9281            return;
9282        }
9283        mTaskPersister.wakeup(task, flush);
9284    }
9285
9286    @Override
9287    public boolean shutdown(int timeout) {
9288        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9289                != PackageManager.PERMISSION_GRANTED) {
9290            throw new SecurityException("Requires permission "
9291                    + android.Manifest.permission.SHUTDOWN);
9292        }
9293
9294        boolean timedout = false;
9295
9296        synchronized(this) {
9297            mShuttingDown = true;
9298            updateEventDispatchingLocked();
9299            timedout = mStackSupervisor.shutdownLocked(timeout);
9300        }
9301
9302        mAppOpsService.shutdown();
9303        if (mUsageStatsService != null) {
9304            mUsageStatsService.prepareShutdown();
9305        }
9306        mBatteryStatsService.shutdown();
9307        synchronized (this) {
9308            mProcessStats.shutdownLocked();
9309        }
9310        notifyTaskPersisterLocked(null, true);
9311
9312        return timedout;
9313    }
9314
9315    public final void activitySlept(IBinder token) {
9316        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9317
9318        final long origId = Binder.clearCallingIdentity();
9319
9320        synchronized (this) {
9321            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9322            if (r != null) {
9323                mStackSupervisor.activitySleptLocked(r);
9324            }
9325        }
9326
9327        Binder.restoreCallingIdentity(origId);
9328    }
9329
9330    void logLockScreen(String msg) {
9331        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9332                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9333                mWentToSleep + " mSleeping=" + mSleeping);
9334    }
9335
9336    private void comeOutOfSleepIfNeededLocked() {
9337        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9338            if (mSleeping) {
9339                mSleeping = false;
9340                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9341            }
9342        }
9343    }
9344
9345    void wakingUp() {
9346        synchronized(this) {
9347            mWentToSleep = false;
9348            updateEventDispatchingLocked();
9349            comeOutOfSleepIfNeededLocked();
9350        }
9351    }
9352
9353    void startRunningVoiceLocked() {
9354        if (!mRunningVoice) {
9355            mRunningVoice = true;
9356            comeOutOfSleepIfNeededLocked();
9357        }
9358    }
9359
9360    private void updateEventDispatchingLocked() {
9361        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9362    }
9363
9364    public void setLockScreenShown(boolean shown) {
9365        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9366                != PackageManager.PERMISSION_GRANTED) {
9367            throw new SecurityException("Requires permission "
9368                    + android.Manifest.permission.DEVICE_POWER);
9369        }
9370
9371        synchronized(this) {
9372            long ident = Binder.clearCallingIdentity();
9373            try {
9374                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9375                mLockScreenShown = shown;
9376                comeOutOfSleepIfNeededLocked();
9377            } finally {
9378                Binder.restoreCallingIdentity(ident);
9379            }
9380        }
9381    }
9382
9383    @Override
9384    public void stopAppSwitches() {
9385        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9386                != PackageManager.PERMISSION_GRANTED) {
9387            throw new SecurityException("Requires permission "
9388                    + android.Manifest.permission.STOP_APP_SWITCHES);
9389        }
9390
9391        synchronized(this) {
9392            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9393                    + APP_SWITCH_DELAY_TIME;
9394            mDidAppSwitch = false;
9395            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9396            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9397            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9398        }
9399    }
9400
9401    public void resumeAppSwitches() {
9402        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9403                != PackageManager.PERMISSION_GRANTED) {
9404            throw new SecurityException("Requires permission "
9405                    + android.Manifest.permission.STOP_APP_SWITCHES);
9406        }
9407
9408        synchronized(this) {
9409            // Note that we don't execute any pending app switches... we will
9410            // let those wait until either the timeout, or the next start
9411            // activity request.
9412            mAppSwitchesAllowedTime = 0;
9413        }
9414    }
9415
9416    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9417            String name) {
9418        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9419            return true;
9420        }
9421
9422        final int perm = checkComponentPermission(
9423                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9424                callingUid, -1, true);
9425        if (perm == PackageManager.PERMISSION_GRANTED) {
9426            return true;
9427        }
9428
9429        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9430        return false;
9431    }
9432
9433    public void setDebugApp(String packageName, boolean waitForDebugger,
9434            boolean persistent) {
9435        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9436                "setDebugApp()");
9437
9438        long ident = Binder.clearCallingIdentity();
9439        try {
9440            // Note that this is not really thread safe if there are multiple
9441            // callers into it at the same time, but that's not a situation we
9442            // care about.
9443            if (persistent) {
9444                final ContentResolver resolver = mContext.getContentResolver();
9445                Settings.Global.putString(
9446                    resolver, Settings.Global.DEBUG_APP,
9447                    packageName);
9448                Settings.Global.putInt(
9449                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9450                    waitForDebugger ? 1 : 0);
9451            }
9452
9453            synchronized (this) {
9454                if (!persistent) {
9455                    mOrigDebugApp = mDebugApp;
9456                    mOrigWaitForDebugger = mWaitForDebugger;
9457                }
9458                mDebugApp = packageName;
9459                mWaitForDebugger = waitForDebugger;
9460                mDebugTransient = !persistent;
9461                if (packageName != null) {
9462                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9463                            false, UserHandle.USER_ALL, "set debug app");
9464                }
9465            }
9466        } finally {
9467            Binder.restoreCallingIdentity(ident);
9468        }
9469    }
9470
9471    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9472        synchronized (this) {
9473            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9474            if (!isDebuggable) {
9475                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9476                    throw new SecurityException("Process not debuggable: " + app.packageName);
9477                }
9478            }
9479
9480            mOpenGlTraceApp = processName;
9481        }
9482    }
9483
9484    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9485            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9486        synchronized (this) {
9487            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9488            if (!isDebuggable) {
9489                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9490                    throw new SecurityException("Process not debuggable: " + app.packageName);
9491                }
9492            }
9493            mProfileApp = processName;
9494            mProfileFile = profileFile;
9495            if (mProfileFd != null) {
9496                try {
9497                    mProfileFd.close();
9498                } catch (IOException e) {
9499                }
9500                mProfileFd = null;
9501            }
9502            mProfileFd = profileFd;
9503            mProfileType = 0;
9504            mAutoStopProfiler = autoStopProfiler;
9505        }
9506    }
9507
9508    @Override
9509    public void setAlwaysFinish(boolean enabled) {
9510        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9511                "setAlwaysFinish()");
9512
9513        Settings.Global.putInt(
9514                mContext.getContentResolver(),
9515                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9516
9517        synchronized (this) {
9518            mAlwaysFinishActivities = enabled;
9519        }
9520    }
9521
9522    @Override
9523    public void setActivityController(IActivityController controller) {
9524        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9525                "setActivityController()");
9526        synchronized (this) {
9527            mController = controller;
9528            Watchdog.getInstance().setActivityController(controller);
9529        }
9530    }
9531
9532    @Override
9533    public void setUserIsMonkey(boolean userIsMonkey) {
9534        synchronized (this) {
9535            synchronized (mPidsSelfLocked) {
9536                final int callingPid = Binder.getCallingPid();
9537                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9538                if (precessRecord == null) {
9539                    throw new SecurityException("Unknown process: " + callingPid);
9540                }
9541                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9542                    throw new SecurityException("Only an instrumentation process "
9543                            + "with a UiAutomation can call setUserIsMonkey");
9544                }
9545            }
9546            mUserIsMonkey = userIsMonkey;
9547        }
9548    }
9549
9550    @Override
9551    public boolean isUserAMonkey() {
9552        synchronized (this) {
9553            // If there is a controller also implies the user is a monkey.
9554            return (mUserIsMonkey || mController != null);
9555        }
9556    }
9557
9558    public void requestBugReport() {
9559        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9560        SystemProperties.set("ctl.start", "bugreport");
9561    }
9562
9563    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9564        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9565    }
9566
9567    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9568        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9569            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9570        }
9571        return KEY_DISPATCHING_TIMEOUT;
9572    }
9573
9574    @Override
9575    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9576        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9577                != PackageManager.PERMISSION_GRANTED) {
9578            throw new SecurityException("Requires permission "
9579                    + android.Manifest.permission.FILTER_EVENTS);
9580        }
9581        ProcessRecord proc;
9582        long timeout;
9583        synchronized (this) {
9584            synchronized (mPidsSelfLocked) {
9585                proc = mPidsSelfLocked.get(pid);
9586            }
9587            timeout = getInputDispatchingTimeoutLocked(proc);
9588        }
9589
9590        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9591            return -1;
9592        }
9593
9594        return timeout;
9595    }
9596
9597    /**
9598     * Handle input dispatching timeouts.
9599     * Returns whether input dispatching should be aborted or not.
9600     */
9601    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9602            final ActivityRecord activity, final ActivityRecord parent,
9603            final boolean aboveSystem, String reason) {
9604        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9605                != PackageManager.PERMISSION_GRANTED) {
9606            throw new SecurityException("Requires permission "
9607                    + android.Manifest.permission.FILTER_EVENTS);
9608        }
9609
9610        final String annotation;
9611        if (reason == null) {
9612            annotation = "Input dispatching timed out";
9613        } else {
9614            annotation = "Input dispatching timed out (" + reason + ")";
9615        }
9616
9617        if (proc != null) {
9618            synchronized (this) {
9619                if (proc.debugging) {
9620                    return false;
9621                }
9622
9623                if (mDidDexOpt) {
9624                    // Give more time since we were dexopting.
9625                    mDidDexOpt = false;
9626                    return false;
9627                }
9628
9629                if (proc.instrumentationClass != null) {
9630                    Bundle info = new Bundle();
9631                    info.putString("shortMsg", "keyDispatchingTimedOut");
9632                    info.putString("longMsg", annotation);
9633                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9634                    return true;
9635                }
9636            }
9637            mHandler.post(new Runnable() {
9638                @Override
9639                public void run() {
9640                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9641                }
9642            });
9643        }
9644
9645        return true;
9646    }
9647
9648    public Bundle getAssistContextExtras(int requestType) {
9649        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9650                "getAssistContextExtras()");
9651        PendingAssistExtras pae;
9652        Bundle extras = new Bundle();
9653        synchronized (this) {
9654            ActivityRecord activity = getFocusedStack().mResumedActivity;
9655            if (activity == null) {
9656                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9657                return null;
9658            }
9659            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9660            if (activity.app == null || activity.app.thread == null) {
9661                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9662                return extras;
9663            }
9664            if (activity.app.pid == Binder.getCallingPid()) {
9665                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9666                return extras;
9667            }
9668            pae = new PendingAssistExtras(activity);
9669            try {
9670                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9671                        requestType);
9672                mPendingAssistExtras.add(pae);
9673                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9674            } catch (RemoteException e) {
9675                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9676                return extras;
9677            }
9678        }
9679        synchronized (pae) {
9680            while (!pae.haveResult) {
9681                try {
9682                    pae.wait();
9683                } catch (InterruptedException e) {
9684                }
9685            }
9686            if (pae.result != null) {
9687                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9688            }
9689        }
9690        synchronized (this) {
9691            mPendingAssistExtras.remove(pae);
9692            mHandler.removeCallbacks(pae);
9693        }
9694        return extras;
9695    }
9696
9697    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9698        PendingAssistExtras pae = (PendingAssistExtras)token;
9699        synchronized (pae) {
9700            pae.result = extras;
9701            pae.haveResult = true;
9702            pae.notifyAll();
9703        }
9704    }
9705
9706    public void registerProcessObserver(IProcessObserver observer) {
9707        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9708                "registerProcessObserver()");
9709        synchronized (this) {
9710            mProcessObservers.register(observer);
9711        }
9712    }
9713
9714    @Override
9715    public void unregisterProcessObserver(IProcessObserver observer) {
9716        synchronized (this) {
9717            mProcessObservers.unregister(observer);
9718        }
9719    }
9720
9721    @Override
9722    public boolean convertFromTranslucent(IBinder token) {
9723        final long origId = Binder.clearCallingIdentity();
9724        try {
9725            synchronized (this) {
9726                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9727                if (r == null) {
9728                    return false;
9729                }
9730                if (r.changeWindowTranslucency(true)) {
9731                    mWindowManager.setAppFullscreen(token, true);
9732                    r.task.stack.releaseBackgroundResources();
9733                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9734                    return true;
9735                }
9736                return false;
9737            }
9738        } finally {
9739            Binder.restoreCallingIdentity(origId);
9740        }
9741    }
9742
9743    @Override
9744    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9745        final long origId = Binder.clearCallingIdentity();
9746        try {
9747            synchronized (this) {
9748                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9749                if (r == null) {
9750                    return false;
9751                }
9752                int index = r.task.mActivities.lastIndexOf(r);
9753                if (index > 0) {
9754                    ActivityRecord under = r.task.mActivities.get(index - 1);
9755                    under.returningOptions = options;
9756                }
9757                if (r.changeWindowTranslucency(false)) {
9758                    r.task.stack.convertToTranslucent(r);
9759                    mWindowManager.setAppFullscreen(token, false);
9760                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9761                    return true;
9762                } else {
9763                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9764                    return false;
9765                }
9766            }
9767        } finally {
9768            Binder.restoreCallingIdentity(origId);
9769        }
9770    }
9771
9772    @Override
9773    public boolean requestVisibleBehind(IBinder token, boolean visible) {
9774        final long origId = Binder.clearCallingIdentity();
9775        try {
9776            synchronized (this) {
9777                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9778                if (r != null) {
9779                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
9780                }
9781            }
9782            return false;
9783        } finally {
9784            Binder.restoreCallingIdentity(origId);
9785        }
9786    }
9787
9788    @Override
9789    public boolean isBackgroundVisibleBehind(IBinder token) {
9790        final long origId = Binder.clearCallingIdentity();
9791        try {
9792            synchronized (this) {
9793                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9794                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
9795                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
9796                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
9797                return visible;
9798            }
9799        } finally {
9800            Binder.restoreCallingIdentity(origId);
9801        }
9802    }
9803
9804    @Override
9805    public ActivityOptions getActivityOptions(IBinder token) {
9806        final long origId = Binder.clearCallingIdentity();
9807        try {
9808            synchronized (this) {
9809                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9810                if (r != null) {
9811                    final ActivityOptions activityOptions = r.pendingOptions;
9812                    r.pendingOptions = null;
9813                    return activityOptions;
9814                }
9815                return null;
9816            }
9817        } finally {
9818            Binder.restoreCallingIdentity(origId);
9819        }
9820    }
9821
9822    @Override
9823    public void setImmersive(IBinder token, boolean immersive) {
9824        synchronized(this) {
9825            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9826            if (r == null) {
9827                throw new IllegalArgumentException();
9828            }
9829            r.immersive = immersive;
9830
9831            // update associated state if we're frontmost
9832            if (r == mFocusedActivity) {
9833                if (DEBUG_IMMERSIVE) {
9834                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9835                }
9836                applyUpdateLockStateLocked(r);
9837            }
9838        }
9839    }
9840
9841    @Override
9842    public boolean isImmersive(IBinder token) {
9843        synchronized (this) {
9844            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9845            if (r == null) {
9846                throw new IllegalArgumentException();
9847            }
9848            return r.immersive;
9849        }
9850    }
9851
9852    public boolean isTopActivityImmersive() {
9853        enforceNotIsolatedCaller("startActivity");
9854        synchronized (this) {
9855            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9856            return (r != null) ? r.immersive : false;
9857        }
9858    }
9859
9860    @Override
9861    public boolean isTopOfTask(IBinder token) {
9862        synchronized (this) {
9863            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9864            if (r == null) {
9865                throw new IllegalArgumentException();
9866            }
9867            return r.task.getTopActivity() == r;
9868        }
9869    }
9870
9871    public final void enterSafeMode() {
9872        synchronized(this) {
9873            // It only makes sense to do this before the system is ready
9874            // and started launching other packages.
9875            if (!mSystemReady) {
9876                try {
9877                    AppGlobals.getPackageManager().enterSafeMode();
9878                } catch (RemoteException e) {
9879                }
9880            }
9881
9882            mSafeMode = true;
9883        }
9884    }
9885
9886    public final void showSafeModeOverlay() {
9887        View v = LayoutInflater.from(mContext).inflate(
9888                com.android.internal.R.layout.safe_mode, null);
9889        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9890        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9891        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9892        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9893        lp.gravity = Gravity.BOTTOM | Gravity.START;
9894        lp.format = v.getBackground().getOpacity();
9895        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9896                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9897        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9898        ((WindowManager)mContext.getSystemService(
9899                Context.WINDOW_SERVICE)).addView(v, lp);
9900    }
9901
9902    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9903        if (!(sender instanceof PendingIntentRecord)) {
9904            return;
9905        }
9906        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9907        synchronized (stats) {
9908            if (mBatteryStatsService.isOnBattery()) {
9909                mBatteryStatsService.enforceCallingPermission();
9910                PendingIntentRecord rec = (PendingIntentRecord)sender;
9911                int MY_UID = Binder.getCallingUid();
9912                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9913                BatteryStatsImpl.Uid.Pkg pkg =
9914                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9915                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9916                pkg.incWakeupsLocked();
9917            }
9918        }
9919    }
9920
9921    public boolean killPids(int[] pids, String pReason, boolean secure) {
9922        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9923            throw new SecurityException("killPids only available to the system");
9924        }
9925        String reason = (pReason == null) ? "Unknown" : pReason;
9926        // XXX Note: don't acquire main activity lock here, because the window
9927        // manager calls in with its locks held.
9928
9929        boolean killed = false;
9930        synchronized (mPidsSelfLocked) {
9931            int[] types = new int[pids.length];
9932            int worstType = 0;
9933            for (int i=0; i<pids.length; i++) {
9934                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9935                if (proc != null) {
9936                    int type = proc.setAdj;
9937                    types[i] = type;
9938                    if (type > worstType) {
9939                        worstType = type;
9940                    }
9941                }
9942            }
9943
9944            // If the worst oom_adj is somewhere in the cached proc LRU range,
9945            // then constrain it so we will kill all cached procs.
9946            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9947                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9948                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9949            }
9950
9951            // If this is not a secure call, don't let it kill processes that
9952            // are important.
9953            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9954                worstType = ProcessList.SERVICE_ADJ;
9955            }
9956
9957            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9958            for (int i=0; i<pids.length; i++) {
9959                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9960                if (proc == null) {
9961                    continue;
9962                }
9963                int adj = proc.setAdj;
9964                if (adj >= worstType && !proc.killedByAm) {
9965                    killUnneededProcessLocked(proc, reason);
9966                    killed = true;
9967                }
9968            }
9969        }
9970        return killed;
9971    }
9972
9973    @Override
9974    public void killUid(int uid, String reason) {
9975        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9976            throw new SecurityException("killUid only available to the system");
9977        }
9978        synchronized (this) {
9979            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9980                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9981                    reason != null ? reason : "kill uid");
9982        }
9983    }
9984
9985    @Override
9986    public boolean killProcessesBelowForeground(String reason) {
9987        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9988            throw new SecurityException("killProcessesBelowForeground() only available to system");
9989        }
9990
9991        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9992    }
9993
9994    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9995        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9996            throw new SecurityException("killProcessesBelowAdj() only available to system");
9997        }
9998
9999        boolean killed = false;
10000        synchronized (mPidsSelfLocked) {
10001            final int size = mPidsSelfLocked.size();
10002            for (int i = 0; i < size; i++) {
10003                final int pid = mPidsSelfLocked.keyAt(i);
10004                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10005                if (proc == null) continue;
10006
10007                final int adj = proc.setAdj;
10008                if (adj > belowAdj && !proc.killedByAm) {
10009                    killUnneededProcessLocked(proc, reason);
10010                    killed = true;
10011                }
10012            }
10013        }
10014        return killed;
10015    }
10016
10017    @Override
10018    public void hang(final IBinder who, boolean allowRestart) {
10019        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10020                != PackageManager.PERMISSION_GRANTED) {
10021            throw new SecurityException("Requires permission "
10022                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10023        }
10024
10025        final IBinder.DeathRecipient death = new DeathRecipient() {
10026            @Override
10027            public void binderDied() {
10028                synchronized (this) {
10029                    notifyAll();
10030                }
10031            }
10032        };
10033
10034        try {
10035            who.linkToDeath(death, 0);
10036        } catch (RemoteException e) {
10037            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10038            return;
10039        }
10040
10041        synchronized (this) {
10042            Watchdog.getInstance().setAllowRestart(allowRestart);
10043            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10044            synchronized (death) {
10045                while (who.isBinderAlive()) {
10046                    try {
10047                        death.wait();
10048                    } catch (InterruptedException e) {
10049                    }
10050                }
10051            }
10052            Watchdog.getInstance().setAllowRestart(true);
10053        }
10054    }
10055
10056    @Override
10057    public void restart() {
10058        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10059                != PackageManager.PERMISSION_GRANTED) {
10060            throw new SecurityException("Requires permission "
10061                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10062        }
10063
10064        Log.i(TAG, "Sending shutdown broadcast...");
10065
10066        BroadcastReceiver br = new BroadcastReceiver() {
10067            @Override public void onReceive(Context context, Intent intent) {
10068                // Now the broadcast is done, finish up the low-level shutdown.
10069                Log.i(TAG, "Shutting down activity manager...");
10070                shutdown(10000);
10071                Log.i(TAG, "Shutdown complete, restarting!");
10072                Process.killProcess(Process.myPid());
10073                System.exit(10);
10074            }
10075        };
10076
10077        // First send the high-level shut down broadcast.
10078        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10079        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10080        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10081        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10082        mContext.sendOrderedBroadcastAsUser(intent,
10083                UserHandle.ALL, null, br, mHandler, 0, null, null);
10084        */
10085        br.onReceive(mContext, intent);
10086    }
10087
10088    private long getLowRamTimeSinceIdle(long now) {
10089        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10090    }
10091
10092    @Override
10093    public void performIdleMaintenance() {
10094        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10095                != PackageManager.PERMISSION_GRANTED) {
10096            throw new SecurityException("Requires permission "
10097                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10098        }
10099
10100        synchronized (this) {
10101            final long now = SystemClock.uptimeMillis();
10102            final long timeSinceLastIdle = now - mLastIdleTime;
10103            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10104            mLastIdleTime = now;
10105            mLowRamTimeSinceLastIdle = 0;
10106            if (mLowRamStartTime != 0) {
10107                mLowRamStartTime = now;
10108            }
10109
10110            StringBuilder sb = new StringBuilder(128);
10111            sb.append("Idle maintenance over ");
10112            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10113            sb.append(" low RAM for ");
10114            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10115            Slog.i(TAG, sb.toString());
10116
10117            // If at least 1/3 of our time since the last idle period has been spent
10118            // with RAM low, then we want to kill processes.
10119            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10120
10121            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10122                ProcessRecord proc = mLruProcesses.get(i);
10123                if (proc.notCachedSinceIdle) {
10124                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10125                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10126                        if (doKilling && proc.initialIdlePss != 0
10127                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10128                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
10129                                    + " from " + proc.initialIdlePss + ")");
10130                        }
10131                    }
10132                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10133                    proc.notCachedSinceIdle = true;
10134                    proc.initialIdlePss = 0;
10135                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10136                            isSleeping(), now);
10137                }
10138            }
10139
10140            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10141            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10142        }
10143    }
10144
10145    private void retrieveSettings() {
10146        final ContentResolver resolver = mContext.getContentResolver();
10147        String debugApp = Settings.Global.getString(
10148            resolver, Settings.Global.DEBUG_APP);
10149        boolean waitForDebugger = Settings.Global.getInt(
10150            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10151        boolean alwaysFinishActivities = Settings.Global.getInt(
10152            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10153        boolean forceRtl = Settings.Global.getInt(
10154                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10155        // Transfer any global setting for forcing RTL layout, into a System Property
10156        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10157
10158        Configuration configuration = new Configuration();
10159        Settings.System.getConfiguration(resolver, configuration);
10160        if (forceRtl) {
10161            // This will take care of setting the correct layout direction flags
10162            configuration.setLayoutDirection(configuration.locale);
10163        }
10164
10165        synchronized (this) {
10166            mDebugApp = mOrigDebugApp = debugApp;
10167            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10168            mAlwaysFinishActivities = alwaysFinishActivities;
10169            // This happens before any activities are started, so we can
10170            // change mConfiguration in-place.
10171            updateConfigurationLocked(configuration, null, false, true);
10172            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10173        }
10174    }
10175
10176    public boolean testIsSystemReady() {
10177        // no need to synchronize(this) just to read & return the value
10178        return mSystemReady;
10179    }
10180
10181    private static File getCalledPreBootReceiversFile() {
10182        File dataDir = Environment.getDataDirectory();
10183        File systemDir = new File(dataDir, "system");
10184        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10185        return fname;
10186    }
10187
10188    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10189        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10190        File file = getCalledPreBootReceiversFile();
10191        FileInputStream fis = null;
10192        try {
10193            fis = new FileInputStream(file);
10194            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10195            int fvers = dis.readInt();
10196            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10197                String vers = dis.readUTF();
10198                String codename = dis.readUTF();
10199                String build = dis.readUTF();
10200                if (android.os.Build.VERSION.RELEASE.equals(vers)
10201                        && android.os.Build.VERSION.CODENAME.equals(codename)
10202                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10203                    int num = dis.readInt();
10204                    while (num > 0) {
10205                        num--;
10206                        String pkg = dis.readUTF();
10207                        String cls = dis.readUTF();
10208                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10209                    }
10210                }
10211            }
10212        } catch (FileNotFoundException e) {
10213        } catch (IOException e) {
10214            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10215        } finally {
10216            if (fis != null) {
10217                try {
10218                    fis.close();
10219                } catch (IOException e) {
10220                }
10221            }
10222        }
10223        return lastDoneReceivers;
10224    }
10225
10226    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10227        File file = getCalledPreBootReceiversFile();
10228        FileOutputStream fos = null;
10229        DataOutputStream dos = null;
10230        try {
10231            fos = new FileOutputStream(file);
10232            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10233            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10234            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10235            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10236            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10237            dos.writeInt(list.size());
10238            for (int i=0; i<list.size(); i++) {
10239                dos.writeUTF(list.get(i).getPackageName());
10240                dos.writeUTF(list.get(i).getClassName());
10241            }
10242        } catch (IOException e) {
10243            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10244            file.delete();
10245        } finally {
10246            FileUtils.sync(fos);
10247            if (dos != null) {
10248                try {
10249                    dos.close();
10250                } catch (IOException e) {
10251                    // TODO Auto-generated catch block
10252                    e.printStackTrace();
10253                }
10254            }
10255        }
10256    }
10257
10258    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10259            ArrayList<ComponentName> doneReceivers, int userId) {
10260        boolean waitingUpdate = false;
10261        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10262        List<ResolveInfo> ris = null;
10263        try {
10264            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10265                    intent, null, 0, userId);
10266        } catch (RemoteException e) {
10267        }
10268        if (ris != null) {
10269            for (int i=ris.size()-1; i>=0; i--) {
10270                if ((ris.get(i).activityInfo.applicationInfo.flags
10271                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10272                    ris.remove(i);
10273                }
10274            }
10275            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10276
10277            // For User 0, load the version number. When delivering to a new user, deliver
10278            // to all receivers.
10279            if (userId == UserHandle.USER_OWNER) {
10280                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10281                for (int i=0; i<ris.size(); i++) {
10282                    ActivityInfo ai = ris.get(i).activityInfo;
10283                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10284                    if (lastDoneReceivers.contains(comp)) {
10285                        // We already did the pre boot receiver for this app with the current
10286                        // platform version, so don't do it again...
10287                        ris.remove(i);
10288                        i--;
10289                        // ...however, do keep it as one that has been done, so we don't
10290                        // forget about it when rewriting the file of last done receivers.
10291                        doneReceivers.add(comp);
10292                    }
10293                }
10294            }
10295
10296            // If primary user, send broadcast to all available users, else just to userId
10297            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10298                    : new int[] { userId };
10299            for (int i = 0; i < ris.size(); i++) {
10300                ActivityInfo ai = ris.get(i).activityInfo;
10301                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10302                doneReceivers.add(comp);
10303                intent.setComponent(comp);
10304                for (int j=0; j<users.length; j++) {
10305                    IIntentReceiver finisher = null;
10306                    // On last receiver and user, set up a completion callback
10307                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10308                        finisher = new IIntentReceiver.Stub() {
10309                            public void performReceive(Intent intent, int resultCode,
10310                                    String data, Bundle extras, boolean ordered,
10311                                    boolean sticky, int sendingUser) {
10312                                // The raw IIntentReceiver interface is called
10313                                // with the AM lock held, so redispatch to
10314                                // execute our code without the lock.
10315                                mHandler.post(onFinishCallback);
10316                            }
10317                        };
10318                    }
10319                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10320                            + " for user " + users[j]);
10321                    broadcastIntentLocked(null, null, intent, null, finisher,
10322                            0, null, null, null, AppOpsManager.OP_NONE,
10323                            true, false, MY_PID, Process.SYSTEM_UID,
10324                            users[j]);
10325                    if (finisher != null) {
10326                        waitingUpdate = true;
10327                    }
10328                }
10329            }
10330        }
10331
10332        return waitingUpdate;
10333    }
10334
10335    public void systemReady(final Runnable goingCallback) {
10336        synchronized(this) {
10337            if (mSystemReady) {
10338                // If we're done calling all the receivers, run the next "boot phase" passed in
10339                // by the SystemServer
10340                if (goingCallback != null) {
10341                    goingCallback.run();
10342                }
10343                return;
10344            }
10345
10346            // Make sure we have the current profile info, since it is needed for
10347            // security checks.
10348            updateCurrentProfileIdsLocked();
10349
10350            if (mRecentTasks == null) {
10351                mRecentTasks = mTaskPersister.restoreTasksLocked();
10352                if (!mRecentTasks.isEmpty()) {
10353                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10354                }
10355                mTaskPersister.startPersisting();
10356            }
10357
10358            // Check to see if there are any update receivers to run.
10359            if (!mDidUpdate) {
10360                if (mWaitingUpdate) {
10361                    return;
10362                }
10363                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10364                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10365                    public void run() {
10366                        synchronized (ActivityManagerService.this) {
10367                            mDidUpdate = true;
10368                        }
10369                        writeLastDonePreBootReceivers(doneReceivers);
10370                        showBootMessage(mContext.getText(
10371                                R.string.android_upgrading_complete),
10372                                false);
10373                        systemReady(goingCallback);
10374                    }
10375                }, doneReceivers, UserHandle.USER_OWNER);
10376
10377                if (mWaitingUpdate) {
10378                    return;
10379                }
10380                mDidUpdate = true;
10381            }
10382
10383            mAppOpsService.systemReady();
10384            mSystemReady = true;
10385        }
10386
10387        ArrayList<ProcessRecord> procsToKill = null;
10388        synchronized(mPidsSelfLocked) {
10389            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10390                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10391                if (!isAllowedWhileBooting(proc.info)){
10392                    if (procsToKill == null) {
10393                        procsToKill = new ArrayList<ProcessRecord>();
10394                    }
10395                    procsToKill.add(proc);
10396                }
10397            }
10398        }
10399
10400        synchronized(this) {
10401            if (procsToKill != null) {
10402                for (int i=procsToKill.size()-1; i>=0; i--) {
10403                    ProcessRecord proc = procsToKill.get(i);
10404                    Slog.i(TAG, "Removing system update proc: " + proc);
10405                    removeProcessLocked(proc, true, false, "system update done");
10406                }
10407            }
10408
10409            // Now that we have cleaned up any update processes, we
10410            // are ready to start launching real processes and know that
10411            // we won't trample on them any more.
10412            mProcessesReady = true;
10413        }
10414
10415        Slog.i(TAG, "System now ready");
10416        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10417            SystemClock.uptimeMillis());
10418
10419        synchronized(this) {
10420            // Make sure we have no pre-ready processes sitting around.
10421
10422            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10423                ResolveInfo ri = mContext.getPackageManager()
10424                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10425                                STOCK_PM_FLAGS);
10426                CharSequence errorMsg = null;
10427                if (ri != null) {
10428                    ActivityInfo ai = ri.activityInfo;
10429                    ApplicationInfo app = ai.applicationInfo;
10430                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10431                        mTopAction = Intent.ACTION_FACTORY_TEST;
10432                        mTopData = null;
10433                        mTopComponent = new ComponentName(app.packageName,
10434                                ai.name);
10435                    } else {
10436                        errorMsg = mContext.getResources().getText(
10437                                com.android.internal.R.string.factorytest_not_system);
10438                    }
10439                } else {
10440                    errorMsg = mContext.getResources().getText(
10441                            com.android.internal.R.string.factorytest_no_action);
10442                }
10443                if (errorMsg != null) {
10444                    mTopAction = null;
10445                    mTopData = null;
10446                    mTopComponent = null;
10447                    Message msg = Message.obtain();
10448                    msg.what = SHOW_FACTORY_ERROR_MSG;
10449                    msg.getData().putCharSequence("msg", errorMsg);
10450                    mHandler.sendMessage(msg);
10451                }
10452            }
10453        }
10454
10455        retrieveSettings();
10456
10457        synchronized (this) {
10458            readGrantedUriPermissionsLocked();
10459        }
10460
10461        if (goingCallback != null) goingCallback.run();
10462
10463        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10464                Integer.toString(mCurrentUserId), mCurrentUserId);
10465        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10466                Integer.toString(mCurrentUserId), mCurrentUserId);
10467        mSystemServiceManager.startUser(mCurrentUserId);
10468
10469        synchronized (this) {
10470            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10471                try {
10472                    List apps = AppGlobals.getPackageManager().
10473                        getPersistentApplications(STOCK_PM_FLAGS);
10474                    if (apps != null) {
10475                        int N = apps.size();
10476                        int i;
10477                        for (i=0; i<N; i++) {
10478                            ApplicationInfo info
10479                                = (ApplicationInfo)apps.get(i);
10480                            if (info != null &&
10481                                    !info.packageName.equals("android")) {
10482                                addAppLocked(info, false, null /* ABI override */);
10483                            }
10484                        }
10485                    }
10486                } catch (RemoteException ex) {
10487                    // pm is in same process, this will never happen.
10488                }
10489            }
10490
10491            // Start up initial activity.
10492            mBooting = true;
10493
10494            try {
10495                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10496                    Message msg = Message.obtain();
10497                    msg.what = SHOW_UID_ERROR_MSG;
10498                    mHandler.sendMessage(msg);
10499                }
10500            } catch (RemoteException e) {
10501            }
10502
10503            long ident = Binder.clearCallingIdentity();
10504            try {
10505                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10506                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10507                        | Intent.FLAG_RECEIVER_FOREGROUND);
10508                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10509                broadcastIntentLocked(null, null, intent,
10510                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10511                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10512                intent = new Intent(Intent.ACTION_USER_STARTING);
10513                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10514                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10515                broadcastIntentLocked(null, null, intent,
10516                        null, new IIntentReceiver.Stub() {
10517                            @Override
10518                            public void performReceive(Intent intent, int resultCode, String data,
10519                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10520                                    throws RemoteException {
10521                            }
10522                        }, 0, null, null,
10523                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10524                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10525            } catch (Throwable t) {
10526                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10527            } finally {
10528                Binder.restoreCallingIdentity(ident);
10529            }
10530            mStackSupervisor.resumeTopActivitiesLocked();
10531            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10532        }
10533    }
10534
10535    private boolean makeAppCrashingLocked(ProcessRecord app,
10536            String shortMsg, String longMsg, String stackTrace) {
10537        app.crashing = true;
10538        app.crashingReport = generateProcessError(app,
10539                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10540        startAppProblemLocked(app);
10541        app.stopFreezingAllLocked();
10542        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10543    }
10544
10545    private void makeAppNotRespondingLocked(ProcessRecord app,
10546            String activity, String shortMsg, String longMsg) {
10547        app.notResponding = true;
10548        app.notRespondingReport = generateProcessError(app,
10549                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10550                activity, shortMsg, longMsg, null);
10551        startAppProblemLocked(app);
10552        app.stopFreezingAllLocked();
10553    }
10554
10555    /**
10556     * Generate a process error record, suitable for attachment to a ProcessRecord.
10557     *
10558     * @param app The ProcessRecord in which the error occurred.
10559     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10560     *                      ActivityManager.AppErrorStateInfo
10561     * @param activity The activity associated with the crash, if known.
10562     * @param shortMsg Short message describing the crash.
10563     * @param longMsg Long message describing the crash.
10564     * @param stackTrace Full crash stack trace, may be null.
10565     *
10566     * @return Returns a fully-formed AppErrorStateInfo record.
10567     */
10568    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10569            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10570        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10571
10572        report.condition = condition;
10573        report.processName = app.processName;
10574        report.pid = app.pid;
10575        report.uid = app.info.uid;
10576        report.tag = activity;
10577        report.shortMsg = shortMsg;
10578        report.longMsg = longMsg;
10579        report.stackTrace = stackTrace;
10580
10581        return report;
10582    }
10583
10584    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10585        synchronized (this) {
10586            app.crashing = false;
10587            app.crashingReport = null;
10588            app.notResponding = false;
10589            app.notRespondingReport = null;
10590            if (app.anrDialog == fromDialog) {
10591                app.anrDialog = null;
10592            }
10593            if (app.waitDialog == fromDialog) {
10594                app.waitDialog = null;
10595            }
10596            if (app.pid > 0 && app.pid != MY_PID) {
10597                handleAppCrashLocked(app, null, null, null);
10598                killUnneededProcessLocked(app, "user request after error");
10599            }
10600        }
10601    }
10602
10603    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10604            String stackTrace) {
10605        long now = SystemClock.uptimeMillis();
10606
10607        Long crashTime;
10608        if (!app.isolated) {
10609            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10610        } else {
10611            crashTime = null;
10612        }
10613        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10614            // This process loses!
10615            Slog.w(TAG, "Process " + app.info.processName
10616                    + " has crashed too many times: killing!");
10617            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10618                    app.userId, app.info.processName, app.uid);
10619            mStackSupervisor.handleAppCrashLocked(app);
10620            if (!app.persistent) {
10621                // We don't want to start this process again until the user
10622                // explicitly does so...  but for persistent process, we really
10623                // need to keep it running.  If a persistent process is actually
10624                // repeatedly crashing, then badness for everyone.
10625                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10626                        app.info.processName);
10627                if (!app.isolated) {
10628                    // XXX We don't have a way to mark isolated processes
10629                    // as bad, since they don't have a peristent identity.
10630                    mBadProcesses.put(app.info.processName, app.uid,
10631                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10632                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10633                }
10634                app.bad = true;
10635                app.removed = true;
10636                // Don't let services in this process be restarted and potentially
10637                // annoy the user repeatedly.  Unless it is persistent, since those
10638                // processes run critical code.
10639                removeProcessLocked(app, false, false, "crash");
10640                mStackSupervisor.resumeTopActivitiesLocked();
10641                return false;
10642            }
10643            mStackSupervisor.resumeTopActivitiesLocked();
10644        } else {
10645            mStackSupervisor.finishTopRunningActivityLocked(app);
10646        }
10647
10648        // Bump up the crash count of any services currently running in the proc.
10649        for (int i=app.services.size()-1; i>=0; i--) {
10650            // Any services running in the application need to be placed
10651            // back in the pending list.
10652            ServiceRecord sr = app.services.valueAt(i);
10653            sr.crashCount++;
10654        }
10655
10656        // If the crashing process is what we consider to be the "home process" and it has been
10657        // replaced by a third-party app, clear the package preferred activities from packages
10658        // with a home activity running in the process to prevent a repeatedly crashing app
10659        // from blocking the user to manually clear the list.
10660        final ArrayList<ActivityRecord> activities = app.activities;
10661        if (app == mHomeProcess && activities.size() > 0
10662                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10663            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10664                final ActivityRecord r = activities.get(activityNdx);
10665                if (r.isHomeActivity()) {
10666                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10667                    try {
10668                        ActivityThread.getPackageManager()
10669                                .clearPackagePreferredActivities(r.packageName);
10670                    } catch (RemoteException c) {
10671                        // pm is in same process, this will never happen.
10672                    }
10673                }
10674            }
10675        }
10676
10677        if (!app.isolated) {
10678            // XXX Can't keep track of crash times for isolated processes,
10679            // because they don't have a perisistent identity.
10680            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10681        }
10682
10683        if (app.crashHandler != null) mHandler.post(app.crashHandler);
10684        return true;
10685    }
10686
10687    void startAppProblemLocked(ProcessRecord app) {
10688        // If this app is not running under the current user, then we
10689        // can't give it a report button because that would require
10690        // launching the report UI under a different user.
10691        app.errorReportReceiver = null;
10692
10693        for (int userId : mCurrentProfileIds) {
10694            if (app.userId == userId) {
10695                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10696                        mContext, app.info.packageName, app.info.flags);
10697            }
10698        }
10699        skipCurrentReceiverLocked(app);
10700    }
10701
10702    void skipCurrentReceiverLocked(ProcessRecord app) {
10703        for (BroadcastQueue queue : mBroadcastQueues) {
10704            queue.skipCurrentReceiverLocked(app);
10705        }
10706    }
10707
10708    /**
10709     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10710     * The application process will exit immediately after this call returns.
10711     * @param app object of the crashing app, null for the system server
10712     * @param crashInfo describing the exception
10713     */
10714    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10715        ProcessRecord r = findAppProcess(app, "Crash");
10716        final String processName = app == null ? "system_server"
10717                : (r == null ? "unknown" : r.processName);
10718
10719        handleApplicationCrashInner("crash", r, processName, crashInfo);
10720    }
10721
10722    /* Native crash reporting uses this inner version because it needs to be somewhat
10723     * decoupled from the AM-managed cleanup lifecycle
10724     */
10725    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10726            ApplicationErrorReport.CrashInfo crashInfo) {
10727        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10728                UserHandle.getUserId(Binder.getCallingUid()), processName,
10729                r == null ? -1 : r.info.flags,
10730                crashInfo.exceptionClassName,
10731                crashInfo.exceptionMessage,
10732                crashInfo.throwFileName,
10733                crashInfo.throwLineNumber);
10734
10735        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10736
10737        crashApplication(r, crashInfo);
10738    }
10739
10740    public void handleApplicationStrictModeViolation(
10741            IBinder app,
10742            int violationMask,
10743            StrictMode.ViolationInfo info) {
10744        ProcessRecord r = findAppProcess(app, "StrictMode");
10745        if (r == null) {
10746            return;
10747        }
10748
10749        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10750            Integer stackFingerprint = info.hashCode();
10751            boolean logIt = true;
10752            synchronized (mAlreadyLoggedViolatedStacks) {
10753                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10754                    logIt = false;
10755                    // TODO: sub-sample into EventLog for these, with
10756                    // the info.durationMillis?  Then we'd get
10757                    // the relative pain numbers, without logging all
10758                    // the stack traces repeatedly.  We'd want to do
10759                    // likewise in the client code, which also does
10760                    // dup suppression, before the Binder call.
10761                } else {
10762                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10763                        mAlreadyLoggedViolatedStacks.clear();
10764                    }
10765                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10766                }
10767            }
10768            if (logIt) {
10769                logStrictModeViolationToDropBox(r, info);
10770            }
10771        }
10772
10773        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10774            AppErrorResult result = new AppErrorResult();
10775            synchronized (this) {
10776                final long origId = Binder.clearCallingIdentity();
10777
10778                Message msg = Message.obtain();
10779                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10780                HashMap<String, Object> data = new HashMap<String, Object>();
10781                data.put("result", result);
10782                data.put("app", r);
10783                data.put("violationMask", violationMask);
10784                data.put("info", info);
10785                msg.obj = data;
10786                mHandler.sendMessage(msg);
10787
10788                Binder.restoreCallingIdentity(origId);
10789            }
10790            int res = result.get();
10791            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10792        }
10793    }
10794
10795    // Depending on the policy in effect, there could be a bunch of
10796    // these in quick succession so we try to batch these together to
10797    // minimize disk writes, number of dropbox entries, and maximize
10798    // compression, by having more fewer, larger records.
10799    private void logStrictModeViolationToDropBox(
10800            ProcessRecord process,
10801            StrictMode.ViolationInfo info) {
10802        if (info == null) {
10803            return;
10804        }
10805        final boolean isSystemApp = process == null ||
10806                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10807                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10808        final String processName = process == null ? "unknown" : process.processName;
10809        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10810        final DropBoxManager dbox = (DropBoxManager)
10811                mContext.getSystemService(Context.DROPBOX_SERVICE);
10812
10813        // Exit early if the dropbox isn't configured to accept this report type.
10814        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10815
10816        boolean bufferWasEmpty;
10817        boolean needsFlush;
10818        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10819        synchronized (sb) {
10820            bufferWasEmpty = sb.length() == 0;
10821            appendDropBoxProcessHeaders(process, processName, sb);
10822            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10823            sb.append("System-App: ").append(isSystemApp).append("\n");
10824            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10825            if (info.violationNumThisLoop != 0) {
10826                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10827            }
10828            if (info.numAnimationsRunning != 0) {
10829                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10830            }
10831            if (info.broadcastIntentAction != null) {
10832                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10833            }
10834            if (info.durationMillis != -1) {
10835                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10836            }
10837            if (info.numInstances != -1) {
10838                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10839            }
10840            if (info.tags != null) {
10841                for (String tag : info.tags) {
10842                    sb.append("Span-Tag: ").append(tag).append("\n");
10843                }
10844            }
10845            sb.append("\n");
10846            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10847                sb.append(info.crashInfo.stackTrace);
10848            }
10849            sb.append("\n");
10850
10851            // Only buffer up to ~64k.  Various logging bits truncate
10852            // things at 128k.
10853            needsFlush = (sb.length() > 64 * 1024);
10854        }
10855
10856        // Flush immediately if the buffer's grown too large, or this
10857        // is a non-system app.  Non-system apps are isolated with a
10858        // different tag & policy and not batched.
10859        //
10860        // Batching is useful during internal testing with
10861        // StrictMode settings turned up high.  Without batching,
10862        // thousands of separate files could be created on boot.
10863        if (!isSystemApp || needsFlush) {
10864            new Thread("Error dump: " + dropboxTag) {
10865                @Override
10866                public void run() {
10867                    String report;
10868                    synchronized (sb) {
10869                        report = sb.toString();
10870                        sb.delete(0, sb.length());
10871                        sb.trimToSize();
10872                    }
10873                    if (report.length() != 0) {
10874                        dbox.addText(dropboxTag, report);
10875                    }
10876                }
10877            }.start();
10878            return;
10879        }
10880
10881        // System app batching:
10882        if (!bufferWasEmpty) {
10883            // An existing dropbox-writing thread is outstanding, so
10884            // we don't need to start it up.  The existing thread will
10885            // catch the buffer appends we just did.
10886            return;
10887        }
10888
10889        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10890        // (After this point, we shouldn't access AMS internal data structures.)
10891        new Thread("Error dump: " + dropboxTag) {
10892            @Override
10893            public void run() {
10894                // 5 second sleep to let stacks arrive and be batched together
10895                try {
10896                    Thread.sleep(5000);  // 5 seconds
10897                } catch (InterruptedException e) {}
10898
10899                String errorReport;
10900                synchronized (mStrictModeBuffer) {
10901                    errorReport = mStrictModeBuffer.toString();
10902                    if (errorReport.length() == 0) {
10903                        return;
10904                    }
10905                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10906                    mStrictModeBuffer.trimToSize();
10907                }
10908                dbox.addText(dropboxTag, errorReport);
10909            }
10910        }.start();
10911    }
10912
10913    /**
10914     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10915     * @param app object of the crashing app, null for the system server
10916     * @param tag reported by the caller
10917     * @param crashInfo describing the context of the error
10918     * @return true if the process should exit immediately (WTF is fatal)
10919     */
10920    public boolean handleApplicationWtf(IBinder app, String tag,
10921            ApplicationErrorReport.CrashInfo crashInfo) {
10922        ProcessRecord r = findAppProcess(app, "WTF");
10923        final String processName = app == null ? "system_server"
10924                : (r == null ? "unknown" : r.processName);
10925
10926        EventLog.writeEvent(EventLogTags.AM_WTF,
10927                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10928                processName,
10929                r == null ? -1 : r.info.flags,
10930                tag, crashInfo.exceptionMessage);
10931
10932        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10933
10934        if (r != null && r.pid != Process.myPid() &&
10935                Settings.Global.getInt(mContext.getContentResolver(),
10936                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10937            crashApplication(r, crashInfo);
10938            return true;
10939        } else {
10940            return false;
10941        }
10942    }
10943
10944    /**
10945     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10946     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10947     */
10948    private ProcessRecord findAppProcess(IBinder app, String reason) {
10949        if (app == null) {
10950            return null;
10951        }
10952
10953        synchronized (this) {
10954            final int NP = mProcessNames.getMap().size();
10955            for (int ip=0; ip<NP; ip++) {
10956                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10957                final int NA = apps.size();
10958                for (int ia=0; ia<NA; ia++) {
10959                    ProcessRecord p = apps.valueAt(ia);
10960                    if (p.thread != null && p.thread.asBinder() == app) {
10961                        return p;
10962                    }
10963                }
10964            }
10965
10966            Slog.w(TAG, "Can't find mystery application for " + reason
10967                    + " from pid=" + Binder.getCallingPid()
10968                    + " uid=" + Binder.getCallingUid() + ": " + app);
10969            return null;
10970        }
10971    }
10972
10973    /**
10974     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10975     * to append various headers to the dropbox log text.
10976     */
10977    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10978            StringBuilder sb) {
10979        // Watchdog thread ends up invoking this function (with
10980        // a null ProcessRecord) to add the stack file to dropbox.
10981        // Do not acquire a lock on this (am) in such cases, as it
10982        // could cause a potential deadlock, if and when watchdog
10983        // is invoked due to unavailability of lock on am and it
10984        // would prevent watchdog from killing system_server.
10985        if (process == null) {
10986            sb.append("Process: ").append(processName).append("\n");
10987            return;
10988        }
10989        // Note: ProcessRecord 'process' is guarded by the service
10990        // instance.  (notably process.pkgList, which could otherwise change
10991        // concurrently during execution of this method)
10992        synchronized (this) {
10993            sb.append("Process: ").append(processName).append("\n");
10994            int flags = process.info.flags;
10995            IPackageManager pm = AppGlobals.getPackageManager();
10996            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10997            for (int ip=0; ip<process.pkgList.size(); ip++) {
10998                String pkg = process.pkgList.keyAt(ip);
10999                sb.append("Package: ").append(pkg);
11000                try {
11001                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11002                    if (pi != null) {
11003                        sb.append(" v").append(pi.versionCode);
11004                        if (pi.versionName != null) {
11005                            sb.append(" (").append(pi.versionName).append(")");
11006                        }
11007                    }
11008                } catch (RemoteException e) {
11009                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11010                }
11011                sb.append("\n");
11012            }
11013        }
11014    }
11015
11016    private static String processClass(ProcessRecord process) {
11017        if (process == null || process.pid == MY_PID) {
11018            return "system_server";
11019        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11020            return "system_app";
11021        } else {
11022            return "data_app";
11023        }
11024    }
11025
11026    /**
11027     * Write a description of an error (crash, WTF, ANR) to the drop box.
11028     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11029     * @param process which caused the error, null means the system server
11030     * @param activity which triggered the error, null if unknown
11031     * @param parent activity related to the error, null if unknown
11032     * @param subject line related to the error, null if absent
11033     * @param report in long form describing the error, null if absent
11034     * @param logFile to include in the report, null if none
11035     * @param crashInfo giving an application stack trace, null if absent
11036     */
11037    public void addErrorToDropBox(String eventType,
11038            ProcessRecord process, String processName, ActivityRecord activity,
11039            ActivityRecord parent, String subject,
11040            final String report, final File logFile,
11041            final ApplicationErrorReport.CrashInfo crashInfo) {
11042        // NOTE -- this must never acquire the ActivityManagerService lock,
11043        // otherwise the watchdog may be prevented from resetting the system.
11044
11045        final String dropboxTag = processClass(process) + "_" + eventType;
11046        final DropBoxManager dbox = (DropBoxManager)
11047                mContext.getSystemService(Context.DROPBOX_SERVICE);
11048
11049        // Exit early if the dropbox isn't configured to accept this report type.
11050        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11051
11052        final StringBuilder sb = new StringBuilder(1024);
11053        appendDropBoxProcessHeaders(process, processName, sb);
11054        if (activity != null) {
11055            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11056        }
11057        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11058            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11059        }
11060        if (parent != null && parent != activity) {
11061            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11062        }
11063        if (subject != null) {
11064            sb.append("Subject: ").append(subject).append("\n");
11065        }
11066        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11067        if (Debug.isDebuggerConnected()) {
11068            sb.append("Debugger: Connected\n");
11069        }
11070        sb.append("\n");
11071
11072        // Do the rest in a worker thread to avoid blocking the caller on I/O
11073        // (After this point, we shouldn't access AMS internal data structures.)
11074        Thread worker = new Thread("Error dump: " + dropboxTag) {
11075            @Override
11076            public void run() {
11077                if (report != null) {
11078                    sb.append(report);
11079                }
11080                if (logFile != null) {
11081                    try {
11082                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11083                                    "\n\n[[TRUNCATED]]"));
11084                    } catch (IOException e) {
11085                        Slog.e(TAG, "Error reading " + logFile, e);
11086                    }
11087                }
11088                if (crashInfo != null && crashInfo.stackTrace != null) {
11089                    sb.append(crashInfo.stackTrace);
11090                }
11091
11092                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11093                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11094                if (lines > 0) {
11095                    sb.append("\n");
11096
11097                    // Merge several logcat streams, and take the last N lines
11098                    InputStreamReader input = null;
11099                    try {
11100                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11101                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11102                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11103
11104                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11105                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11106                        input = new InputStreamReader(logcat.getInputStream());
11107
11108                        int num;
11109                        char[] buf = new char[8192];
11110                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11111                    } catch (IOException e) {
11112                        Slog.e(TAG, "Error running logcat", e);
11113                    } finally {
11114                        if (input != null) try { input.close(); } catch (IOException e) {}
11115                    }
11116                }
11117
11118                dbox.addText(dropboxTag, sb.toString());
11119            }
11120        };
11121
11122        if (process == null) {
11123            // If process is null, we are being called from some internal code
11124            // and may be about to die -- run this synchronously.
11125            worker.run();
11126        } else {
11127            worker.start();
11128        }
11129    }
11130
11131    /**
11132     * Bring up the "unexpected error" dialog box for a crashing app.
11133     * Deal with edge cases (intercepts from instrumented applications,
11134     * ActivityController, error intent receivers, that sort of thing).
11135     * @param r the application crashing
11136     * @param crashInfo describing the failure
11137     */
11138    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11139        long timeMillis = System.currentTimeMillis();
11140        String shortMsg = crashInfo.exceptionClassName;
11141        String longMsg = crashInfo.exceptionMessage;
11142        String stackTrace = crashInfo.stackTrace;
11143        if (shortMsg != null && longMsg != null) {
11144            longMsg = shortMsg + ": " + longMsg;
11145        } else if (shortMsg != null) {
11146            longMsg = shortMsg;
11147        }
11148
11149        AppErrorResult result = new AppErrorResult();
11150        synchronized (this) {
11151            if (mController != null) {
11152                try {
11153                    String name = r != null ? r.processName : null;
11154                    int pid = r != null ? r.pid : Binder.getCallingPid();
11155                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11156                    if (!mController.appCrashed(name, pid,
11157                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11158                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11159                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11160                            Slog.w(TAG, "Skip killing native crashed app " + name
11161                                    + "(" + pid + ") during testing");
11162                        } else {
11163                            Slog.w(TAG, "Force-killing crashed app " + name
11164                                    + " at watcher's request");
11165                            Process.killProcess(pid);
11166                            if (r != null) {
11167                                Process.killProcessGroup(uid, pid);
11168                            }
11169                        }
11170                        return;
11171                    }
11172                } catch (RemoteException e) {
11173                    mController = null;
11174                    Watchdog.getInstance().setActivityController(null);
11175                }
11176            }
11177
11178            final long origId = Binder.clearCallingIdentity();
11179
11180            // If this process is running instrumentation, finish it.
11181            if (r != null && r.instrumentationClass != null) {
11182                Slog.w(TAG, "Error in app " + r.processName
11183                      + " running instrumentation " + r.instrumentationClass + ":");
11184                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11185                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11186                Bundle info = new Bundle();
11187                info.putString("shortMsg", shortMsg);
11188                info.putString("longMsg", longMsg);
11189                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11190                Binder.restoreCallingIdentity(origId);
11191                return;
11192            }
11193
11194            // If we can't identify the process or it's already exceeded its crash quota,
11195            // quit right away without showing a crash dialog.
11196            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11197                Binder.restoreCallingIdentity(origId);
11198                return;
11199            }
11200
11201            Message msg = Message.obtain();
11202            msg.what = SHOW_ERROR_MSG;
11203            HashMap data = new HashMap();
11204            data.put("result", result);
11205            data.put("app", r);
11206            msg.obj = data;
11207            mHandler.sendMessage(msg);
11208
11209            Binder.restoreCallingIdentity(origId);
11210        }
11211
11212        int res = result.get();
11213
11214        Intent appErrorIntent = null;
11215        synchronized (this) {
11216            if (r != null && !r.isolated) {
11217                // XXX Can't keep track of crash time for isolated processes,
11218                // since they don't have a persistent identity.
11219                mProcessCrashTimes.put(r.info.processName, r.uid,
11220                        SystemClock.uptimeMillis());
11221            }
11222            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11223                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11224            }
11225        }
11226
11227        if (appErrorIntent != null) {
11228            try {
11229                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11230            } catch (ActivityNotFoundException e) {
11231                Slog.w(TAG, "bug report receiver dissappeared", e);
11232            }
11233        }
11234    }
11235
11236    Intent createAppErrorIntentLocked(ProcessRecord r,
11237            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11238        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11239        if (report == null) {
11240            return null;
11241        }
11242        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11243        result.setComponent(r.errorReportReceiver);
11244        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11245        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11246        return result;
11247    }
11248
11249    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11250            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11251        if (r.errorReportReceiver == null) {
11252            return null;
11253        }
11254
11255        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11256            return null;
11257        }
11258
11259        ApplicationErrorReport report = new ApplicationErrorReport();
11260        report.packageName = r.info.packageName;
11261        report.installerPackageName = r.errorReportReceiver.getPackageName();
11262        report.processName = r.processName;
11263        report.time = timeMillis;
11264        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11265
11266        if (r.crashing || r.forceCrashReport) {
11267            report.type = ApplicationErrorReport.TYPE_CRASH;
11268            report.crashInfo = crashInfo;
11269        } else if (r.notResponding) {
11270            report.type = ApplicationErrorReport.TYPE_ANR;
11271            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11272
11273            report.anrInfo.activity = r.notRespondingReport.tag;
11274            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11275            report.anrInfo.info = r.notRespondingReport.longMsg;
11276        }
11277
11278        return report;
11279    }
11280
11281    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11282        enforceNotIsolatedCaller("getProcessesInErrorState");
11283        // assume our apps are happy - lazy create the list
11284        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11285
11286        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11287                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11288        int userId = UserHandle.getUserId(Binder.getCallingUid());
11289
11290        synchronized (this) {
11291
11292            // iterate across all processes
11293            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11294                ProcessRecord app = mLruProcesses.get(i);
11295                if (!allUsers && app.userId != userId) {
11296                    continue;
11297                }
11298                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11299                    // This one's in trouble, so we'll generate a report for it
11300                    // crashes are higher priority (in case there's a crash *and* an anr)
11301                    ActivityManager.ProcessErrorStateInfo report = null;
11302                    if (app.crashing) {
11303                        report = app.crashingReport;
11304                    } else if (app.notResponding) {
11305                        report = app.notRespondingReport;
11306                    }
11307
11308                    if (report != null) {
11309                        if (errList == null) {
11310                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11311                        }
11312                        errList.add(report);
11313                    } else {
11314                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11315                                " crashing = " + app.crashing +
11316                                " notResponding = " + app.notResponding);
11317                    }
11318                }
11319            }
11320        }
11321
11322        return errList;
11323    }
11324
11325    static int procStateToImportance(int procState, int memAdj,
11326            ActivityManager.RunningAppProcessInfo currApp) {
11327        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11328        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11329            currApp.lru = memAdj;
11330        } else {
11331            currApp.lru = 0;
11332        }
11333        return imp;
11334    }
11335
11336    private void fillInProcMemInfo(ProcessRecord app,
11337            ActivityManager.RunningAppProcessInfo outInfo) {
11338        outInfo.pid = app.pid;
11339        outInfo.uid = app.info.uid;
11340        if (mHeavyWeightProcess == app) {
11341            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11342        }
11343        if (app.persistent) {
11344            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11345        }
11346        if (app.activities.size() > 0) {
11347            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11348        }
11349        outInfo.lastTrimLevel = app.trimMemoryLevel;
11350        int adj = app.curAdj;
11351        int procState = app.curProcState;
11352        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11353        outInfo.importanceReasonCode = app.adjTypeCode;
11354        outInfo.processState = app.curProcState;
11355    }
11356
11357    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11358        enforceNotIsolatedCaller("getRunningAppProcesses");
11359        // Lazy instantiation of list
11360        List<ActivityManager.RunningAppProcessInfo> runList = null;
11361        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11362                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11363        int userId = UserHandle.getUserId(Binder.getCallingUid());
11364        synchronized (this) {
11365            // Iterate across all processes
11366            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11367                ProcessRecord app = mLruProcesses.get(i);
11368                if (!allUsers && app.userId != userId) {
11369                    continue;
11370                }
11371                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11372                    // Generate process state info for running application
11373                    ActivityManager.RunningAppProcessInfo currApp =
11374                        new ActivityManager.RunningAppProcessInfo(app.processName,
11375                                app.pid, app.getPackageList());
11376                    fillInProcMemInfo(app, currApp);
11377                    if (app.adjSource instanceof ProcessRecord) {
11378                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11379                        currApp.importanceReasonImportance =
11380                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11381                                        app.adjSourceProcState);
11382                    } else if (app.adjSource instanceof ActivityRecord) {
11383                        ActivityRecord r = (ActivityRecord)app.adjSource;
11384                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11385                    }
11386                    if (app.adjTarget instanceof ComponentName) {
11387                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11388                    }
11389                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11390                    //        + " lru=" + currApp.lru);
11391                    if (runList == null) {
11392                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11393                    }
11394                    runList.add(currApp);
11395                }
11396            }
11397        }
11398        return runList;
11399    }
11400
11401    public List<ApplicationInfo> getRunningExternalApplications() {
11402        enforceNotIsolatedCaller("getRunningExternalApplications");
11403        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11404        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11405        if (runningApps != null && runningApps.size() > 0) {
11406            Set<String> extList = new HashSet<String>();
11407            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11408                if (app.pkgList != null) {
11409                    for (String pkg : app.pkgList) {
11410                        extList.add(pkg);
11411                    }
11412                }
11413            }
11414            IPackageManager pm = AppGlobals.getPackageManager();
11415            for (String pkg : extList) {
11416                try {
11417                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11418                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11419                        retList.add(info);
11420                    }
11421                } catch (RemoteException e) {
11422                }
11423            }
11424        }
11425        return retList;
11426    }
11427
11428    @Override
11429    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11430        enforceNotIsolatedCaller("getMyMemoryState");
11431        synchronized (this) {
11432            ProcessRecord proc;
11433            synchronized (mPidsSelfLocked) {
11434                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11435            }
11436            fillInProcMemInfo(proc, outInfo);
11437        }
11438    }
11439
11440    @Override
11441    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11442        if (checkCallingPermission(android.Manifest.permission.DUMP)
11443                != PackageManager.PERMISSION_GRANTED) {
11444            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11445                    + Binder.getCallingPid()
11446                    + ", uid=" + Binder.getCallingUid()
11447                    + " without permission "
11448                    + android.Manifest.permission.DUMP);
11449            return;
11450        }
11451
11452        boolean dumpAll = false;
11453        boolean dumpClient = false;
11454        String dumpPackage = null;
11455
11456        int opti = 0;
11457        while (opti < args.length) {
11458            String opt = args[opti];
11459            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11460                break;
11461            }
11462            opti++;
11463            if ("-a".equals(opt)) {
11464                dumpAll = true;
11465            } else if ("-c".equals(opt)) {
11466                dumpClient = true;
11467            } else if ("-h".equals(opt)) {
11468                pw.println("Activity manager dump options:");
11469                pw.println("  [-a] [-c] [-h] [cmd] ...");
11470                pw.println("  cmd may be one of:");
11471                pw.println("    a[ctivities]: activity stack state");
11472                pw.println("    r[recents]: recent activities state");
11473                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11474                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11475                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11476                pw.println("    o[om]: out of memory management");
11477                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11478                pw.println("    provider [COMP_SPEC]: provider client-side state");
11479                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11480                pw.println("    service [COMP_SPEC]: service client-side state");
11481                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11482                pw.println("    all: dump all activities");
11483                pw.println("    top: dump the top activity");
11484                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11485                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11486                pw.println("    a partial substring in a component name, a");
11487                pw.println("    hex object identifier.");
11488                pw.println("  -a: include all available server state.");
11489                pw.println("  -c: include client state.");
11490                return;
11491            } else {
11492                pw.println("Unknown argument: " + opt + "; use -h for help");
11493            }
11494        }
11495
11496        long origId = Binder.clearCallingIdentity();
11497        boolean more = false;
11498        // Is the caller requesting to dump a particular piece of data?
11499        if (opti < args.length) {
11500            String cmd = args[opti];
11501            opti++;
11502            if ("activities".equals(cmd) || "a".equals(cmd)) {
11503                synchronized (this) {
11504                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11505                }
11506            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
11507                synchronized (this) {
11508                    dumpRecentsLocked(fd, pw, args, opti, true, null);
11509                }
11510            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11511                String[] newArgs;
11512                String name;
11513                if (opti >= args.length) {
11514                    name = null;
11515                    newArgs = EMPTY_STRING_ARRAY;
11516                } else {
11517                    name = args[opti];
11518                    opti++;
11519                    newArgs = new String[args.length - opti];
11520                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11521                            args.length - opti);
11522                }
11523                synchronized (this) {
11524                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11525                }
11526            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11527                String[] newArgs;
11528                String name;
11529                if (opti >= args.length) {
11530                    name = null;
11531                    newArgs = EMPTY_STRING_ARRAY;
11532                } else {
11533                    name = args[opti];
11534                    opti++;
11535                    newArgs = new String[args.length - opti];
11536                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11537                            args.length - opti);
11538                }
11539                synchronized (this) {
11540                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11541                }
11542            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11543                String[] newArgs;
11544                String name;
11545                if (opti >= args.length) {
11546                    name = null;
11547                    newArgs = EMPTY_STRING_ARRAY;
11548                } else {
11549                    name = args[opti];
11550                    opti++;
11551                    newArgs = new String[args.length - opti];
11552                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11553                            args.length - opti);
11554                }
11555                synchronized (this) {
11556                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11557                }
11558            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11559                synchronized (this) {
11560                    dumpOomLocked(fd, pw, args, opti, true);
11561                }
11562            } else if ("provider".equals(cmd)) {
11563                String[] newArgs;
11564                String name;
11565                if (opti >= args.length) {
11566                    name = null;
11567                    newArgs = EMPTY_STRING_ARRAY;
11568                } else {
11569                    name = args[opti];
11570                    opti++;
11571                    newArgs = new String[args.length - opti];
11572                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11573                }
11574                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11575                    pw.println("No providers match: " + name);
11576                    pw.println("Use -h for help.");
11577                }
11578            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11579                synchronized (this) {
11580                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11581                }
11582            } else if ("service".equals(cmd)) {
11583                String[] newArgs;
11584                String name;
11585                if (opti >= args.length) {
11586                    name = null;
11587                    newArgs = EMPTY_STRING_ARRAY;
11588                } else {
11589                    name = args[opti];
11590                    opti++;
11591                    newArgs = new String[args.length - opti];
11592                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11593                            args.length - opti);
11594                }
11595                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11596                    pw.println("No services match: " + name);
11597                    pw.println("Use -h for help.");
11598                }
11599            } else if ("package".equals(cmd)) {
11600                String[] newArgs;
11601                if (opti >= args.length) {
11602                    pw.println("package: no package name specified");
11603                    pw.println("Use -h for help.");
11604                } else {
11605                    dumpPackage = args[opti];
11606                    opti++;
11607                    newArgs = new String[args.length - opti];
11608                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11609                            args.length - opti);
11610                    args = newArgs;
11611                    opti = 0;
11612                    more = true;
11613                }
11614            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11615                synchronized (this) {
11616                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11617                }
11618            } else {
11619                // Dumping a single activity?
11620                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11621                    pw.println("Bad activity command, or no activities match: " + cmd);
11622                    pw.println("Use -h for help.");
11623                }
11624            }
11625            if (!more) {
11626                Binder.restoreCallingIdentity(origId);
11627                return;
11628            }
11629        }
11630
11631        // No piece of data specified, dump everything.
11632        synchronized (this) {
11633            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11634            pw.println();
11635            if (dumpAll) {
11636                pw.println("-------------------------------------------------------------------------------");
11637            }
11638            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11639            pw.println();
11640            if (dumpAll) {
11641                pw.println("-------------------------------------------------------------------------------");
11642            }
11643            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11644            pw.println();
11645            if (dumpAll) {
11646                pw.println("-------------------------------------------------------------------------------");
11647            }
11648            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11649            pw.println();
11650            if (dumpAll) {
11651                pw.println("-------------------------------------------------------------------------------");
11652            }
11653            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11654            pw.println();
11655            if (dumpAll) {
11656                pw.println("-------------------------------------------------------------------------------");
11657            }
11658            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11659            pw.println();
11660            if (dumpAll) {
11661                pw.println("-------------------------------------------------------------------------------");
11662            }
11663            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11664        }
11665        Binder.restoreCallingIdentity(origId);
11666    }
11667
11668    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11669            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11670        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11671
11672        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11673                dumpPackage);
11674        boolean needSep = printedAnything;
11675
11676        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11677                dumpPackage, needSep, "  mFocusedActivity: ");
11678        if (printed) {
11679            printedAnything = true;
11680            needSep = false;
11681        }
11682
11683        if (dumpPackage == null) {
11684            if (needSep) {
11685                pw.println();
11686            }
11687            needSep = true;
11688            printedAnything = true;
11689            mStackSupervisor.dump(pw, "  ");
11690        }
11691
11692        if (!printedAnything) {
11693            pw.println("  (nothing)");
11694        }
11695    }
11696
11697    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11698            int opti, boolean dumpAll, String dumpPackage) {
11699        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
11700
11701        boolean printedAnything = false;
11702
11703        if (mRecentTasks.size() > 0) {
11704            boolean printedHeader = false;
11705
11706            final int N = mRecentTasks.size();
11707            for (int i=0; i<N; i++) {
11708                TaskRecord tr = mRecentTasks.get(i);
11709                if (dumpPackage != null) {
11710                    if (tr.realActivity == null ||
11711                            !dumpPackage.equals(tr.realActivity)) {
11712                        continue;
11713                    }
11714                }
11715                if (!printedHeader) {
11716                    pw.println("  Recent tasks:");
11717                    printedHeader = true;
11718                    printedAnything = true;
11719                }
11720                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11721                        pw.println(tr);
11722                if (dumpAll) {
11723                    mRecentTasks.get(i).dump(pw, "    ");
11724                }
11725            }
11726        }
11727
11728        if (!printedAnything) {
11729            pw.println("  (nothing)");
11730        }
11731    }
11732
11733    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11734            int opti, boolean dumpAll, String dumpPackage) {
11735        boolean needSep = false;
11736        boolean printedAnything = false;
11737        int numPers = 0;
11738
11739        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11740
11741        if (dumpAll) {
11742            final int NP = mProcessNames.getMap().size();
11743            for (int ip=0; ip<NP; ip++) {
11744                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11745                final int NA = procs.size();
11746                for (int ia=0; ia<NA; ia++) {
11747                    ProcessRecord r = procs.valueAt(ia);
11748                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11749                        continue;
11750                    }
11751                    if (!needSep) {
11752                        pw.println("  All known processes:");
11753                        needSep = true;
11754                        printedAnything = true;
11755                    }
11756                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11757                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11758                        pw.print(" "); pw.println(r);
11759                    r.dump(pw, "    ");
11760                    if (r.persistent) {
11761                        numPers++;
11762                    }
11763                }
11764            }
11765        }
11766
11767        if (mIsolatedProcesses.size() > 0) {
11768            boolean printed = false;
11769            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11770                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11771                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11772                    continue;
11773                }
11774                if (!printed) {
11775                    if (needSep) {
11776                        pw.println();
11777                    }
11778                    pw.println("  Isolated process list (sorted by uid):");
11779                    printedAnything = true;
11780                    printed = true;
11781                    needSep = true;
11782                }
11783                pw.println(String.format("%sIsolated #%2d: %s",
11784                        "    ", i, r.toString()));
11785            }
11786        }
11787
11788        if (mLruProcesses.size() > 0) {
11789            if (needSep) {
11790                pw.println();
11791            }
11792            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11793                    pw.print(" total, non-act at ");
11794                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11795                    pw.print(", non-svc at ");
11796                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11797                    pw.println("):");
11798            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11799            needSep = true;
11800            printedAnything = true;
11801        }
11802
11803        if (dumpAll || dumpPackage != null) {
11804            synchronized (mPidsSelfLocked) {
11805                boolean printed = false;
11806                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11807                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11808                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11809                        continue;
11810                    }
11811                    if (!printed) {
11812                        if (needSep) pw.println();
11813                        needSep = true;
11814                        pw.println("  PID mappings:");
11815                        printed = true;
11816                        printedAnything = true;
11817                    }
11818                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11819                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11820                }
11821            }
11822        }
11823
11824        if (mForegroundProcesses.size() > 0) {
11825            synchronized (mPidsSelfLocked) {
11826                boolean printed = false;
11827                for (int i=0; i<mForegroundProcesses.size(); i++) {
11828                    ProcessRecord r = mPidsSelfLocked.get(
11829                            mForegroundProcesses.valueAt(i).pid);
11830                    if (dumpPackage != null && (r == null
11831                            || !r.pkgList.containsKey(dumpPackage))) {
11832                        continue;
11833                    }
11834                    if (!printed) {
11835                        if (needSep) pw.println();
11836                        needSep = true;
11837                        pw.println("  Foreground Processes:");
11838                        printed = true;
11839                        printedAnything = true;
11840                    }
11841                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11842                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11843                }
11844            }
11845        }
11846
11847        if (mPersistentStartingProcesses.size() > 0) {
11848            if (needSep) pw.println();
11849            needSep = true;
11850            printedAnything = true;
11851            pw.println("  Persisent processes that are starting:");
11852            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11853                    "Starting Norm", "Restarting PERS", dumpPackage);
11854        }
11855
11856        if (mRemovedProcesses.size() > 0) {
11857            if (needSep) pw.println();
11858            needSep = true;
11859            printedAnything = true;
11860            pw.println("  Processes that are being removed:");
11861            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11862                    "Removed Norm", "Removed PERS", dumpPackage);
11863        }
11864
11865        if (mProcessesOnHold.size() > 0) {
11866            if (needSep) pw.println();
11867            needSep = true;
11868            printedAnything = true;
11869            pw.println("  Processes that are on old until the system is ready:");
11870            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11871                    "OnHold Norm", "OnHold PERS", dumpPackage);
11872        }
11873
11874        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11875
11876        if (mProcessCrashTimes.getMap().size() > 0) {
11877            boolean printed = false;
11878            long now = SystemClock.uptimeMillis();
11879            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11880            final int NP = pmap.size();
11881            for (int ip=0; ip<NP; ip++) {
11882                String pname = pmap.keyAt(ip);
11883                SparseArray<Long> uids = pmap.valueAt(ip);
11884                final int N = uids.size();
11885                for (int i=0; i<N; i++) {
11886                    int puid = uids.keyAt(i);
11887                    ProcessRecord r = mProcessNames.get(pname, puid);
11888                    if (dumpPackage != null && (r == null
11889                            || !r.pkgList.containsKey(dumpPackage))) {
11890                        continue;
11891                    }
11892                    if (!printed) {
11893                        if (needSep) pw.println();
11894                        needSep = true;
11895                        pw.println("  Time since processes crashed:");
11896                        printed = true;
11897                        printedAnything = true;
11898                    }
11899                    pw.print("    Process "); pw.print(pname);
11900                            pw.print(" uid "); pw.print(puid);
11901                            pw.print(": last crashed ");
11902                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11903                            pw.println(" ago");
11904                }
11905            }
11906        }
11907
11908        if (mBadProcesses.getMap().size() > 0) {
11909            boolean printed = false;
11910            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11911            final int NP = pmap.size();
11912            for (int ip=0; ip<NP; ip++) {
11913                String pname = pmap.keyAt(ip);
11914                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11915                final int N = uids.size();
11916                for (int i=0; i<N; i++) {
11917                    int puid = uids.keyAt(i);
11918                    ProcessRecord r = mProcessNames.get(pname, puid);
11919                    if (dumpPackage != null && (r == null
11920                            || !r.pkgList.containsKey(dumpPackage))) {
11921                        continue;
11922                    }
11923                    if (!printed) {
11924                        if (needSep) pw.println();
11925                        needSep = true;
11926                        pw.println("  Bad processes:");
11927                        printedAnything = true;
11928                    }
11929                    BadProcessInfo info = uids.valueAt(i);
11930                    pw.print("    Bad process "); pw.print(pname);
11931                            pw.print(" uid "); pw.print(puid);
11932                            pw.print(": crashed at time "); pw.println(info.time);
11933                    if (info.shortMsg != null) {
11934                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11935                    }
11936                    if (info.longMsg != null) {
11937                        pw.print("      Long msg: "); pw.println(info.longMsg);
11938                    }
11939                    if (info.stack != null) {
11940                        pw.println("      Stack:");
11941                        int lastPos = 0;
11942                        for (int pos=0; pos<info.stack.length(); pos++) {
11943                            if (info.stack.charAt(pos) == '\n') {
11944                                pw.print("        ");
11945                                pw.write(info.stack, lastPos, pos-lastPos);
11946                                pw.println();
11947                                lastPos = pos+1;
11948                            }
11949                        }
11950                        if (lastPos < info.stack.length()) {
11951                            pw.print("        ");
11952                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11953                            pw.println();
11954                        }
11955                    }
11956                }
11957            }
11958        }
11959
11960        if (dumpPackage == null) {
11961            pw.println();
11962            needSep = false;
11963            pw.println("  mStartedUsers:");
11964            for (int i=0; i<mStartedUsers.size(); i++) {
11965                UserStartedState uss = mStartedUsers.valueAt(i);
11966                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11967                        pw.print(": "); uss.dump("", pw);
11968            }
11969            pw.print("  mStartedUserArray: [");
11970            for (int i=0; i<mStartedUserArray.length; i++) {
11971                if (i > 0) pw.print(", ");
11972                pw.print(mStartedUserArray[i]);
11973            }
11974            pw.println("]");
11975            pw.print("  mUserLru: [");
11976            for (int i=0; i<mUserLru.size(); i++) {
11977                if (i > 0) pw.print(", ");
11978                pw.print(mUserLru.get(i));
11979            }
11980            pw.println("]");
11981            if (dumpAll) {
11982                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11983            }
11984            synchronized (mUserProfileGroupIdsSelfLocked) {
11985                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11986                    pw.println("  mUserProfileGroupIds:");
11987                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11988                        pw.print("    User #");
11989                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11990                        pw.print(" -> profile #");
11991                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11992                    }
11993                }
11994            }
11995        }
11996        if (mHomeProcess != null && (dumpPackage == null
11997                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11998            if (needSep) {
11999                pw.println();
12000                needSep = false;
12001            }
12002            pw.println("  mHomeProcess: " + mHomeProcess);
12003        }
12004        if (mPreviousProcess != null && (dumpPackage == null
12005                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12006            if (needSep) {
12007                pw.println();
12008                needSep = false;
12009            }
12010            pw.println("  mPreviousProcess: " + mPreviousProcess);
12011        }
12012        if (dumpAll) {
12013            StringBuilder sb = new StringBuilder(128);
12014            sb.append("  mPreviousProcessVisibleTime: ");
12015            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12016            pw.println(sb);
12017        }
12018        if (mHeavyWeightProcess != null && (dumpPackage == null
12019                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12020            if (needSep) {
12021                pw.println();
12022                needSep = false;
12023            }
12024            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12025        }
12026        if (dumpPackage == null) {
12027            pw.println("  mConfiguration: " + mConfiguration);
12028        }
12029        if (dumpAll) {
12030            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12031            if (mCompatModePackages.getPackages().size() > 0) {
12032                boolean printed = false;
12033                for (Map.Entry<String, Integer> entry
12034                        : mCompatModePackages.getPackages().entrySet()) {
12035                    String pkg = entry.getKey();
12036                    int mode = entry.getValue();
12037                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12038                        continue;
12039                    }
12040                    if (!printed) {
12041                        pw.println("  mScreenCompatPackages:");
12042                        printed = true;
12043                    }
12044                    pw.print("    "); pw.print(pkg); pw.print(": ");
12045                            pw.print(mode); pw.println();
12046                }
12047            }
12048        }
12049        if (dumpPackage == null) {
12050            if (mSleeping || mWentToSleep || mLockScreenShown) {
12051                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12052                        + " mLockScreenShown " + mLockScreenShown);
12053            }
12054            if (mShuttingDown || mRunningVoice) {
12055                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12056            }
12057        }
12058        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12059                || mOrigWaitForDebugger) {
12060            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12061                    || dumpPackage.equals(mOrigDebugApp)) {
12062                if (needSep) {
12063                    pw.println();
12064                    needSep = false;
12065                }
12066                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12067                        + " mDebugTransient=" + mDebugTransient
12068                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12069            }
12070        }
12071        if (mOpenGlTraceApp != null) {
12072            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12073                if (needSep) {
12074                    pw.println();
12075                    needSep = false;
12076                }
12077                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12078            }
12079        }
12080        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12081                || mProfileFd != null) {
12082            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12083                if (needSep) {
12084                    pw.println();
12085                    needSep = false;
12086                }
12087                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12088                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12089                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
12090                        + mAutoStopProfiler);
12091            }
12092        }
12093        if (dumpPackage == null) {
12094            if (mAlwaysFinishActivities || mController != null) {
12095                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12096                        + " mController=" + mController);
12097            }
12098            if (dumpAll) {
12099                pw.println("  Total persistent processes: " + numPers);
12100                pw.println("  mProcessesReady=" + mProcessesReady
12101                        + " mSystemReady=" + mSystemReady);
12102                pw.println("  mBooting=" + mBooting
12103                        + " mBooted=" + mBooted
12104                        + " mFactoryTest=" + mFactoryTest);
12105                pw.print("  mLastPowerCheckRealtime=");
12106                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12107                        pw.println("");
12108                pw.print("  mLastPowerCheckUptime=");
12109                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12110                        pw.println("");
12111                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12112                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12113                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12114                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12115                        + " (" + mLruProcesses.size() + " total)"
12116                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12117                        + " mNumServiceProcs=" + mNumServiceProcs
12118                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12119                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12120                        + " mLastMemoryLevel" + mLastMemoryLevel
12121                        + " mLastNumProcesses" + mLastNumProcesses);
12122                long now = SystemClock.uptimeMillis();
12123                pw.print("  mLastIdleTime=");
12124                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12125                        pw.print(" mLowRamSinceLastIdle=");
12126                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12127                        pw.println();
12128            }
12129        }
12130
12131        if (!printedAnything) {
12132            pw.println("  (nothing)");
12133        }
12134    }
12135
12136    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12137            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12138        if (mProcessesToGc.size() > 0) {
12139            boolean printed = false;
12140            long now = SystemClock.uptimeMillis();
12141            for (int i=0; i<mProcessesToGc.size(); i++) {
12142                ProcessRecord proc = mProcessesToGc.get(i);
12143                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12144                    continue;
12145                }
12146                if (!printed) {
12147                    if (needSep) pw.println();
12148                    needSep = true;
12149                    pw.println("  Processes that are waiting to GC:");
12150                    printed = true;
12151                }
12152                pw.print("    Process "); pw.println(proc);
12153                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12154                        pw.print(", last gced=");
12155                        pw.print(now-proc.lastRequestedGc);
12156                        pw.print(" ms ago, last lowMem=");
12157                        pw.print(now-proc.lastLowMemory);
12158                        pw.println(" ms ago");
12159
12160            }
12161        }
12162        return needSep;
12163    }
12164
12165    void printOomLevel(PrintWriter pw, String name, int adj) {
12166        pw.print("    ");
12167        if (adj >= 0) {
12168            pw.print(' ');
12169            if (adj < 10) pw.print(' ');
12170        } else {
12171            if (adj > -10) pw.print(' ');
12172        }
12173        pw.print(adj);
12174        pw.print(": ");
12175        pw.print(name);
12176        pw.print(" (");
12177        pw.print(mProcessList.getMemLevel(adj)/1024);
12178        pw.println(" kB)");
12179    }
12180
12181    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12182            int opti, boolean dumpAll) {
12183        boolean needSep = false;
12184
12185        if (mLruProcesses.size() > 0) {
12186            if (needSep) pw.println();
12187            needSep = true;
12188            pw.println("  OOM levels:");
12189            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12190            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12191            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12192            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12193            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12194            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12195            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12196            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12197            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12198            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12199            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12200            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12201            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12202
12203            if (needSep) pw.println();
12204            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12205                    pw.print(" total, non-act at ");
12206                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12207                    pw.print(", non-svc at ");
12208                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12209                    pw.println("):");
12210            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12211            needSep = true;
12212        }
12213
12214        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12215
12216        pw.println();
12217        pw.println("  mHomeProcess: " + mHomeProcess);
12218        pw.println("  mPreviousProcess: " + mPreviousProcess);
12219        if (mHeavyWeightProcess != null) {
12220            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12221        }
12222
12223        return true;
12224    }
12225
12226    /**
12227     * There are three ways to call this:
12228     *  - no provider specified: dump all the providers
12229     *  - a flattened component name that matched an existing provider was specified as the
12230     *    first arg: dump that one provider
12231     *  - the first arg isn't the flattened component name of an existing provider:
12232     *    dump all providers whose component contains the first arg as a substring
12233     */
12234    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12235            int opti, boolean dumpAll) {
12236        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12237    }
12238
12239    static class ItemMatcher {
12240        ArrayList<ComponentName> components;
12241        ArrayList<String> strings;
12242        ArrayList<Integer> objects;
12243        boolean all;
12244
12245        ItemMatcher() {
12246            all = true;
12247        }
12248
12249        void build(String name) {
12250            ComponentName componentName = ComponentName.unflattenFromString(name);
12251            if (componentName != null) {
12252                if (components == null) {
12253                    components = new ArrayList<ComponentName>();
12254                }
12255                components.add(componentName);
12256                all = false;
12257            } else {
12258                int objectId = 0;
12259                // Not a '/' separated full component name; maybe an object ID?
12260                try {
12261                    objectId = Integer.parseInt(name, 16);
12262                    if (objects == null) {
12263                        objects = new ArrayList<Integer>();
12264                    }
12265                    objects.add(objectId);
12266                    all = false;
12267                } catch (RuntimeException e) {
12268                    // Not an integer; just do string match.
12269                    if (strings == null) {
12270                        strings = new ArrayList<String>();
12271                    }
12272                    strings.add(name);
12273                    all = false;
12274                }
12275            }
12276        }
12277
12278        int build(String[] args, int opti) {
12279            for (; opti<args.length; opti++) {
12280                String name = args[opti];
12281                if ("--".equals(name)) {
12282                    return opti+1;
12283                }
12284                build(name);
12285            }
12286            return opti;
12287        }
12288
12289        boolean match(Object object, ComponentName comp) {
12290            if (all) {
12291                return true;
12292            }
12293            if (components != null) {
12294                for (int i=0; i<components.size(); i++) {
12295                    if (components.get(i).equals(comp)) {
12296                        return true;
12297                    }
12298                }
12299            }
12300            if (objects != null) {
12301                for (int i=0; i<objects.size(); i++) {
12302                    if (System.identityHashCode(object) == objects.get(i)) {
12303                        return true;
12304                    }
12305                }
12306            }
12307            if (strings != null) {
12308                String flat = comp.flattenToString();
12309                for (int i=0; i<strings.size(); i++) {
12310                    if (flat.contains(strings.get(i))) {
12311                        return true;
12312                    }
12313                }
12314            }
12315            return false;
12316        }
12317    }
12318
12319    /**
12320     * There are three things that cmd can be:
12321     *  - a flattened component name that matches an existing activity
12322     *  - the cmd arg isn't the flattened component name of an existing activity:
12323     *    dump all activity whose component contains the cmd as a substring
12324     *  - A hex number of the ActivityRecord object instance.
12325     */
12326    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12327            int opti, boolean dumpAll) {
12328        ArrayList<ActivityRecord> activities;
12329
12330        synchronized (this) {
12331            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12332        }
12333
12334        if (activities.size() <= 0) {
12335            return false;
12336        }
12337
12338        String[] newArgs = new String[args.length - opti];
12339        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12340
12341        TaskRecord lastTask = null;
12342        boolean needSep = false;
12343        for (int i=activities.size()-1; i>=0; i--) {
12344            ActivityRecord r = activities.get(i);
12345            if (needSep) {
12346                pw.println();
12347            }
12348            needSep = true;
12349            synchronized (this) {
12350                if (lastTask != r.task) {
12351                    lastTask = r.task;
12352                    pw.print("TASK "); pw.print(lastTask.affinity);
12353                            pw.print(" id="); pw.println(lastTask.taskId);
12354                    if (dumpAll) {
12355                        lastTask.dump(pw, "  ");
12356                    }
12357                }
12358            }
12359            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12360        }
12361        return true;
12362    }
12363
12364    /**
12365     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12366     * there is a thread associated with the activity.
12367     */
12368    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12369            final ActivityRecord r, String[] args, boolean dumpAll) {
12370        String innerPrefix = prefix + "  ";
12371        synchronized (this) {
12372            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12373                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12374                    pw.print(" pid=");
12375                    if (r.app != null) pw.println(r.app.pid);
12376                    else pw.println("(not running)");
12377            if (dumpAll) {
12378                r.dump(pw, innerPrefix);
12379            }
12380        }
12381        if (r.app != null && r.app.thread != null) {
12382            // flush anything that is already in the PrintWriter since the thread is going
12383            // to write to the file descriptor directly
12384            pw.flush();
12385            try {
12386                TransferPipe tp = new TransferPipe();
12387                try {
12388                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12389                            r.appToken, innerPrefix, args);
12390                    tp.go(fd);
12391                } finally {
12392                    tp.kill();
12393                }
12394            } catch (IOException e) {
12395                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12396            } catch (RemoteException e) {
12397                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12398            }
12399        }
12400    }
12401
12402    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12403            int opti, boolean dumpAll, String dumpPackage) {
12404        boolean needSep = false;
12405        boolean onlyHistory = false;
12406        boolean printedAnything = false;
12407
12408        if ("history".equals(dumpPackage)) {
12409            if (opti < args.length && "-s".equals(args[opti])) {
12410                dumpAll = false;
12411            }
12412            onlyHistory = true;
12413            dumpPackage = null;
12414        }
12415
12416        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12417        if (!onlyHistory && dumpAll) {
12418            if (mRegisteredReceivers.size() > 0) {
12419                boolean printed = false;
12420                Iterator it = mRegisteredReceivers.values().iterator();
12421                while (it.hasNext()) {
12422                    ReceiverList r = (ReceiverList)it.next();
12423                    if (dumpPackage != null && (r.app == null ||
12424                            !dumpPackage.equals(r.app.info.packageName))) {
12425                        continue;
12426                    }
12427                    if (!printed) {
12428                        pw.println("  Registered Receivers:");
12429                        needSep = true;
12430                        printed = true;
12431                        printedAnything = true;
12432                    }
12433                    pw.print("  * "); pw.println(r);
12434                    r.dump(pw, "    ");
12435                }
12436            }
12437
12438            if (mReceiverResolver.dump(pw, needSep ?
12439                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12440                    "    ", dumpPackage, false)) {
12441                needSep = true;
12442                printedAnything = true;
12443            }
12444        }
12445
12446        for (BroadcastQueue q : mBroadcastQueues) {
12447            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12448            printedAnything |= needSep;
12449        }
12450
12451        needSep = true;
12452
12453        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12454            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12455                if (needSep) {
12456                    pw.println();
12457                }
12458                needSep = true;
12459                printedAnything = true;
12460                pw.print("  Sticky broadcasts for user ");
12461                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12462                StringBuilder sb = new StringBuilder(128);
12463                for (Map.Entry<String, ArrayList<Intent>> ent
12464                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12465                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12466                    if (dumpAll) {
12467                        pw.println(":");
12468                        ArrayList<Intent> intents = ent.getValue();
12469                        final int N = intents.size();
12470                        for (int i=0; i<N; i++) {
12471                            sb.setLength(0);
12472                            sb.append("    Intent: ");
12473                            intents.get(i).toShortString(sb, false, true, false, false);
12474                            pw.println(sb.toString());
12475                            Bundle bundle = intents.get(i).getExtras();
12476                            if (bundle != null) {
12477                                pw.print("      ");
12478                                pw.println(bundle.toString());
12479                            }
12480                        }
12481                    } else {
12482                        pw.println("");
12483                    }
12484                }
12485            }
12486        }
12487
12488        if (!onlyHistory && dumpAll) {
12489            pw.println();
12490            for (BroadcastQueue queue : mBroadcastQueues) {
12491                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12492                        + queue.mBroadcastsScheduled);
12493            }
12494            pw.println("  mHandler:");
12495            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12496            needSep = true;
12497            printedAnything = true;
12498        }
12499
12500        if (!printedAnything) {
12501            pw.println("  (nothing)");
12502        }
12503    }
12504
12505    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12506            int opti, boolean dumpAll, String dumpPackage) {
12507        boolean needSep;
12508        boolean printedAnything = false;
12509
12510        ItemMatcher matcher = new ItemMatcher();
12511        matcher.build(args, opti);
12512
12513        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12514
12515        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12516        printedAnything |= needSep;
12517
12518        if (mLaunchingProviders.size() > 0) {
12519            boolean printed = false;
12520            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12521                ContentProviderRecord r = mLaunchingProviders.get(i);
12522                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12523                    continue;
12524                }
12525                if (!printed) {
12526                    if (needSep) pw.println();
12527                    needSep = true;
12528                    pw.println("  Launching content providers:");
12529                    printed = true;
12530                    printedAnything = true;
12531                }
12532                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12533                        pw.println(r);
12534            }
12535        }
12536
12537        if (mGrantedUriPermissions.size() > 0) {
12538            boolean printed = false;
12539            int dumpUid = -2;
12540            if (dumpPackage != null) {
12541                try {
12542                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12543                } catch (NameNotFoundException e) {
12544                    dumpUid = -1;
12545                }
12546            }
12547            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12548                int uid = mGrantedUriPermissions.keyAt(i);
12549                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12550                    continue;
12551                }
12552                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12553                if (!printed) {
12554                    if (needSep) pw.println();
12555                    needSep = true;
12556                    pw.println("  Granted Uri Permissions:");
12557                    printed = true;
12558                    printedAnything = true;
12559                }
12560                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12561                for (UriPermission perm : perms.values()) {
12562                    pw.print("    "); pw.println(perm);
12563                    if (dumpAll) {
12564                        perm.dump(pw, "      ");
12565                    }
12566                }
12567            }
12568        }
12569
12570        if (!printedAnything) {
12571            pw.println("  (nothing)");
12572        }
12573    }
12574
12575    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12576            int opti, boolean dumpAll, String dumpPackage) {
12577        boolean printed = false;
12578
12579        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12580
12581        if (mIntentSenderRecords.size() > 0) {
12582            Iterator<WeakReference<PendingIntentRecord>> it
12583                    = mIntentSenderRecords.values().iterator();
12584            while (it.hasNext()) {
12585                WeakReference<PendingIntentRecord> ref = it.next();
12586                PendingIntentRecord rec = ref != null ? ref.get(): null;
12587                if (dumpPackage != null && (rec == null
12588                        || !dumpPackage.equals(rec.key.packageName))) {
12589                    continue;
12590                }
12591                printed = true;
12592                if (rec != null) {
12593                    pw.print("  * "); pw.println(rec);
12594                    if (dumpAll) {
12595                        rec.dump(pw, "    ");
12596                    }
12597                } else {
12598                    pw.print("  * "); pw.println(ref);
12599                }
12600            }
12601        }
12602
12603        if (!printed) {
12604            pw.println("  (nothing)");
12605        }
12606    }
12607
12608    private static final int dumpProcessList(PrintWriter pw,
12609            ActivityManagerService service, List list,
12610            String prefix, String normalLabel, String persistentLabel,
12611            String dumpPackage) {
12612        int numPers = 0;
12613        final int N = list.size()-1;
12614        for (int i=N; i>=0; i--) {
12615            ProcessRecord r = (ProcessRecord)list.get(i);
12616            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12617                continue;
12618            }
12619            pw.println(String.format("%s%s #%2d: %s",
12620                    prefix, (r.persistent ? persistentLabel : normalLabel),
12621                    i, r.toString()));
12622            if (r.persistent) {
12623                numPers++;
12624            }
12625        }
12626        return numPers;
12627    }
12628
12629    private static final boolean dumpProcessOomList(PrintWriter pw,
12630            ActivityManagerService service, List<ProcessRecord> origList,
12631            String prefix, String normalLabel, String persistentLabel,
12632            boolean inclDetails, String dumpPackage) {
12633
12634        ArrayList<Pair<ProcessRecord, Integer>> list
12635                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12636        for (int i=0; i<origList.size(); i++) {
12637            ProcessRecord r = origList.get(i);
12638            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12639                continue;
12640            }
12641            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12642        }
12643
12644        if (list.size() <= 0) {
12645            return false;
12646        }
12647
12648        Comparator<Pair<ProcessRecord, Integer>> comparator
12649                = new Comparator<Pair<ProcessRecord, Integer>>() {
12650            @Override
12651            public int compare(Pair<ProcessRecord, Integer> object1,
12652                    Pair<ProcessRecord, Integer> object2) {
12653                if (object1.first.setAdj != object2.first.setAdj) {
12654                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12655                }
12656                if (object1.second.intValue() != object2.second.intValue()) {
12657                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12658                }
12659                return 0;
12660            }
12661        };
12662
12663        Collections.sort(list, comparator);
12664
12665        final long curRealtime = SystemClock.elapsedRealtime();
12666        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12667        final long curUptime = SystemClock.uptimeMillis();
12668        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12669
12670        for (int i=list.size()-1; i>=0; i--) {
12671            ProcessRecord r = list.get(i).first;
12672            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12673            char schedGroup;
12674            switch (r.setSchedGroup) {
12675                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12676                    schedGroup = 'B';
12677                    break;
12678                case Process.THREAD_GROUP_DEFAULT:
12679                    schedGroup = 'F';
12680                    break;
12681                default:
12682                    schedGroup = '?';
12683                    break;
12684            }
12685            char foreground;
12686            if (r.foregroundActivities) {
12687                foreground = 'A';
12688            } else if (r.foregroundServices) {
12689                foreground = 'S';
12690            } else {
12691                foreground = ' ';
12692            }
12693            String procState = ProcessList.makeProcStateString(r.curProcState);
12694            pw.print(prefix);
12695            pw.print(r.persistent ? persistentLabel : normalLabel);
12696            pw.print(" #");
12697            int num = (origList.size()-1)-list.get(i).second;
12698            if (num < 10) pw.print(' ');
12699            pw.print(num);
12700            pw.print(": ");
12701            pw.print(oomAdj);
12702            pw.print(' ');
12703            pw.print(schedGroup);
12704            pw.print('/');
12705            pw.print(foreground);
12706            pw.print('/');
12707            pw.print(procState);
12708            pw.print(" trm:");
12709            if (r.trimMemoryLevel < 10) pw.print(' ');
12710            pw.print(r.trimMemoryLevel);
12711            pw.print(' ');
12712            pw.print(r.toShortString());
12713            pw.print(" (");
12714            pw.print(r.adjType);
12715            pw.println(')');
12716            if (r.adjSource != null || r.adjTarget != null) {
12717                pw.print(prefix);
12718                pw.print("    ");
12719                if (r.adjTarget instanceof ComponentName) {
12720                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12721                } else if (r.adjTarget != null) {
12722                    pw.print(r.adjTarget.toString());
12723                } else {
12724                    pw.print("{null}");
12725                }
12726                pw.print("<=");
12727                if (r.adjSource instanceof ProcessRecord) {
12728                    pw.print("Proc{");
12729                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12730                    pw.println("}");
12731                } else if (r.adjSource != null) {
12732                    pw.println(r.adjSource.toString());
12733                } else {
12734                    pw.println("{null}");
12735                }
12736            }
12737            if (inclDetails) {
12738                pw.print(prefix);
12739                pw.print("    ");
12740                pw.print("oom: max="); pw.print(r.maxAdj);
12741                pw.print(" curRaw="); pw.print(r.curRawAdj);
12742                pw.print(" setRaw="); pw.print(r.setRawAdj);
12743                pw.print(" cur="); pw.print(r.curAdj);
12744                pw.print(" set="); pw.println(r.setAdj);
12745                pw.print(prefix);
12746                pw.print("    ");
12747                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12748                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12749                pw.print(" lastPss="); pw.print(r.lastPss);
12750                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12751                pw.print(prefix);
12752                pw.print("    ");
12753                pw.print("cached="); pw.print(r.cached);
12754                pw.print(" empty="); pw.print(r.empty);
12755                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12756
12757                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12758                    if (r.lastWakeTime != 0) {
12759                        long wtime;
12760                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12761                        synchronized (stats) {
12762                            wtime = stats.getProcessWakeTime(r.info.uid,
12763                                    r.pid, curRealtime);
12764                        }
12765                        long timeUsed = wtime - r.lastWakeTime;
12766                        pw.print(prefix);
12767                        pw.print("    ");
12768                        pw.print("keep awake over ");
12769                        TimeUtils.formatDuration(realtimeSince, pw);
12770                        pw.print(" used ");
12771                        TimeUtils.formatDuration(timeUsed, pw);
12772                        pw.print(" (");
12773                        pw.print((timeUsed*100)/realtimeSince);
12774                        pw.println("%)");
12775                    }
12776                    if (r.lastCpuTime != 0) {
12777                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12778                        pw.print(prefix);
12779                        pw.print("    ");
12780                        pw.print("run cpu over ");
12781                        TimeUtils.formatDuration(uptimeSince, pw);
12782                        pw.print(" used ");
12783                        TimeUtils.formatDuration(timeUsed, pw);
12784                        pw.print(" (");
12785                        pw.print((timeUsed*100)/uptimeSince);
12786                        pw.println("%)");
12787                    }
12788                }
12789            }
12790        }
12791        return true;
12792    }
12793
12794    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12795        ArrayList<ProcessRecord> procs;
12796        synchronized (this) {
12797            if (args != null && args.length > start
12798                    && args[start].charAt(0) != '-') {
12799                procs = new ArrayList<ProcessRecord>();
12800                int pid = -1;
12801                try {
12802                    pid = Integer.parseInt(args[start]);
12803                } catch (NumberFormatException e) {
12804                }
12805                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12806                    ProcessRecord proc = mLruProcesses.get(i);
12807                    if (proc.pid == pid) {
12808                        procs.add(proc);
12809                    } else if (proc.processName.equals(args[start])) {
12810                        procs.add(proc);
12811                    }
12812                }
12813                if (procs.size() <= 0) {
12814                    return null;
12815                }
12816            } else {
12817                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12818            }
12819        }
12820        return procs;
12821    }
12822
12823    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12824            PrintWriter pw, String[] args) {
12825        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12826        if (procs == null) {
12827            pw.println("No process found for: " + args[0]);
12828            return;
12829        }
12830
12831        long uptime = SystemClock.uptimeMillis();
12832        long realtime = SystemClock.elapsedRealtime();
12833        pw.println("Applications Graphics Acceleration Info:");
12834        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12835
12836        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12837            ProcessRecord r = procs.get(i);
12838            if (r.thread != null) {
12839                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12840                pw.flush();
12841                try {
12842                    TransferPipe tp = new TransferPipe();
12843                    try {
12844                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12845                        tp.go(fd);
12846                    } finally {
12847                        tp.kill();
12848                    }
12849                } catch (IOException e) {
12850                    pw.println("Failure while dumping the app: " + r);
12851                    pw.flush();
12852                } catch (RemoteException e) {
12853                    pw.println("Got a RemoteException while dumping the app " + r);
12854                    pw.flush();
12855                }
12856            }
12857        }
12858    }
12859
12860    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12861        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12862        if (procs == null) {
12863            pw.println("No process found for: " + args[0]);
12864            return;
12865        }
12866
12867        pw.println("Applications Database Info:");
12868
12869        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12870            ProcessRecord r = procs.get(i);
12871            if (r.thread != null) {
12872                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12873                pw.flush();
12874                try {
12875                    TransferPipe tp = new TransferPipe();
12876                    try {
12877                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12878                        tp.go(fd);
12879                    } finally {
12880                        tp.kill();
12881                    }
12882                } catch (IOException e) {
12883                    pw.println("Failure while dumping the app: " + r);
12884                    pw.flush();
12885                } catch (RemoteException e) {
12886                    pw.println("Got a RemoteException while dumping the app " + r);
12887                    pw.flush();
12888                }
12889            }
12890        }
12891    }
12892
12893    final static class MemItem {
12894        final boolean isProc;
12895        final String label;
12896        final String shortLabel;
12897        final long pss;
12898        final int id;
12899        final boolean hasActivities;
12900        ArrayList<MemItem> subitems;
12901
12902        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12903                boolean _hasActivities) {
12904            isProc = true;
12905            label = _label;
12906            shortLabel = _shortLabel;
12907            pss = _pss;
12908            id = _id;
12909            hasActivities = _hasActivities;
12910        }
12911
12912        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12913            isProc = false;
12914            label = _label;
12915            shortLabel = _shortLabel;
12916            pss = _pss;
12917            id = _id;
12918            hasActivities = false;
12919        }
12920    }
12921
12922    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12923            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12924        if (sort && !isCompact) {
12925            Collections.sort(items, new Comparator<MemItem>() {
12926                @Override
12927                public int compare(MemItem lhs, MemItem rhs) {
12928                    if (lhs.pss < rhs.pss) {
12929                        return 1;
12930                    } else if (lhs.pss > rhs.pss) {
12931                        return -1;
12932                    }
12933                    return 0;
12934                }
12935            });
12936        }
12937
12938        for (int i=0; i<items.size(); i++) {
12939            MemItem mi = items.get(i);
12940            if (!isCompact) {
12941                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12942            } else if (mi.isProc) {
12943                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12944                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12945                pw.println(mi.hasActivities ? ",a" : ",e");
12946            } else {
12947                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12948                pw.println(mi.pss);
12949            }
12950            if (mi.subitems != null) {
12951                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12952                        true, isCompact);
12953            }
12954        }
12955    }
12956
12957    // These are in KB.
12958    static final long[] DUMP_MEM_BUCKETS = new long[] {
12959        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12960        120*1024, 160*1024, 200*1024,
12961        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12962        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12963    };
12964
12965    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12966            boolean stackLike) {
12967        int start = label.lastIndexOf('.');
12968        if (start >= 0) start++;
12969        else start = 0;
12970        int end = label.length();
12971        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12972            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12973                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12974                out.append(bucket);
12975                out.append(stackLike ? "MB." : "MB ");
12976                out.append(label, start, end);
12977                return;
12978            }
12979        }
12980        out.append(memKB/1024);
12981        out.append(stackLike ? "MB." : "MB ");
12982        out.append(label, start, end);
12983    }
12984
12985    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12986            ProcessList.NATIVE_ADJ,
12987            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12988            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12989            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12990            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12991            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12992    };
12993    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12994            "Native",
12995            "System", "Persistent", "Foreground",
12996            "Visible", "Perceptible",
12997            "Heavy Weight", "Backup",
12998            "A Services", "Home",
12999            "Previous", "B Services", "Cached"
13000    };
13001    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13002            "native",
13003            "sys", "pers", "fore",
13004            "vis", "percept",
13005            "heavy", "backup",
13006            "servicea", "home",
13007            "prev", "serviceb", "cached"
13008    };
13009
13010    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13011            long realtime, boolean isCheckinRequest, boolean isCompact) {
13012        if (isCheckinRequest || isCompact) {
13013            // short checkin version
13014            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13015        } else {
13016            pw.println("Applications Memory Usage (kB):");
13017            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13018        }
13019    }
13020
13021    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13022            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13023        boolean dumpDetails = false;
13024        boolean dumpFullDetails = false;
13025        boolean dumpDalvik = false;
13026        boolean oomOnly = false;
13027        boolean isCompact = false;
13028        boolean localOnly = false;
13029
13030        int opti = 0;
13031        while (opti < args.length) {
13032            String opt = args[opti];
13033            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13034                break;
13035            }
13036            opti++;
13037            if ("-a".equals(opt)) {
13038                dumpDetails = true;
13039                dumpFullDetails = true;
13040                dumpDalvik = true;
13041            } else if ("-d".equals(opt)) {
13042                dumpDalvik = true;
13043            } else if ("-c".equals(opt)) {
13044                isCompact = true;
13045            } else if ("--oom".equals(opt)) {
13046                oomOnly = true;
13047            } else if ("--local".equals(opt)) {
13048                localOnly = true;
13049            } else if ("-h".equals(opt)) {
13050                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13051                pw.println("  -a: include all available information for each process.");
13052                pw.println("  -d: include dalvik details when dumping process details.");
13053                pw.println("  -c: dump in a compact machine-parseable representation.");
13054                pw.println("  --oom: only show processes organized by oom adj.");
13055                pw.println("  --local: only collect details locally, don't call process.");
13056                pw.println("If [process] is specified it can be the name or ");
13057                pw.println("pid of a specific process to dump.");
13058                return;
13059            } else {
13060                pw.println("Unknown argument: " + opt + "; use -h for help");
13061            }
13062        }
13063
13064        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13065        long uptime = SystemClock.uptimeMillis();
13066        long realtime = SystemClock.elapsedRealtime();
13067        final long[] tmpLong = new long[1];
13068
13069        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13070        if (procs == null) {
13071            // No Java processes.  Maybe they want to print a native process.
13072            if (args != null && args.length > opti
13073                    && args[opti].charAt(0) != '-') {
13074                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13075                        = new ArrayList<ProcessCpuTracker.Stats>();
13076                updateCpuStatsNow();
13077                int findPid = -1;
13078                try {
13079                    findPid = Integer.parseInt(args[opti]);
13080                } catch (NumberFormatException e) {
13081                }
13082                synchronized (mProcessCpuThread) {
13083                    final int N = mProcessCpuTracker.countStats();
13084                    for (int i=0; i<N; i++) {
13085                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13086                        if (st.pid == findPid || (st.baseName != null
13087                                && st.baseName.equals(args[opti]))) {
13088                            nativeProcs.add(st);
13089                        }
13090                    }
13091                }
13092                if (nativeProcs.size() > 0) {
13093                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13094                            isCompact);
13095                    Debug.MemoryInfo mi = null;
13096                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13097                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13098                        final int pid = r.pid;
13099                        if (!isCheckinRequest && dumpDetails) {
13100                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13101                        }
13102                        if (mi == null) {
13103                            mi = new Debug.MemoryInfo();
13104                        }
13105                        if (dumpDetails || (!brief && !oomOnly)) {
13106                            Debug.getMemoryInfo(pid, mi);
13107                        } else {
13108                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13109                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13110                        }
13111                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13112                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13113                        if (isCheckinRequest) {
13114                            pw.println();
13115                        }
13116                    }
13117                    return;
13118                }
13119            }
13120            pw.println("No process found for: " + args[opti]);
13121            return;
13122        }
13123
13124        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13125            dumpDetails = true;
13126        }
13127
13128        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13129
13130        String[] innerArgs = new String[args.length-opti];
13131        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13132
13133        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13134        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13135        long nativePss=0, dalvikPss=0, otherPss=0;
13136        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13137
13138        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13139        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13140                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13141
13142        long totalPss = 0;
13143        long cachedPss = 0;
13144
13145        Debug.MemoryInfo mi = null;
13146        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13147            final ProcessRecord r = procs.get(i);
13148            final IApplicationThread thread;
13149            final int pid;
13150            final int oomAdj;
13151            final boolean hasActivities;
13152            synchronized (this) {
13153                thread = r.thread;
13154                pid = r.pid;
13155                oomAdj = r.getSetAdjWithServices();
13156                hasActivities = r.activities.size() > 0;
13157            }
13158            if (thread != null) {
13159                if (!isCheckinRequest && dumpDetails) {
13160                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13161                }
13162                if (mi == null) {
13163                    mi = new Debug.MemoryInfo();
13164                }
13165                if (dumpDetails || (!brief && !oomOnly)) {
13166                    Debug.getMemoryInfo(pid, mi);
13167                } else {
13168                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13169                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13170                }
13171                if (dumpDetails) {
13172                    if (localOnly) {
13173                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13174                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13175                        if (isCheckinRequest) {
13176                            pw.println();
13177                        }
13178                    } else {
13179                        try {
13180                            pw.flush();
13181                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13182                                    dumpDalvik, innerArgs);
13183                        } catch (RemoteException e) {
13184                            if (!isCheckinRequest) {
13185                                pw.println("Got RemoteException!");
13186                                pw.flush();
13187                            }
13188                        }
13189                    }
13190                }
13191
13192                final long myTotalPss = mi.getTotalPss();
13193                final long myTotalUss = mi.getTotalUss();
13194
13195                synchronized (this) {
13196                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13197                        // Record this for posterity if the process has been stable.
13198                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13199                    }
13200                }
13201
13202                if (!isCheckinRequest && mi != null) {
13203                    totalPss += myTotalPss;
13204                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13205                            (hasActivities ? " / activities)" : ")"),
13206                            r.processName, myTotalPss, pid, hasActivities);
13207                    procMems.add(pssItem);
13208                    procMemsMap.put(pid, pssItem);
13209
13210                    nativePss += mi.nativePss;
13211                    dalvikPss += mi.dalvikPss;
13212                    otherPss += mi.otherPss;
13213                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13214                        long mem = mi.getOtherPss(j);
13215                        miscPss[j] += mem;
13216                        otherPss -= mem;
13217                    }
13218
13219                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13220                        cachedPss += myTotalPss;
13221                    }
13222
13223                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13224                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13225                                || oomIndex == (oomPss.length-1)) {
13226                            oomPss[oomIndex] += myTotalPss;
13227                            if (oomProcs[oomIndex] == null) {
13228                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13229                            }
13230                            oomProcs[oomIndex].add(pssItem);
13231                            break;
13232                        }
13233                    }
13234                }
13235            }
13236        }
13237
13238        long nativeProcTotalPss = 0;
13239
13240        if (!isCheckinRequest && procs.size() > 1) {
13241            // If we are showing aggregations, also look for native processes to
13242            // include so that our aggregations are more accurate.
13243            updateCpuStatsNow();
13244            synchronized (mProcessCpuThread) {
13245                final int N = mProcessCpuTracker.countStats();
13246                for (int i=0; i<N; i++) {
13247                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13248                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13249                        if (mi == null) {
13250                            mi = new Debug.MemoryInfo();
13251                        }
13252                        if (!brief && !oomOnly) {
13253                            Debug.getMemoryInfo(st.pid, mi);
13254                        } else {
13255                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13256                            mi.nativePrivateDirty = (int)tmpLong[0];
13257                        }
13258
13259                        final long myTotalPss = mi.getTotalPss();
13260                        totalPss += myTotalPss;
13261                        nativeProcTotalPss += myTotalPss;
13262
13263                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13264                                st.name, myTotalPss, st.pid, false);
13265                        procMems.add(pssItem);
13266
13267                        nativePss += mi.nativePss;
13268                        dalvikPss += mi.dalvikPss;
13269                        otherPss += mi.otherPss;
13270                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13271                            long mem = mi.getOtherPss(j);
13272                            miscPss[j] += mem;
13273                            otherPss -= mem;
13274                        }
13275                        oomPss[0] += myTotalPss;
13276                        if (oomProcs[0] == null) {
13277                            oomProcs[0] = new ArrayList<MemItem>();
13278                        }
13279                        oomProcs[0].add(pssItem);
13280                    }
13281                }
13282            }
13283
13284            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13285
13286            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13287            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13288            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13289            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13290                String label = Debug.MemoryInfo.getOtherLabel(j);
13291                catMems.add(new MemItem(label, label, miscPss[j], j));
13292            }
13293
13294            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13295            for (int j=0; j<oomPss.length; j++) {
13296                if (oomPss[j] != 0) {
13297                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13298                            : DUMP_MEM_OOM_LABEL[j];
13299                    MemItem item = new MemItem(label, label, oomPss[j],
13300                            DUMP_MEM_OOM_ADJ[j]);
13301                    item.subitems = oomProcs[j];
13302                    oomMems.add(item);
13303                }
13304            }
13305
13306            if (!brief && !oomOnly && !isCompact) {
13307                pw.println();
13308                pw.println("Total PSS by process:");
13309                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13310                pw.println();
13311            }
13312            if (!isCompact) {
13313                pw.println("Total PSS by OOM adjustment:");
13314            }
13315            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13316            if (!brief && !oomOnly) {
13317                PrintWriter out = categoryPw != null ? categoryPw : pw;
13318                if (!isCompact) {
13319                    out.println();
13320                    out.println("Total PSS by category:");
13321                }
13322                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13323            }
13324            if (!isCompact) {
13325                pw.println();
13326            }
13327            MemInfoReader memInfo = new MemInfoReader();
13328            memInfo.readMemInfo();
13329            if (nativeProcTotalPss > 0) {
13330                synchronized (this) {
13331                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13332                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13333                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13334                            nativeProcTotalPss);
13335                }
13336            }
13337            if (!brief) {
13338                if (!isCompact) {
13339                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13340                    pw.print(" kB (status ");
13341                    switch (mLastMemoryLevel) {
13342                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13343                            pw.println("normal)");
13344                            break;
13345                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13346                            pw.println("moderate)");
13347                            break;
13348                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13349                            pw.println("low)");
13350                            break;
13351                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13352                            pw.println("critical)");
13353                            break;
13354                        default:
13355                            pw.print(mLastMemoryLevel);
13356                            pw.println(")");
13357                            break;
13358                    }
13359                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13360                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13361                            pw.print(cachedPss); pw.print(" cached pss + ");
13362                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13363                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13364                } else {
13365                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13366                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13367                            + memInfo.getFreeSizeKb()); pw.print(",");
13368                    pw.println(totalPss - cachedPss);
13369                }
13370            }
13371            if (!isCompact) {
13372                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13373                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13374                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13375                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13376                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13377                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13378                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13379                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13380                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13381                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13382                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13383            }
13384            if (!brief) {
13385                if (memInfo.getZramTotalSizeKb() != 0) {
13386                    if (!isCompact) {
13387                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13388                                pw.print(" kB physical used for ");
13389                                pw.print(memInfo.getSwapTotalSizeKb()
13390                                        - memInfo.getSwapFreeSizeKb());
13391                                pw.print(" kB in swap (");
13392                                pw.print(memInfo.getSwapTotalSizeKb());
13393                                pw.println(" kB total swap)");
13394                    } else {
13395                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13396                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13397                                pw.println(memInfo.getSwapFreeSizeKb());
13398                    }
13399                }
13400                final int[] SINGLE_LONG_FORMAT = new int[] {
13401                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13402                };
13403                long[] longOut = new long[1];
13404                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13405                        SINGLE_LONG_FORMAT, null, longOut, null);
13406                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13407                longOut[0] = 0;
13408                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13409                        SINGLE_LONG_FORMAT, null, longOut, null);
13410                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13411                longOut[0] = 0;
13412                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13413                        SINGLE_LONG_FORMAT, null, longOut, null);
13414                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13415                longOut[0] = 0;
13416                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13417                        SINGLE_LONG_FORMAT, null, longOut, null);
13418                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13419                if (!isCompact) {
13420                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13421                        pw.print("      KSM: "); pw.print(sharing);
13422                                pw.print(" kB saved from shared ");
13423                                pw.print(shared); pw.println(" kB");
13424                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13425                                pw.print(voltile); pw.println(" kB volatile");
13426                    }
13427                    pw.print("   Tuning: ");
13428                    pw.print(ActivityManager.staticGetMemoryClass());
13429                    pw.print(" (large ");
13430                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13431                    pw.print("), oom ");
13432                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13433                    pw.print(" kB");
13434                    pw.print(", restore limit ");
13435                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13436                    pw.print(" kB");
13437                    if (ActivityManager.isLowRamDeviceStatic()) {
13438                        pw.print(" (low-ram)");
13439                    }
13440                    if (ActivityManager.isHighEndGfx()) {
13441                        pw.print(" (high-end-gfx)");
13442                    }
13443                    pw.println();
13444                } else {
13445                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13446                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13447                    pw.println(voltile);
13448                    pw.print("tuning,");
13449                    pw.print(ActivityManager.staticGetMemoryClass());
13450                    pw.print(',');
13451                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13452                    pw.print(',');
13453                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13454                    if (ActivityManager.isLowRamDeviceStatic()) {
13455                        pw.print(",low-ram");
13456                    }
13457                    if (ActivityManager.isHighEndGfx()) {
13458                        pw.print(",high-end-gfx");
13459                    }
13460                    pw.println();
13461                }
13462            }
13463        }
13464    }
13465
13466    /**
13467     * Searches array of arguments for the specified string
13468     * @param args array of argument strings
13469     * @param value value to search for
13470     * @return true if the value is contained in the array
13471     */
13472    private static boolean scanArgs(String[] args, String value) {
13473        if (args != null) {
13474            for (String arg : args) {
13475                if (value.equals(arg)) {
13476                    return true;
13477                }
13478            }
13479        }
13480        return false;
13481    }
13482
13483    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13484            ContentProviderRecord cpr, boolean always) {
13485        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13486
13487        if (!inLaunching || always) {
13488            synchronized (cpr) {
13489                cpr.launchingApp = null;
13490                cpr.notifyAll();
13491            }
13492            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13493            String names[] = cpr.info.authority.split(";");
13494            for (int j = 0; j < names.length; j++) {
13495                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13496            }
13497        }
13498
13499        for (int i=0; i<cpr.connections.size(); i++) {
13500            ContentProviderConnection conn = cpr.connections.get(i);
13501            if (conn.waiting) {
13502                // If this connection is waiting for the provider, then we don't
13503                // need to mess with its process unless we are always removing
13504                // or for some reason the provider is not currently launching.
13505                if (inLaunching && !always) {
13506                    continue;
13507                }
13508            }
13509            ProcessRecord capp = conn.client;
13510            conn.dead = true;
13511            if (conn.stableCount > 0) {
13512                if (!capp.persistent && capp.thread != null
13513                        && capp.pid != 0
13514                        && capp.pid != MY_PID) {
13515                    killUnneededProcessLocked(capp, "depends on provider "
13516                            + cpr.name.flattenToShortString()
13517                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13518                }
13519            } else if (capp.thread != null && conn.provider.provider != null) {
13520                try {
13521                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13522                } catch (RemoteException e) {
13523                }
13524                // In the protocol here, we don't expect the client to correctly
13525                // clean up this connection, we'll just remove it.
13526                cpr.connections.remove(i);
13527                conn.client.conProviders.remove(conn);
13528            }
13529        }
13530
13531        if (inLaunching && always) {
13532            mLaunchingProviders.remove(cpr);
13533        }
13534        return inLaunching;
13535    }
13536
13537    /**
13538     * Main code for cleaning up a process when it has gone away.  This is
13539     * called both as a result of the process dying, or directly when stopping
13540     * a process when running in single process mode.
13541     */
13542    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13543            boolean restarting, boolean allowRestart, int index) {
13544        if (index >= 0) {
13545            removeLruProcessLocked(app);
13546            ProcessList.remove(app.pid);
13547        }
13548
13549        mProcessesToGc.remove(app);
13550        mPendingPssProcesses.remove(app);
13551
13552        // Dismiss any open dialogs.
13553        if (app.crashDialog != null && !app.forceCrashReport) {
13554            app.crashDialog.dismiss();
13555            app.crashDialog = null;
13556        }
13557        if (app.anrDialog != null) {
13558            app.anrDialog.dismiss();
13559            app.anrDialog = null;
13560        }
13561        if (app.waitDialog != null) {
13562            app.waitDialog.dismiss();
13563            app.waitDialog = null;
13564        }
13565
13566        app.crashing = false;
13567        app.notResponding = false;
13568
13569        app.resetPackageList(mProcessStats);
13570        app.unlinkDeathRecipient();
13571        app.makeInactive(mProcessStats);
13572        app.waitingToKill = null;
13573        app.forcingToForeground = null;
13574        updateProcessForegroundLocked(app, false, false);
13575        app.foregroundActivities = false;
13576        app.hasShownUi = false;
13577        app.treatLikeActivity = false;
13578        app.hasAboveClient = false;
13579        app.hasClientActivities = false;
13580
13581        mServices.killServicesLocked(app, allowRestart);
13582
13583        boolean restart = false;
13584
13585        // Remove published content providers.
13586        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13587            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13588            final boolean always = app.bad || !allowRestart;
13589            if (removeDyingProviderLocked(app, cpr, always) || always) {
13590                // We left the provider in the launching list, need to
13591                // restart it.
13592                restart = true;
13593            }
13594
13595            cpr.provider = null;
13596            cpr.proc = null;
13597        }
13598        app.pubProviders.clear();
13599
13600        // Take care of any launching providers waiting for this process.
13601        if (checkAppInLaunchingProvidersLocked(app, false)) {
13602            restart = true;
13603        }
13604
13605        // Unregister from connected content providers.
13606        if (!app.conProviders.isEmpty()) {
13607            for (int i=0; i<app.conProviders.size(); i++) {
13608                ContentProviderConnection conn = app.conProviders.get(i);
13609                conn.provider.connections.remove(conn);
13610            }
13611            app.conProviders.clear();
13612        }
13613
13614        // At this point there may be remaining entries in mLaunchingProviders
13615        // where we were the only one waiting, so they are no longer of use.
13616        // Look for these and clean up if found.
13617        // XXX Commented out for now.  Trying to figure out a way to reproduce
13618        // the actual situation to identify what is actually going on.
13619        if (false) {
13620            for (int i=0; i<mLaunchingProviders.size(); i++) {
13621                ContentProviderRecord cpr = (ContentProviderRecord)
13622                        mLaunchingProviders.get(i);
13623                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13624                    synchronized (cpr) {
13625                        cpr.launchingApp = null;
13626                        cpr.notifyAll();
13627                    }
13628                }
13629            }
13630        }
13631
13632        skipCurrentReceiverLocked(app);
13633
13634        // Unregister any receivers.
13635        for (int i=app.receivers.size()-1; i>=0; i--) {
13636            removeReceiverLocked(app.receivers.valueAt(i));
13637        }
13638        app.receivers.clear();
13639
13640        // If the app is undergoing backup, tell the backup manager about it
13641        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13642            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13643                    + mBackupTarget.appInfo + " died during backup");
13644            try {
13645                IBackupManager bm = IBackupManager.Stub.asInterface(
13646                        ServiceManager.getService(Context.BACKUP_SERVICE));
13647                bm.agentDisconnected(app.info.packageName);
13648            } catch (RemoteException e) {
13649                // can't happen; backup manager is local
13650            }
13651        }
13652
13653        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13654            ProcessChangeItem item = mPendingProcessChanges.get(i);
13655            if (item.pid == app.pid) {
13656                mPendingProcessChanges.remove(i);
13657                mAvailProcessChanges.add(item);
13658            }
13659        }
13660        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13661
13662        // If the caller is restarting this app, then leave it in its
13663        // current lists and let the caller take care of it.
13664        if (restarting) {
13665            return;
13666        }
13667
13668        if (!app.persistent || app.isolated) {
13669            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13670                    "Removing non-persistent process during cleanup: " + app);
13671            mProcessNames.remove(app.processName, app.uid);
13672            mIsolatedProcesses.remove(app.uid);
13673            if (mHeavyWeightProcess == app) {
13674                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13675                        mHeavyWeightProcess.userId, 0));
13676                mHeavyWeightProcess = null;
13677            }
13678        } else if (!app.removed) {
13679            // This app is persistent, so we need to keep its record around.
13680            // If it is not already on the pending app list, add it there
13681            // and start a new process for it.
13682            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13683                mPersistentStartingProcesses.add(app);
13684                restart = true;
13685            }
13686        }
13687        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13688                "Clean-up removing on hold: " + app);
13689        mProcessesOnHold.remove(app);
13690
13691        if (app == mHomeProcess) {
13692            mHomeProcess = null;
13693        }
13694        if (app == mPreviousProcess) {
13695            mPreviousProcess = null;
13696        }
13697
13698        if (restart && !app.isolated) {
13699            // We have components that still need to be running in the
13700            // process, so re-launch it.
13701            mProcessNames.put(app.processName, app.uid, app);
13702            startProcessLocked(app, "restart", app.processName);
13703        } else if (app.pid > 0 && app.pid != MY_PID) {
13704            // Goodbye!
13705            boolean removed;
13706            synchronized (mPidsSelfLocked) {
13707                mPidsSelfLocked.remove(app.pid);
13708                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13709            }
13710            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13711            if (app.isolated) {
13712                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13713            }
13714            app.setPid(0);
13715        }
13716    }
13717
13718    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13719        // Look through the content providers we are waiting to have launched,
13720        // and if any run in this process then either schedule a restart of
13721        // the process or kill the client waiting for it if this process has
13722        // gone bad.
13723        int NL = mLaunchingProviders.size();
13724        boolean restart = false;
13725        for (int i=0; i<NL; i++) {
13726            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13727            if (cpr.launchingApp == app) {
13728                if (!alwaysBad && !app.bad) {
13729                    restart = true;
13730                } else {
13731                    removeDyingProviderLocked(app, cpr, true);
13732                    // cpr should have been removed from mLaunchingProviders
13733                    NL = mLaunchingProviders.size();
13734                    i--;
13735                }
13736            }
13737        }
13738        return restart;
13739    }
13740
13741    // =========================================================
13742    // SERVICES
13743    // =========================================================
13744
13745    @Override
13746    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13747            int flags) {
13748        enforceNotIsolatedCaller("getServices");
13749        synchronized (this) {
13750            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13751        }
13752    }
13753
13754    @Override
13755    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13756        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13757        synchronized (this) {
13758            return mServices.getRunningServiceControlPanelLocked(name);
13759        }
13760    }
13761
13762    @Override
13763    public ComponentName startService(IApplicationThread caller, Intent service,
13764            String resolvedType, int userId) {
13765        enforceNotIsolatedCaller("startService");
13766        // Refuse possible leaked file descriptors
13767        if (service != null && service.hasFileDescriptors() == true) {
13768            throw new IllegalArgumentException("File descriptors passed in Intent");
13769        }
13770
13771        if (DEBUG_SERVICE)
13772            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13773        synchronized(this) {
13774            final int callingPid = Binder.getCallingPid();
13775            final int callingUid = Binder.getCallingUid();
13776            final long origId = Binder.clearCallingIdentity();
13777            ComponentName res = mServices.startServiceLocked(caller, service,
13778                    resolvedType, callingPid, callingUid, userId);
13779            Binder.restoreCallingIdentity(origId);
13780            return res;
13781        }
13782    }
13783
13784    ComponentName startServiceInPackage(int uid,
13785            Intent service, String resolvedType, int userId) {
13786        synchronized(this) {
13787            if (DEBUG_SERVICE)
13788                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13789            final long origId = Binder.clearCallingIdentity();
13790            ComponentName res = mServices.startServiceLocked(null, service,
13791                    resolvedType, -1, uid, userId);
13792            Binder.restoreCallingIdentity(origId);
13793            return res;
13794        }
13795    }
13796
13797    @Override
13798    public int stopService(IApplicationThread caller, Intent service,
13799            String resolvedType, int userId) {
13800        enforceNotIsolatedCaller("stopService");
13801        // Refuse possible leaked file descriptors
13802        if (service != null && service.hasFileDescriptors() == true) {
13803            throw new IllegalArgumentException("File descriptors passed in Intent");
13804        }
13805
13806        synchronized(this) {
13807            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13808        }
13809    }
13810
13811    @Override
13812    public IBinder peekService(Intent service, String resolvedType) {
13813        enforceNotIsolatedCaller("peekService");
13814        // Refuse possible leaked file descriptors
13815        if (service != null && service.hasFileDescriptors() == true) {
13816            throw new IllegalArgumentException("File descriptors passed in Intent");
13817        }
13818        synchronized(this) {
13819            return mServices.peekServiceLocked(service, resolvedType);
13820        }
13821    }
13822
13823    @Override
13824    public boolean stopServiceToken(ComponentName className, IBinder token,
13825            int startId) {
13826        synchronized(this) {
13827            return mServices.stopServiceTokenLocked(className, token, startId);
13828        }
13829    }
13830
13831    @Override
13832    public void setServiceForeground(ComponentName className, IBinder token,
13833            int id, Notification notification, boolean removeNotification) {
13834        synchronized(this) {
13835            mServices.setServiceForegroundLocked(className, token, id, notification,
13836                    removeNotification);
13837        }
13838    }
13839
13840    @Override
13841    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13842            boolean requireFull, String name, String callerPackage) {
13843        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13844                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13845    }
13846
13847    int unsafeConvertIncomingUser(int userId) {
13848        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13849                ? mCurrentUserId : userId;
13850    }
13851
13852    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13853            int allowMode, String name, String callerPackage) {
13854        final int callingUserId = UserHandle.getUserId(callingUid);
13855        if (callingUserId == userId) {
13856            return userId;
13857        }
13858
13859        // Note that we may be accessing mCurrentUserId outside of a lock...
13860        // shouldn't be a big deal, if this is being called outside
13861        // of a locked context there is intrinsically a race with
13862        // the value the caller will receive and someone else changing it.
13863        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13864        // we will switch to the calling user if access to the current user fails.
13865        int targetUserId = unsafeConvertIncomingUser(userId);
13866
13867        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13868            final boolean allow;
13869            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13870                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13871                // If the caller has this permission, they always pass go.  And collect $200.
13872                allow = true;
13873            } else if (allowMode == ALLOW_FULL_ONLY) {
13874                // We require full access, sucks to be you.
13875                allow = false;
13876            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13877                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13878                // If the caller does not have either permission, they are always doomed.
13879                allow = false;
13880            } else if (allowMode == ALLOW_NON_FULL) {
13881                // We are blanket allowing non-full access, you lucky caller!
13882                allow = true;
13883            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13884                // We may or may not allow this depending on whether the two users are
13885                // in the same profile.
13886                synchronized (mUserProfileGroupIdsSelfLocked) {
13887                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13888                            UserInfo.NO_PROFILE_GROUP_ID);
13889                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13890                            UserInfo.NO_PROFILE_GROUP_ID);
13891                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13892                            && callingProfile == targetProfile;
13893                }
13894            } else {
13895                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13896            }
13897            if (!allow) {
13898                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13899                    // In this case, they would like to just execute as their
13900                    // owner user instead of failing.
13901                    targetUserId = callingUserId;
13902                } else {
13903                    StringBuilder builder = new StringBuilder(128);
13904                    builder.append("Permission Denial: ");
13905                    builder.append(name);
13906                    if (callerPackage != null) {
13907                        builder.append(" from ");
13908                        builder.append(callerPackage);
13909                    }
13910                    builder.append(" asks to run as user ");
13911                    builder.append(userId);
13912                    builder.append(" but is calling from user ");
13913                    builder.append(UserHandle.getUserId(callingUid));
13914                    builder.append("; this requires ");
13915                    builder.append(INTERACT_ACROSS_USERS_FULL);
13916                    if (allowMode != ALLOW_FULL_ONLY) {
13917                        builder.append(" or ");
13918                        builder.append(INTERACT_ACROSS_USERS);
13919                    }
13920                    String msg = builder.toString();
13921                    Slog.w(TAG, msg);
13922                    throw new SecurityException(msg);
13923                }
13924            }
13925        }
13926        if (!allowAll && targetUserId < 0) {
13927            throw new IllegalArgumentException(
13928                    "Call does not support special user #" + targetUserId);
13929        }
13930        return targetUserId;
13931    }
13932
13933    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13934            String className, int flags) {
13935        boolean result = false;
13936        // For apps that don't have pre-defined UIDs, check for permission
13937        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13938            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13939                if (ActivityManager.checkUidPermission(
13940                        INTERACT_ACROSS_USERS,
13941                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13942                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13943                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13944                            + " requests FLAG_SINGLE_USER, but app does not hold "
13945                            + INTERACT_ACROSS_USERS;
13946                    Slog.w(TAG, msg);
13947                    throw new SecurityException(msg);
13948                }
13949                // Permission passed
13950                result = true;
13951            }
13952        } else if ("system".equals(componentProcessName)) {
13953            result = true;
13954        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
13955                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13956            // Phone app is allowed to export singleuser providers.
13957            result = true;
13958        } else {
13959            // App with pre-defined UID, check if it's a persistent app
13960            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13961        }
13962        if (DEBUG_MU) {
13963            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13964                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13965        }
13966        return result;
13967    }
13968
13969    /**
13970     * Checks to see if the caller is in the same app as the singleton
13971     * component, or the component is in a special app. It allows special apps
13972     * to export singleton components but prevents exporting singleton
13973     * components for regular apps.
13974     */
13975    boolean isValidSingletonCall(int callingUid, int componentUid) {
13976        int componentAppId = UserHandle.getAppId(componentUid);
13977        return UserHandle.isSameApp(callingUid, componentUid)
13978                || componentAppId == Process.SYSTEM_UID
13979                || componentAppId == Process.PHONE_UID
13980                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13981                        == PackageManager.PERMISSION_GRANTED;
13982    }
13983
13984    public int bindService(IApplicationThread caller, IBinder token,
13985            Intent service, String resolvedType,
13986            IServiceConnection connection, int flags, int userId) {
13987        enforceNotIsolatedCaller("bindService");
13988        // Refuse possible leaked file descriptors
13989        if (service != null && service.hasFileDescriptors() == true) {
13990            throw new IllegalArgumentException("File descriptors passed in Intent");
13991        }
13992
13993        synchronized(this) {
13994            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13995                    connection, flags, userId);
13996        }
13997    }
13998
13999    public boolean unbindService(IServiceConnection connection) {
14000        synchronized (this) {
14001            return mServices.unbindServiceLocked(connection);
14002        }
14003    }
14004
14005    public void publishService(IBinder token, Intent intent, IBinder service) {
14006        // Refuse possible leaked file descriptors
14007        if (intent != null && intent.hasFileDescriptors() == true) {
14008            throw new IllegalArgumentException("File descriptors passed in Intent");
14009        }
14010
14011        synchronized(this) {
14012            if (!(token instanceof ServiceRecord)) {
14013                throw new IllegalArgumentException("Invalid service token");
14014            }
14015            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14016        }
14017    }
14018
14019    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14020        // Refuse possible leaked file descriptors
14021        if (intent != null && intent.hasFileDescriptors() == true) {
14022            throw new IllegalArgumentException("File descriptors passed in Intent");
14023        }
14024
14025        synchronized(this) {
14026            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14027        }
14028    }
14029
14030    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14031        synchronized(this) {
14032            if (!(token instanceof ServiceRecord)) {
14033                throw new IllegalArgumentException("Invalid service token");
14034            }
14035            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14036        }
14037    }
14038
14039    // =========================================================
14040    // BACKUP AND RESTORE
14041    // =========================================================
14042
14043    // Cause the target app to be launched if necessary and its backup agent
14044    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14045    // activity manager to announce its creation.
14046    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14047        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14048        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14049
14050        synchronized(this) {
14051            // !!! TODO: currently no check here that we're already bound
14052            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14053            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14054            synchronized (stats) {
14055                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14056            }
14057
14058            // Backup agent is now in use, its package can't be stopped.
14059            try {
14060                AppGlobals.getPackageManager().setPackageStoppedState(
14061                        app.packageName, false, UserHandle.getUserId(app.uid));
14062            } catch (RemoteException e) {
14063            } catch (IllegalArgumentException e) {
14064                Slog.w(TAG, "Failed trying to unstop package "
14065                        + app.packageName + ": " + e);
14066            }
14067
14068            BackupRecord r = new BackupRecord(ss, app, backupMode);
14069            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14070                    ? new ComponentName(app.packageName, app.backupAgentName)
14071                    : new ComponentName("android", "FullBackupAgent");
14072            // startProcessLocked() returns existing proc's record if it's already running
14073            ProcessRecord proc = startProcessLocked(app.processName, app,
14074                    false, 0, "backup", hostingName, false, false, false);
14075            if (proc == null) {
14076                Slog.e(TAG, "Unable to start backup agent process " + r);
14077                return false;
14078            }
14079
14080            r.app = proc;
14081            mBackupTarget = r;
14082            mBackupAppName = app.packageName;
14083
14084            // Try not to kill the process during backup
14085            updateOomAdjLocked(proc);
14086
14087            // If the process is already attached, schedule the creation of the backup agent now.
14088            // If it is not yet live, this will be done when it attaches to the framework.
14089            if (proc.thread != null) {
14090                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14091                try {
14092                    proc.thread.scheduleCreateBackupAgent(app,
14093                            compatibilityInfoForPackageLocked(app), backupMode);
14094                } catch (RemoteException e) {
14095                    // Will time out on the backup manager side
14096                }
14097            } else {
14098                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14099            }
14100            // Invariants: at this point, the target app process exists and the application
14101            // is either already running or in the process of coming up.  mBackupTarget and
14102            // mBackupAppName describe the app, so that when it binds back to the AM we
14103            // know that it's scheduled for a backup-agent operation.
14104        }
14105
14106        return true;
14107    }
14108
14109    @Override
14110    public void clearPendingBackup() {
14111        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14112        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14113
14114        synchronized (this) {
14115            mBackupTarget = null;
14116            mBackupAppName = null;
14117        }
14118    }
14119
14120    // A backup agent has just come up
14121    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14122        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14123                + " = " + agent);
14124
14125        synchronized(this) {
14126            if (!agentPackageName.equals(mBackupAppName)) {
14127                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14128                return;
14129            }
14130        }
14131
14132        long oldIdent = Binder.clearCallingIdentity();
14133        try {
14134            IBackupManager bm = IBackupManager.Stub.asInterface(
14135                    ServiceManager.getService(Context.BACKUP_SERVICE));
14136            bm.agentConnected(agentPackageName, agent);
14137        } catch (RemoteException e) {
14138            // can't happen; the backup manager service is local
14139        } catch (Exception e) {
14140            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14141            e.printStackTrace();
14142        } finally {
14143            Binder.restoreCallingIdentity(oldIdent);
14144        }
14145    }
14146
14147    // done with this agent
14148    public void unbindBackupAgent(ApplicationInfo appInfo) {
14149        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14150        if (appInfo == null) {
14151            Slog.w(TAG, "unbind backup agent for null app");
14152            return;
14153        }
14154
14155        synchronized(this) {
14156            try {
14157                if (mBackupAppName == null) {
14158                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14159                    return;
14160                }
14161
14162                if (!mBackupAppName.equals(appInfo.packageName)) {
14163                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14164                    return;
14165                }
14166
14167                // Not backing this app up any more; reset its OOM adjustment
14168                final ProcessRecord proc = mBackupTarget.app;
14169                updateOomAdjLocked(proc);
14170
14171                // If the app crashed during backup, 'thread' will be null here
14172                if (proc.thread != null) {
14173                    try {
14174                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14175                                compatibilityInfoForPackageLocked(appInfo));
14176                    } catch (Exception e) {
14177                        Slog.e(TAG, "Exception when unbinding backup agent:");
14178                        e.printStackTrace();
14179                    }
14180                }
14181            } finally {
14182                mBackupTarget = null;
14183                mBackupAppName = null;
14184            }
14185        }
14186    }
14187    // =========================================================
14188    // BROADCASTS
14189    // =========================================================
14190
14191    private final List getStickiesLocked(String action, IntentFilter filter,
14192            List cur, int userId) {
14193        final ContentResolver resolver = mContext.getContentResolver();
14194        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14195        if (stickies == null) {
14196            return cur;
14197        }
14198        final ArrayList<Intent> list = stickies.get(action);
14199        if (list == null) {
14200            return cur;
14201        }
14202        int N = list.size();
14203        for (int i=0; i<N; i++) {
14204            Intent intent = list.get(i);
14205            if (filter.match(resolver, intent, true, TAG) >= 0) {
14206                if (cur == null) {
14207                    cur = new ArrayList<Intent>();
14208                }
14209                cur.add(intent);
14210            }
14211        }
14212        return cur;
14213    }
14214
14215    boolean isPendingBroadcastProcessLocked(int pid) {
14216        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14217                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14218    }
14219
14220    void skipPendingBroadcastLocked(int pid) {
14221            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14222            for (BroadcastQueue queue : mBroadcastQueues) {
14223                queue.skipPendingBroadcastLocked(pid);
14224            }
14225    }
14226
14227    // The app just attached; send any pending broadcasts that it should receive
14228    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14229        boolean didSomething = false;
14230        for (BroadcastQueue queue : mBroadcastQueues) {
14231            didSomething |= queue.sendPendingBroadcastsLocked(app);
14232        }
14233        return didSomething;
14234    }
14235
14236    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14237            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14238        enforceNotIsolatedCaller("registerReceiver");
14239        int callingUid;
14240        int callingPid;
14241        synchronized(this) {
14242            ProcessRecord callerApp = null;
14243            if (caller != null) {
14244                callerApp = getRecordForAppLocked(caller);
14245                if (callerApp == null) {
14246                    throw new SecurityException(
14247                            "Unable to find app for caller " + caller
14248                            + " (pid=" + Binder.getCallingPid()
14249                            + ") when registering receiver " + receiver);
14250                }
14251                if (callerApp.info.uid != Process.SYSTEM_UID &&
14252                        !callerApp.pkgList.containsKey(callerPackage) &&
14253                        !"android".equals(callerPackage)) {
14254                    throw new SecurityException("Given caller package " + callerPackage
14255                            + " is not running in process " + callerApp);
14256                }
14257                callingUid = callerApp.info.uid;
14258                callingPid = callerApp.pid;
14259            } else {
14260                callerPackage = null;
14261                callingUid = Binder.getCallingUid();
14262                callingPid = Binder.getCallingPid();
14263            }
14264
14265            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14266                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14267
14268            List allSticky = null;
14269
14270            // Look for any matching sticky broadcasts...
14271            Iterator actions = filter.actionsIterator();
14272            if (actions != null) {
14273                while (actions.hasNext()) {
14274                    String action = (String)actions.next();
14275                    allSticky = getStickiesLocked(action, filter, allSticky,
14276                            UserHandle.USER_ALL);
14277                    allSticky = getStickiesLocked(action, filter, allSticky,
14278                            UserHandle.getUserId(callingUid));
14279                }
14280            } else {
14281                allSticky = getStickiesLocked(null, filter, allSticky,
14282                        UserHandle.USER_ALL);
14283                allSticky = getStickiesLocked(null, filter, allSticky,
14284                        UserHandle.getUserId(callingUid));
14285            }
14286
14287            // The first sticky in the list is returned directly back to
14288            // the client.
14289            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14290
14291            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14292                    + ": " + sticky);
14293
14294            if (receiver == null) {
14295                return sticky;
14296            }
14297
14298            ReceiverList rl
14299                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14300            if (rl == null) {
14301                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14302                        userId, receiver);
14303                if (rl.app != null) {
14304                    rl.app.receivers.add(rl);
14305                } else {
14306                    try {
14307                        receiver.asBinder().linkToDeath(rl, 0);
14308                    } catch (RemoteException e) {
14309                        return sticky;
14310                    }
14311                    rl.linkedToDeath = true;
14312                }
14313                mRegisteredReceivers.put(receiver.asBinder(), rl);
14314            } else if (rl.uid != callingUid) {
14315                throw new IllegalArgumentException(
14316                        "Receiver requested to register for uid " + callingUid
14317                        + " was previously registered for uid " + rl.uid);
14318            } else if (rl.pid != callingPid) {
14319                throw new IllegalArgumentException(
14320                        "Receiver requested to register for pid " + callingPid
14321                        + " was previously registered for pid " + rl.pid);
14322            } else if (rl.userId != userId) {
14323                throw new IllegalArgumentException(
14324                        "Receiver requested to register for user " + userId
14325                        + " was previously registered for user " + rl.userId);
14326            }
14327            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14328                    permission, callingUid, userId);
14329            rl.add(bf);
14330            if (!bf.debugCheck()) {
14331                Slog.w(TAG, "==> For Dynamic broadast");
14332            }
14333            mReceiverResolver.addFilter(bf);
14334
14335            // Enqueue broadcasts for all existing stickies that match
14336            // this filter.
14337            if (allSticky != null) {
14338                ArrayList receivers = new ArrayList();
14339                receivers.add(bf);
14340
14341                int N = allSticky.size();
14342                for (int i=0; i<N; i++) {
14343                    Intent intent = (Intent)allSticky.get(i);
14344                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14345                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14346                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14347                            null, null, false, true, true, -1);
14348                    queue.enqueueParallelBroadcastLocked(r);
14349                    queue.scheduleBroadcastsLocked();
14350                }
14351            }
14352
14353            return sticky;
14354        }
14355    }
14356
14357    public void unregisterReceiver(IIntentReceiver receiver) {
14358        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14359
14360        final long origId = Binder.clearCallingIdentity();
14361        try {
14362            boolean doTrim = false;
14363
14364            synchronized(this) {
14365                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14366                if (rl != null) {
14367                    if (rl.curBroadcast != null) {
14368                        BroadcastRecord r = rl.curBroadcast;
14369                        final boolean doNext = finishReceiverLocked(
14370                                receiver.asBinder(), r.resultCode, r.resultData,
14371                                r.resultExtras, r.resultAbort);
14372                        if (doNext) {
14373                            doTrim = true;
14374                            r.queue.processNextBroadcast(false);
14375                        }
14376                    }
14377
14378                    if (rl.app != null) {
14379                        rl.app.receivers.remove(rl);
14380                    }
14381                    removeReceiverLocked(rl);
14382                    if (rl.linkedToDeath) {
14383                        rl.linkedToDeath = false;
14384                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14385                    }
14386                }
14387            }
14388
14389            // If we actually concluded any broadcasts, we might now be able
14390            // to trim the recipients' apps from our working set
14391            if (doTrim) {
14392                trimApplications();
14393                return;
14394            }
14395
14396        } finally {
14397            Binder.restoreCallingIdentity(origId);
14398        }
14399    }
14400
14401    void removeReceiverLocked(ReceiverList rl) {
14402        mRegisteredReceivers.remove(rl.receiver.asBinder());
14403        int N = rl.size();
14404        for (int i=0; i<N; i++) {
14405            mReceiverResolver.removeFilter(rl.get(i));
14406        }
14407    }
14408
14409    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14410        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14411            ProcessRecord r = mLruProcesses.get(i);
14412            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14413                try {
14414                    r.thread.dispatchPackageBroadcast(cmd, packages);
14415                } catch (RemoteException ex) {
14416                }
14417            }
14418        }
14419    }
14420
14421    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14422            int[] users) {
14423        List<ResolveInfo> receivers = null;
14424        try {
14425            HashSet<ComponentName> singleUserReceivers = null;
14426            boolean scannedFirstReceivers = false;
14427            for (int user : users) {
14428                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14429                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14430                if (user != 0 && newReceivers != null) {
14431                    // If this is not the primary user, we need to check for
14432                    // any receivers that should be filtered out.
14433                    for (int i=0; i<newReceivers.size(); i++) {
14434                        ResolveInfo ri = newReceivers.get(i);
14435                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14436                            newReceivers.remove(i);
14437                            i--;
14438                        }
14439                    }
14440                }
14441                if (newReceivers != null && newReceivers.size() == 0) {
14442                    newReceivers = null;
14443                }
14444                if (receivers == null) {
14445                    receivers = newReceivers;
14446                } else if (newReceivers != null) {
14447                    // We need to concatenate the additional receivers
14448                    // found with what we have do far.  This would be easy,
14449                    // but we also need to de-dup any receivers that are
14450                    // singleUser.
14451                    if (!scannedFirstReceivers) {
14452                        // Collect any single user receivers we had already retrieved.
14453                        scannedFirstReceivers = true;
14454                        for (int i=0; i<receivers.size(); i++) {
14455                            ResolveInfo ri = receivers.get(i);
14456                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14457                                ComponentName cn = new ComponentName(
14458                                        ri.activityInfo.packageName, ri.activityInfo.name);
14459                                if (singleUserReceivers == null) {
14460                                    singleUserReceivers = new HashSet<ComponentName>();
14461                                }
14462                                singleUserReceivers.add(cn);
14463                            }
14464                        }
14465                    }
14466                    // Add the new results to the existing results, tracking
14467                    // and de-dupping single user receivers.
14468                    for (int i=0; i<newReceivers.size(); i++) {
14469                        ResolveInfo ri = newReceivers.get(i);
14470                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14471                            ComponentName cn = new ComponentName(
14472                                    ri.activityInfo.packageName, ri.activityInfo.name);
14473                            if (singleUserReceivers == null) {
14474                                singleUserReceivers = new HashSet<ComponentName>();
14475                            }
14476                            if (!singleUserReceivers.contains(cn)) {
14477                                singleUserReceivers.add(cn);
14478                                receivers.add(ri);
14479                            }
14480                        } else {
14481                            receivers.add(ri);
14482                        }
14483                    }
14484                }
14485            }
14486        } catch (RemoteException ex) {
14487            // pm is in same process, this will never happen.
14488        }
14489        return receivers;
14490    }
14491
14492    private final int broadcastIntentLocked(ProcessRecord callerApp,
14493            String callerPackage, Intent intent, String resolvedType,
14494            IIntentReceiver resultTo, int resultCode, String resultData,
14495            Bundle map, String requiredPermission, int appOp,
14496            boolean ordered, boolean sticky, int callingPid, int callingUid,
14497            int userId) {
14498        intent = new Intent(intent);
14499
14500        // By default broadcasts do not go to stopped apps.
14501        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14502
14503        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14504            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14505            + " ordered=" + ordered + " userid=" + userId);
14506        if ((resultTo != null) && !ordered) {
14507            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14508        }
14509
14510        userId = handleIncomingUser(callingPid, callingUid, userId,
14511                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14512
14513        // Make sure that the user who is receiving this broadcast is started.
14514        // If not, we will just skip it.
14515
14516
14517        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14518            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14519                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14520                Slog.w(TAG, "Skipping broadcast of " + intent
14521                        + ": user " + userId + " is stopped");
14522                return ActivityManager.BROADCAST_SUCCESS;
14523            }
14524        }
14525
14526        /*
14527         * Prevent non-system code (defined here to be non-persistent
14528         * processes) from sending protected broadcasts.
14529         */
14530        int callingAppId = UserHandle.getAppId(callingUid);
14531        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14532            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14533            || callingAppId == Process.NFC_UID || callingUid == 0) {
14534            // Always okay.
14535        } else if (callerApp == null || !callerApp.persistent) {
14536            try {
14537                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14538                        intent.getAction())) {
14539                    String msg = "Permission Denial: not allowed to send broadcast "
14540                            + intent.getAction() + " from pid="
14541                            + callingPid + ", uid=" + callingUid;
14542                    Slog.w(TAG, msg);
14543                    throw new SecurityException(msg);
14544                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14545                    // Special case for compatibility: we don't want apps to send this,
14546                    // but historically it has not been protected and apps may be using it
14547                    // to poke their own app widget.  So, instead of making it protected,
14548                    // just limit it to the caller.
14549                    if (callerApp == null) {
14550                        String msg = "Permission Denial: not allowed to send broadcast "
14551                                + intent.getAction() + " from unknown caller.";
14552                        Slog.w(TAG, msg);
14553                        throw new SecurityException(msg);
14554                    } else if (intent.getComponent() != null) {
14555                        // They are good enough to send to an explicit component...  verify
14556                        // it is being sent to the calling app.
14557                        if (!intent.getComponent().getPackageName().equals(
14558                                callerApp.info.packageName)) {
14559                            String msg = "Permission Denial: not allowed to send broadcast "
14560                                    + intent.getAction() + " to "
14561                                    + intent.getComponent().getPackageName() + " from "
14562                                    + callerApp.info.packageName;
14563                            Slog.w(TAG, msg);
14564                            throw new SecurityException(msg);
14565                        }
14566                    } else {
14567                        // Limit broadcast to their own package.
14568                        intent.setPackage(callerApp.info.packageName);
14569                    }
14570                }
14571            } catch (RemoteException e) {
14572                Slog.w(TAG, "Remote exception", e);
14573                return ActivityManager.BROADCAST_SUCCESS;
14574            }
14575        }
14576
14577        // Handle special intents: if this broadcast is from the package
14578        // manager about a package being removed, we need to remove all of
14579        // its activities from the history stack.
14580        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14581                intent.getAction());
14582        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14583                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14584                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14585                || uidRemoved) {
14586            if (checkComponentPermission(
14587                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14588                    callingPid, callingUid, -1, true)
14589                    == PackageManager.PERMISSION_GRANTED) {
14590                if (uidRemoved) {
14591                    final Bundle intentExtras = intent.getExtras();
14592                    final int uid = intentExtras != null
14593                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14594                    if (uid >= 0) {
14595                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14596                        synchronized (bs) {
14597                            bs.removeUidStatsLocked(uid);
14598                        }
14599                        mAppOpsService.uidRemoved(uid);
14600                    }
14601                } else {
14602                    // If resources are unavailable just force stop all
14603                    // those packages and flush the attribute cache as well.
14604                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14605                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14606                        if (list != null && (list.length > 0)) {
14607                            for (String pkg : list) {
14608                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14609                                        "storage unmount");
14610                            }
14611                            sendPackageBroadcastLocked(
14612                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14613                        }
14614                    } else {
14615                        Uri data = intent.getData();
14616                        String ssp;
14617                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14618                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14619                                    intent.getAction());
14620                            boolean fullUninstall = removed &&
14621                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14622                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14623                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14624                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14625                                        false, fullUninstall, userId,
14626                                        removed ? "pkg removed" : "pkg changed");
14627                            }
14628                            if (removed) {
14629                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14630                                        new String[] {ssp}, userId);
14631                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14632                                    mAppOpsService.packageRemoved(
14633                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14634
14635                                    // Remove all permissions granted from/to this package
14636                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14637                                }
14638                            }
14639                        }
14640                    }
14641                }
14642            } else {
14643                String msg = "Permission Denial: " + intent.getAction()
14644                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14645                        + ", uid=" + callingUid + ")"
14646                        + " requires "
14647                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14648                Slog.w(TAG, msg);
14649                throw new SecurityException(msg);
14650            }
14651
14652        // Special case for adding a package: by default turn on compatibility
14653        // mode.
14654        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14655            Uri data = intent.getData();
14656            String ssp;
14657            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14658                mCompatModePackages.handlePackageAddedLocked(ssp,
14659                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14660            }
14661        }
14662
14663        /*
14664         * If this is the time zone changed action, queue up a message that will reset the timezone
14665         * of all currently running processes. This message will get queued up before the broadcast
14666         * happens.
14667         */
14668        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14669            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14670        }
14671
14672        /*
14673         * If the user set the time, let all running processes know.
14674         */
14675        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14676            final int is24Hour = intent.getBooleanExtra(
14677                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14678            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14679        }
14680
14681        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14682            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14683        }
14684
14685        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14686            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14687            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14688        }
14689
14690        // Add to the sticky list if requested.
14691        if (sticky) {
14692            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14693                    callingPid, callingUid)
14694                    != PackageManager.PERMISSION_GRANTED) {
14695                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14696                        + callingPid + ", uid=" + callingUid
14697                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14698                Slog.w(TAG, msg);
14699                throw new SecurityException(msg);
14700            }
14701            if (requiredPermission != null) {
14702                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14703                        + " and enforce permission " + requiredPermission);
14704                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14705            }
14706            if (intent.getComponent() != null) {
14707                throw new SecurityException(
14708                        "Sticky broadcasts can't target a specific component");
14709            }
14710            // We use userId directly here, since the "all" target is maintained
14711            // as a separate set of sticky broadcasts.
14712            if (userId != UserHandle.USER_ALL) {
14713                // But first, if this is not a broadcast to all users, then
14714                // make sure it doesn't conflict with an existing broadcast to
14715                // all users.
14716                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14717                        UserHandle.USER_ALL);
14718                if (stickies != null) {
14719                    ArrayList<Intent> list = stickies.get(intent.getAction());
14720                    if (list != null) {
14721                        int N = list.size();
14722                        int i;
14723                        for (i=0; i<N; i++) {
14724                            if (intent.filterEquals(list.get(i))) {
14725                                throw new IllegalArgumentException(
14726                                        "Sticky broadcast " + intent + " for user "
14727                                        + userId + " conflicts with existing global broadcast");
14728                            }
14729                        }
14730                    }
14731                }
14732            }
14733            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14734            if (stickies == null) {
14735                stickies = new ArrayMap<String, ArrayList<Intent>>();
14736                mStickyBroadcasts.put(userId, stickies);
14737            }
14738            ArrayList<Intent> list = stickies.get(intent.getAction());
14739            if (list == null) {
14740                list = new ArrayList<Intent>();
14741                stickies.put(intent.getAction(), list);
14742            }
14743            int N = list.size();
14744            int i;
14745            for (i=0; i<N; i++) {
14746                if (intent.filterEquals(list.get(i))) {
14747                    // This sticky already exists, replace it.
14748                    list.set(i, new Intent(intent));
14749                    break;
14750                }
14751            }
14752            if (i >= N) {
14753                list.add(new Intent(intent));
14754            }
14755        }
14756
14757        int[] users;
14758        if (userId == UserHandle.USER_ALL) {
14759            // Caller wants broadcast to go to all started users.
14760            users = mStartedUserArray;
14761        } else {
14762            // Caller wants broadcast to go to one specific user.
14763            users = new int[] {userId};
14764        }
14765
14766        // Figure out who all will receive this broadcast.
14767        List receivers = null;
14768        List<BroadcastFilter> registeredReceivers = null;
14769        // Need to resolve the intent to interested receivers...
14770        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14771                 == 0) {
14772            receivers = collectReceiverComponents(intent, resolvedType, users);
14773        }
14774        if (intent.getComponent() == null) {
14775            registeredReceivers = mReceiverResolver.queryIntent(intent,
14776                    resolvedType, false, userId);
14777        }
14778
14779        final boolean replacePending =
14780                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14781
14782        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14783                + " replacePending=" + replacePending);
14784
14785        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14786        if (!ordered && NR > 0) {
14787            // If we are not serializing this broadcast, then send the
14788            // registered receivers separately so they don't wait for the
14789            // components to be launched.
14790            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14791            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14792                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14793                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14794                    ordered, sticky, false, userId);
14795            if (DEBUG_BROADCAST) Slog.v(
14796                    TAG, "Enqueueing parallel broadcast " + r);
14797            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14798            if (!replaced) {
14799                queue.enqueueParallelBroadcastLocked(r);
14800                queue.scheduleBroadcastsLocked();
14801            }
14802            registeredReceivers = null;
14803            NR = 0;
14804        }
14805
14806        // Merge into one list.
14807        int ir = 0;
14808        if (receivers != null) {
14809            // A special case for PACKAGE_ADDED: do not allow the package
14810            // being added to see this broadcast.  This prevents them from
14811            // using this as a back door to get run as soon as they are
14812            // installed.  Maybe in the future we want to have a special install
14813            // broadcast or such for apps, but we'd like to deliberately make
14814            // this decision.
14815            String skipPackages[] = null;
14816            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14817                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14818                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14819                Uri data = intent.getData();
14820                if (data != null) {
14821                    String pkgName = data.getSchemeSpecificPart();
14822                    if (pkgName != null) {
14823                        skipPackages = new String[] { pkgName };
14824                    }
14825                }
14826            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14827                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14828            }
14829            if (skipPackages != null && (skipPackages.length > 0)) {
14830                for (String skipPackage : skipPackages) {
14831                    if (skipPackage != null) {
14832                        int NT = receivers.size();
14833                        for (int it=0; it<NT; it++) {
14834                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14835                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14836                                receivers.remove(it);
14837                                it--;
14838                                NT--;
14839                            }
14840                        }
14841                    }
14842                }
14843            }
14844
14845            int NT = receivers != null ? receivers.size() : 0;
14846            int it = 0;
14847            ResolveInfo curt = null;
14848            BroadcastFilter curr = null;
14849            while (it < NT && ir < NR) {
14850                if (curt == null) {
14851                    curt = (ResolveInfo)receivers.get(it);
14852                }
14853                if (curr == null) {
14854                    curr = registeredReceivers.get(ir);
14855                }
14856                if (curr.getPriority() >= curt.priority) {
14857                    // Insert this broadcast record into the final list.
14858                    receivers.add(it, curr);
14859                    ir++;
14860                    curr = null;
14861                    it++;
14862                    NT++;
14863                } else {
14864                    // Skip to the next ResolveInfo in the final list.
14865                    it++;
14866                    curt = null;
14867                }
14868            }
14869        }
14870        while (ir < NR) {
14871            if (receivers == null) {
14872                receivers = new ArrayList();
14873            }
14874            receivers.add(registeredReceivers.get(ir));
14875            ir++;
14876        }
14877
14878        if ((receivers != null && receivers.size() > 0)
14879                || resultTo != null) {
14880            BroadcastQueue queue = broadcastQueueForIntent(intent);
14881            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14882                    callerPackage, callingPid, callingUid, resolvedType,
14883                    requiredPermission, appOp, receivers, resultTo, resultCode,
14884                    resultData, map, ordered, sticky, false, userId);
14885            if (DEBUG_BROADCAST) Slog.v(
14886                    TAG, "Enqueueing ordered broadcast " + r
14887                    + ": prev had " + queue.mOrderedBroadcasts.size());
14888            if (DEBUG_BROADCAST) {
14889                int seq = r.intent.getIntExtra("seq", -1);
14890                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14891            }
14892            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14893            if (!replaced) {
14894                queue.enqueueOrderedBroadcastLocked(r);
14895                queue.scheduleBroadcastsLocked();
14896            }
14897        }
14898
14899        return ActivityManager.BROADCAST_SUCCESS;
14900    }
14901
14902    final Intent verifyBroadcastLocked(Intent intent) {
14903        // Refuse possible leaked file descriptors
14904        if (intent != null && intent.hasFileDescriptors() == true) {
14905            throw new IllegalArgumentException("File descriptors passed in Intent");
14906        }
14907
14908        int flags = intent.getFlags();
14909
14910        if (!mProcessesReady) {
14911            // if the caller really truly claims to know what they're doing, go
14912            // ahead and allow the broadcast without launching any receivers
14913            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14914                intent = new Intent(intent);
14915                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14916            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14917                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14918                        + " before boot completion");
14919                throw new IllegalStateException("Cannot broadcast before boot completed");
14920            }
14921        }
14922
14923        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14924            throw new IllegalArgumentException(
14925                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14926        }
14927
14928        return intent;
14929    }
14930
14931    public final int broadcastIntent(IApplicationThread caller,
14932            Intent intent, String resolvedType, IIntentReceiver resultTo,
14933            int resultCode, String resultData, Bundle map,
14934            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14935        enforceNotIsolatedCaller("broadcastIntent");
14936        synchronized(this) {
14937            intent = verifyBroadcastLocked(intent);
14938
14939            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14940            final int callingPid = Binder.getCallingPid();
14941            final int callingUid = Binder.getCallingUid();
14942            final long origId = Binder.clearCallingIdentity();
14943            int res = broadcastIntentLocked(callerApp,
14944                    callerApp != null ? callerApp.info.packageName : null,
14945                    intent, resolvedType, resultTo,
14946                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14947                    callingPid, callingUid, userId);
14948            Binder.restoreCallingIdentity(origId);
14949            return res;
14950        }
14951    }
14952
14953    int broadcastIntentInPackage(String packageName, int uid,
14954            Intent intent, String resolvedType, IIntentReceiver resultTo,
14955            int resultCode, String resultData, Bundle map,
14956            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14957        synchronized(this) {
14958            intent = verifyBroadcastLocked(intent);
14959
14960            final long origId = Binder.clearCallingIdentity();
14961            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14962                    resultTo, resultCode, resultData, map, requiredPermission,
14963                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14964            Binder.restoreCallingIdentity(origId);
14965            return res;
14966        }
14967    }
14968
14969    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14970        // Refuse possible leaked file descriptors
14971        if (intent != null && intent.hasFileDescriptors() == true) {
14972            throw new IllegalArgumentException("File descriptors passed in Intent");
14973        }
14974
14975        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14976                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14977
14978        synchronized(this) {
14979            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14980                    != PackageManager.PERMISSION_GRANTED) {
14981                String msg = "Permission Denial: unbroadcastIntent() from pid="
14982                        + Binder.getCallingPid()
14983                        + ", uid=" + Binder.getCallingUid()
14984                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14985                Slog.w(TAG, msg);
14986                throw new SecurityException(msg);
14987            }
14988            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14989            if (stickies != null) {
14990                ArrayList<Intent> list = stickies.get(intent.getAction());
14991                if (list != null) {
14992                    int N = list.size();
14993                    int i;
14994                    for (i=0; i<N; i++) {
14995                        if (intent.filterEquals(list.get(i))) {
14996                            list.remove(i);
14997                            break;
14998                        }
14999                    }
15000                    if (list.size() <= 0) {
15001                        stickies.remove(intent.getAction());
15002                    }
15003                }
15004                if (stickies.size() <= 0) {
15005                    mStickyBroadcasts.remove(userId);
15006                }
15007            }
15008        }
15009    }
15010
15011    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15012            String resultData, Bundle resultExtras, boolean resultAbort) {
15013        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15014        if (r == null) {
15015            Slog.w(TAG, "finishReceiver called but not found on queue");
15016            return false;
15017        }
15018
15019        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15020    }
15021
15022    void backgroundServicesFinishedLocked(int userId) {
15023        for (BroadcastQueue queue : mBroadcastQueues) {
15024            queue.backgroundServicesFinishedLocked(userId);
15025        }
15026    }
15027
15028    public void finishReceiver(IBinder who, int resultCode, String resultData,
15029            Bundle resultExtras, boolean resultAbort) {
15030        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15031
15032        // Refuse possible leaked file descriptors
15033        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15034            throw new IllegalArgumentException("File descriptors passed in Bundle");
15035        }
15036
15037        final long origId = Binder.clearCallingIdentity();
15038        try {
15039            boolean doNext = false;
15040            BroadcastRecord r;
15041
15042            synchronized(this) {
15043                r = broadcastRecordForReceiverLocked(who);
15044                if (r != null) {
15045                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15046                        resultData, resultExtras, resultAbort, true);
15047                }
15048            }
15049
15050            if (doNext) {
15051                r.queue.processNextBroadcast(false);
15052            }
15053            trimApplications();
15054        } finally {
15055            Binder.restoreCallingIdentity(origId);
15056        }
15057    }
15058
15059    // =========================================================
15060    // INSTRUMENTATION
15061    // =========================================================
15062
15063    public boolean startInstrumentation(ComponentName className,
15064            String profileFile, int flags, Bundle arguments,
15065            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15066            int userId, String abiOverride) {
15067        enforceNotIsolatedCaller("startInstrumentation");
15068        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15069                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15070        // Refuse possible leaked file descriptors
15071        if (arguments != null && arguments.hasFileDescriptors()) {
15072            throw new IllegalArgumentException("File descriptors passed in Bundle");
15073        }
15074
15075        synchronized(this) {
15076            InstrumentationInfo ii = null;
15077            ApplicationInfo ai = null;
15078            try {
15079                ii = mContext.getPackageManager().getInstrumentationInfo(
15080                    className, STOCK_PM_FLAGS);
15081                ai = AppGlobals.getPackageManager().getApplicationInfo(
15082                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15083            } catch (PackageManager.NameNotFoundException e) {
15084            } catch (RemoteException e) {
15085            }
15086            if (ii == null) {
15087                reportStartInstrumentationFailure(watcher, className,
15088                        "Unable to find instrumentation info for: " + className);
15089                return false;
15090            }
15091            if (ai == null) {
15092                reportStartInstrumentationFailure(watcher, className,
15093                        "Unable to find instrumentation target package: " + ii.targetPackage);
15094                return false;
15095            }
15096
15097            int match = mContext.getPackageManager().checkSignatures(
15098                    ii.targetPackage, ii.packageName);
15099            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15100                String msg = "Permission Denial: starting instrumentation "
15101                        + className + " from pid="
15102                        + Binder.getCallingPid()
15103                        + ", uid=" + Binder.getCallingPid()
15104                        + " not allowed because package " + ii.packageName
15105                        + " does not have a signature matching the target "
15106                        + ii.targetPackage;
15107                reportStartInstrumentationFailure(watcher, className, msg);
15108                throw new SecurityException(msg);
15109            }
15110
15111            final long origId = Binder.clearCallingIdentity();
15112            // Instrumentation can kill and relaunch even persistent processes
15113            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15114                    "start instr");
15115            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15116            app.instrumentationClass = className;
15117            app.instrumentationInfo = ai;
15118            app.instrumentationProfileFile = profileFile;
15119            app.instrumentationArguments = arguments;
15120            app.instrumentationWatcher = watcher;
15121            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15122            app.instrumentationResultClass = className;
15123            Binder.restoreCallingIdentity(origId);
15124        }
15125
15126        return true;
15127    }
15128
15129    /**
15130     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15131     * error to the logs, but if somebody is watching, send the report there too.  This enables
15132     * the "am" command to report errors with more information.
15133     *
15134     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15135     * @param cn The component name of the instrumentation.
15136     * @param report The error report.
15137     */
15138    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15139            ComponentName cn, String report) {
15140        Slog.w(TAG, report);
15141        try {
15142            if (watcher != null) {
15143                Bundle results = new Bundle();
15144                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15145                results.putString("Error", report);
15146                watcher.instrumentationStatus(cn, -1, results);
15147            }
15148        } catch (RemoteException e) {
15149            Slog.w(TAG, e);
15150        }
15151    }
15152
15153    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15154        if (app.instrumentationWatcher != null) {
15155            try {
15156                // NOTE:  IInstrumentationWatcher *must* be oneway here
15157                app.instrumentationWatcher.instrumentationFinished(
15158                    app.instrumentationClass,
15159                    resultCode,
15160                    results);
15161            } catch (RemoteException e) {
15162            }
15163        }
15164        if (app.instrumentationUiAutomationConnection != null) {
15165            try {
15166                app.instrumentationUiAutomationConnection.shutdown();
15167            } catch (RemoteException re) {
15168                /* ignore */
15169            }
15170            // Only a UiAutomation can set this flag and now that
15171            // it is finished we make sure it is reset to its default.
15172            mUserIsMonkey = false;
15173        }
15174        app.instrumentationWatcher = null;
15175        app.instrumentationUiAutomationConnection = null;
15176        app.instrumentationClass = null;
15177        app.instrumentationInfo = null;
15178        app.instrumentationProfileFile = null;
15179        app.instrumentationArguments = null;
15180
15181        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15182                "finished inst");
15183    }
15184
15185    public void finishInstrumentation(IApplicationThread target,
15186            int resultCode, Bundle results) {
15187        int userId = UserHandle.getCallingUserId();
15188        // Refuse possible leaked file descriptors
15189        if (results != null && results.hasFileDescriptors()) {
15190            throw new IllegalArgumentException("File descriptors passed in Intent");
15191        }
15192
15193        synchronized(this) {
15194            ProcessRecord app = getRecordForAppLocked(target);
15195            if (app == null) {
15196                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15197                return;
15198            }
15199            final long origId = Binder.clearCallingIdentity();
15200            finishInstrumentationLocked(app, resultCode, results);
15201            Binder.restoreCallingIdentity(origId);
15202        }
15203    }
15204
15205    // =========================================================
15206    // CONFIGURATION
15207    // =========================================================
15208
15209    public ConfigurationInfo getDeviceConfigurationInfo() {
15210        ConfigurationInfo config = new ConfigurationInfo();
15211        synchronized (this) {
15212            config.reqTouchScreen = mConfiguration.touchscreen;
15213            config.reqKeyboardType = mConfiguration.keyboard;
15214            config.reqNavigation = mConfiguration.navigation;
15215            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15216                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15217                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15218            }
15219            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15220                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15221                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15222            }
15223            config.reqGlEsVersion = GL_ES_VERSION;
15224        }
15225        return config;
15226    }
15227
15228    ActivityStack getFocusedStack() {
15229        return mStackSupervisor.getFocusedStack();
15230    }
15231
15232    public Configuration getConfiguration() {
15233        Configuration ci;
15234        synchronized(this) {
15235            ci = new Configuration(mConfiguration);
15236        }
15237        return ci;
15238    }
15239
15240    public void updatePersistentConfiguration(Configuration values) {
15241        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15242                "updateConfiguration()");
15243        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15244                "updateConfiguration()");
15245        if (values == null) {
15246            throw new NullPointerException("Configuration must not be null");
15247        }
15248
15249        synchronized(this) {
15250            final long origId = Binder.clearCallingIdentity();
15251            updateConfigurationLocked(values, null, true, false);
15252            Binder.restoreCallingIdentity(origId);
15253        }
15254    }
15255
15256    public void updateConfiguration(Configuration values) {
15257        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15258                "updateConfiguration()");
15259
15260        synchronized(this) {
15261            if (values == null && mWindowManager != null) {
15262                // sentinel: fetch the current configuration from the window manager
15263                values = mWindowManager.computeNewConfiguration();
15264            }
15265
15266            if (mWindowManager != null) {
15267                mProcessList.applyDisplaySize(mWindowManager);
15268            }
15269
15270            final long origId = Binder.clearCallingIdentity();
15271            if (values != null) {
15272                Settings.System.clearConfiguration(values);
15273            }
15274            updateConfigurationLocked(values, null, false, false);
15275            Binder.restoreCallingIdentity(origId);
15276        }
15277    }
15278
15279    /**
15280     * Do either or both things: (1) change the current configuration, and (2)
15281     * make sure the given activity is running with the (now) current
15282     * configuration.  Returns true if the activity has been left running, or
15283     * false if <var>starting</var> is being destroyed to match the new
15284     * configuration.
15285     * @param persistent TODO
15286     */
15287    boolean updateConfigurationLocked(Configuration values,
15288            ActivityRecord starting, boolean persistent, boolean initLocale) {
15289        int changes = 0;
15290
15291        if (values != null) {
15292            Configuration newConfig = new Configuration(mConfiguration);
15293            changes = newConfig.updateFrom(values);
15294            if (changes != 0) {
15295                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15296                    Slog.i(TAG, "Updating configuration to: " + values);
15297                }
15298
15299                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15300
15301                if (values.locale != null && !initLocale) {
15302                    saveLocaleLocked(values.locale,
15303                                     !values.locale.equals(mConfiguration.locale),
15304                                     values.userSetLocale);
15305                }
15306
15307                mConfigurationSeq++;
15308                if (mConfigurationSeq <= 0) {
15309                    mConfigurationSeq = 1;
15310                }
15311                newConfig.seq = mConfigurationSeq;
15312                mConfiguration = newConfig;
15313                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15314                //mUsageStatsService.noteStartConfig(newConfig);
15315
15316                final Configuration configCopy = new Configuration(mConfiguration);
15317
15318                // TODO: If our config changes, should we auto dismiss any currently
15319                // showing dialogs?
15320                mShowDialogs = shouldShowDialogs(newConfig);
15321
15322                AttributeCache ac = AttributeCache.instance();
15323                if (ac != null) {
15324                    ac.updateConfiguration(configCopy);
15325                }
15326
15327                // Make sure all resources in our process are updated
15328                // right now, so that anyone who is going to retrieve
15329                // resource values after we return will be sure to get
15330                // the new ones.  This is especially important during
15331                // boot, where the first config change needs to guarantee
15332                // all resources have that config before following boot
15333                // code is executed.
15334                mSystemThread.applyConfigurationToResources(configCopy);
15335
15336                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15337                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15338                    msg.obj = new Configuration(configCopy);
15339                    mHandler.sendMessage(msg);
15340                }
15341
15342                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15343                    ProcessRecord app = mLruProcesses.get(i);
15344                    try {
15345                        if (app.thread != null) {
15346                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15347                                    + app.processName + " new config " + mConfiguration);
15348                            app.thread.scheduleConfigurationChanged(configCopy);
15349                        }
15350                    } catch (Exception e) {
15351                    }
15352                }
15353                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15354                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15355                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15356                        | Intent.FLAG_RECEIVER_FOREGROUND);
15357                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15358                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15359                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15360                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15361                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15362                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15363                    broadcastIntentLocked(null, null, intent,
15364                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15365                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15366                }
15367            }
15368        }
15369
15370        boolean kept = true;
15371        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15372        // mainStack is null during startup.
15373        if (mainStack != null) {
15374            if (changes != 0 && starting == null) {
15375                // If the configuration changed, and the caller is not already
15376                // in the process of starting an activity, then find the top
15377                // activity to check if its configuration needs to change.
15378                starting = mainStack.topRunningActivityLocked(null);
15379            }
15380
15381            if (starting != null) {
15382                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15383                // And we need to make sure at this point that all other activities
15384                // are made visible with the correct configuration.
15385                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15386            }
15387        }
15388
15389        if (values != null && mWindowManager != null) {
15390            mWindowManager.setNewConfiguration(mConfiguration);
15391        }
15392
15393        return kept;
15394    }
15395
15396    /**
15397     * Decide based on the configuration whether we should shouw the ANR,
15398     * crash, etc dialogs.  The idea is that if there is no affordnace to
15399     * press the on-screen buttons, we shouldn't show the dialog.
15400     *
15401     * A thought: SystemUI might also want to get told about this, the Power
15402     * dialog / global actions also might want different behaviors.
15403     */
15404    private static final boolean shouldShowDialogs(Configuration config) {
15405        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15406                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15407    }
15408
15409    /**
15410     * Save the locale.  You must be inside a synchronized (this) block.
15411     */
15412    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15413        if(isDiff) {
15414            SystemProperties.set("user.language", l.getLanguage());
15415            SystemProperties.set("user.region", l.getCountry());
15416        }
15417
15418        if(isPersist) {
15419            SystemProperties.set("persist.sys.language", l.getLanguage());
15420            SystemProperties.set("persist.sys.country", l.getCountry());
15421            SystemProperties.set("persist.sys.localevar", l.getVariant());
15422        }
15423    }
15424
15425    @Override
15426    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15427        ActivityRecord srec = ActivityRecord.forToken(token);
15428        return srec != null && srec.task.affinity != null &&
15429                srec.task.affinity.equals(destAffinity);
15430    }
15431
15432    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15433            Intent resultData) {
15434
15435        synchronized (this) {
15436            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15437            if (stack != null) {
15438                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15439            }
15440            return false;
15441        }
15442    }
15443
15444    public int getLaunchedFromUid(IBinder activityToken) {
15445        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15446        if (srec == null) {
15447            return -1;
15448        }
15449        return srec.launchedFromUid;
15450    }
15451
15452    public String getLaunchedFromPackage(IBinder activityToken) {
15453        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15454        if (srec == null) {
15455            return null;
15456        }
15457        return srec.launchedFromPackage;
15458    }
15459
15460    // =========================================================
15461    // LIFETIME MANAGEMENT
15462    // =========================================================
15463
15464    // Returns which broadcast queue the app is the current [or imminent] receiver
15465    // on, or 'null' if the app is not an active broadcast recipient.
15466    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15467        BroadcastRecord r = app.curReceiver;
15468        if (r != null) {
15469            return r.queue;
15470        }
15471
15472        // It's not the current receiver, but it might be starting up to become one
15473        synchronized (this) {
15474            for (BroadcastQueue queue : mBroadcastQueues) {
15475                r = queue.mPendingBroadcast;
15476                if (r != null && r.curApp == app) {
15477                    // found it; report which queue it's in
15478                    return queue;
15479                }
15480            }
15481        }
15482
15483        return null;
15484    }
15485
15486    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15487            boolean doingAll, long now) {
15488        if (mAdjSeq == app.adjSeq) {
15489            // This adjustment has already been computed.
15490            return app.curRawAdj;
15491        }
15492
15493        if (app.thread == null) {
15494            app.adjSeq = mAdjSeq;
15495            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15496            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15497            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15498        }
15499
15500        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15501        app.adjSource = null;
15502        app.adjTarget = null;
15503        app.empty = false;
15504        app.cached = false;
15505
15506        final int activitiesSize = app.activities.size();
15507
15508        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15509            // The max adjustment doesn't allow this app to be anything
15510            // below foreground, so it is not worth doing work for it.
15511            app.adjType = "fixed";
15512            app.adjSeq = mAdjSeq;
15513            app.curRawAdj = app.maxAdj;
15514            app.foregroundActivities = false;
15515            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15516            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15517            // System processes can do UI, and when they do we want to have
15518            // them trim their memory after the user leaves the UI.  To
15519            // facilitate this, here we need to determine whether or not it
15520            // is currently showing UI.
15521            app.systemNoUi = true;
15522            if (app == TOP_APP) {
15523                app.systemNoUi = false;
15524            } else if (activitiesSize > 0) {
15525                for (int j = 0; j < activitiesSize; j++) {
15526                    final ActivityRecord r = app.activities.get(j);
15527                    if (r.visible) {
15528                        app.systemNoUi = false;
15529                    }
15530                }
15531            }
15532            if (!app.systemNoUi) {
15533                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15534            }
15535            return (app.curAdj=app.maxAdj);
15536        }
15537
15538        app.systemNoUi = false;
15539
15540        // Determine the importance of the process, starting with most
15541        // important to least, and assign an appropriate OOM adjustment.
15542        int adj;
15543        int schedGroup;
15544        int procState;
15545        boolean foregroundActivities = false;
15546        BroadcastQueue queue;
15547        if (app == TOP_APP) {
15548            // The last app on the list is the foreground app.
15549            adj = ProcessList.FOREGROUND_APP_ADJ;
15550            schedGroup = Process.THREAD_GROUP_DEFAULT;
15551            app.adjType = "top-activity";
15552            foregroundActivities = true;
15553            procState = ActivityManager.PROCESS_STATE_TOP;
15554        } else if (app.instrumentationClass != null) {
15555            // Don't want to kill running instrumentation.
15556            adj = ProcessList.FOREGROUND_APP_ADJ;
15557            schedGroup = Process.THREAD_GROUP_DEFAULT;
15558            app.adjType = "instrumentation";
15559            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15560        } else if ((queue = isReceivingBroadcast(app)) != null) {
15561            // An app that is currently receiving a broadcast also
15562            // counts as being in the foreground for OOM killer purposes.
15563            // It's placed in a sched group based on the nature of the
15564            // broadcast as reflected by which queue it's active in.
15565            adj = ProcessList.FOREGROUND_APP_ADJ;
15566            schedGroup = (queue == mFgBroadcastQueue)
15567                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15568            app.adjType = "broadcast";
15569            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15570        } else if (app.executingServices.size() > 0) {
15571            // An app that is currently executing a service callback also
15572            // counts as being in the foreground.
15573            adj = ProcessList.FOREGROUND_APP_ADJ;
15574            schedGroup = app.execServicesFg ?
15575                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15576            app.adjType = "exec-service";
15577            procState = ActivityManager.PROCESS_STATE_SERVICE;
15578            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15579        } else {
15580            // As far as we know the process is empty.  We may change our mind later.
15581            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15582            // At this point we don't actually know the adjustment.  Use the cached adj
15583            // value that the caller wants us to.
15584            adj = cachedAdj;
15585            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15586            app.cached = true;
15587            app.empty = true;
15588            app.adjType = "cch-empty";
15589        }
15590
15591        // Examine all activities if not already foreground.
15592        if (!foregroundActivities && activitiesSize > 0) {
15593            for (int j = 0; j < activitiesSize; j++) {
15594                final ActivityRecord r = app.activities.get(j);
15595                if (r.app != app) {
15596                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15597                            + app + "?!?");
15598                    continue;
15599                }
15600                if (r.visible) {
15601                    // App has a visible activity; only upgrade adjustment.
15602                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15603                        adj = ProcessList.VISIBLE_APP_ADJ;
15604                        app.adjType = "visible";
15605                    }
15606                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15607                        procState = ActivityManager.PROCESS_STATE_TOP;
15608                    }
15609                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15610                    app.cached = false;
15611                    app.empty = false;
15612                    foregroundActivities = true;
15613                    break;
15614                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15615                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15616                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15617                        app.adjType = "pausing";
15618                    }
15619                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15620                        procState = ActivityManager.PROCESS_STATE_TOP;
15621                    }
15622                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15623                    app.cached = false;
15624                    app.empty = false;
15625                    foregroundActivities = true;
15626                } else if (r.state == ActivityState.STOPPING) {
15627                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15628                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15629                        app.adjType = "stopping";
15630                    }
15631                    // For the process state, we will at this point consider the
15632                    // process to be cached.  It will be cached either as an activity
15633                    // or empty depending on whether the activity is finishing.  We do
15634                    // this so that we can treat the process as cached for purposes of
15635                    // memory trimming (determing current memory level, trim command to
15636                    // send to process) since there can be an arbitrary number of stopping
15637                    // processes and they should soon all go into the cached state.
15638                    if (!r.finishing) {
15639                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15640                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15641                        }
15642                    }
15643                    app.cached = false;
15644                    app.empty = false;
15645                    foregroundActivities = true;
15646                } else {
15647                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15648                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15649                        app.adjType = "cch-act";
15650                    }
15651                }
15652            }
15653        }
15654
15655        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15656            if (app.foregroundServices) {
15657                // The user is aware of this app, so make it visible.
15658                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15659                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15660                app.cached = false;
15661                app.adjType = "fg-service";
15662                schedGroup = Process.THREAD_GROUP_DEFAULT;
15663            } else if (app.forcingToForeground != null) {
15664                // The user is aware of this app, so make it visible.
15665                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15666                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15667                app.cached = false;
15668                app.adjType = "force-fg";
15669                app.adjSource = app.forcingToForeground;
15670                schedGroup = Process.THREAD_GROUP_DEFAULT;
15671            }
15672        }
15673
15674        if (app == mHeavyWeightProcess) {
15675            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15676                // We don't want to kill the current heavy-weight process.
15677                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15678                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15679                app.cached = false;
15680                app.adjType = "heavy";
15681            }
15682            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15683                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15684            }
15685        }
15686
15687        if (app == mHomeProcess) {
15688            if (adj > ProcessList.HOME_APP_ADJ) {
15689                // This process is hosting what we currently consider to be the
15690                // home app, so we don't want to let it go into the background.
15691                adj = ProcessList.HOME_APP_ADJ;
15692                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15693                app.cached = false;
15694                app.adjType = "home";
15695            }
15696            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15697                procState = ActivityManager.PROCESS_STATE_HOME;
15698            }
15699        }
15700
15701        if (app == mPreviousProcess && app.activities.size() > 0) {
15702            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15703                // This was the previous process that showed UI to the user.
15704                // We want to try to keep it around more aggressively, to give
15705                // a good experience around switching between two apps.
15706                adj = ProcessList.PREVIOUS_APP_ADJ;
15707                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15708                app.cached = false;
15709                app.adjType = "previous";
15710            }
15711            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15712                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15713            }
15714        }
15715
15716        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15717                + " reason=" + app.adjType);
15718
15719        // By default, we use the computed adjustment.  It may be changed if
15720        // there are applications dependent on our services or providers, but
15721        // this gives us a baseline and makes sure we don't get into an
15722        // infinite recursion.
15723        app.adjSeq = mAdjSeq;
15724        app.curRawAdj = adj;
15725        app.hasStartedServices = false;
15726
15727        if (mBackupTarget != null && app == mBackupTarget.app) {
15728            // If possible we want to avoid killing apps while they're being backed up
15729            if (adj > ProcessList.BACKUP_APP_ADJ) {
15730                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15731                adj = ProcessList.BACKUP_APP_ADJ;
15732                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15733                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15734                }
15735                app.adjType = "backup";
15736                app.cached = false;
15737            }
15738            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15739                procState = ActivityManager.PROCESS_STATE_BACKUP;
15740            }
15741        }
15742
15743        boolean mayBeTop = false;
15744
15745        for (int is = app.services.size()-1;
15746                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15747                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15748                        || procState > ActivityManager.PROCESS_STATE_TOP);
15749                is--) {
15750            ServiceRecord s = app.services.valueAt(is);
15751            if (s.startRequested) {
15752                app.hasStartedServices = true;
15753                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15754                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15755                }
15756                if (app.hasShownUi && app != mHomeProcess) {
15757                    // If this process has shown some UI, let it immediately
15758                    // go to the LRU list because it may be pretty heavy with
15759                    // UI stuff.  We'll tag it with a label just to help
15760                    // debug and understand what is going on.
15761                    if (adj > ProcessList.SERVICE_ADJ) {
15762                        app.adjType = "cch-started-ui-services";
15763                    }
15764                } else {
15765                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15766                        // This service has seen some activity within
15767                        // recent memory, so we will keep its process ahead
15768                        // of the background processes.
15769                        if (adj > ProcessList.SERVICE_ADJ) {
15770                            adj = ProcessList.SERVICE_ADJ;
15771                            app.adjType = "started-services";
15772                            app.cached = false;
15773                        }
15774                    }
15775                    // If we have let the service slide into the background
15776                    // state, still have some text describing what it is doing
15777                    // even though the service no longer has an impact.
15778                    if (adj > ProcessList.SERVICE_ADJ) {
15779                        app.adjType = "cch-started-services";
15780                    }
15781                }
15782            }
15783            for (int conni = s.connections.size()-1;
15784                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15785                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15786                            || procState > ActivityManager.PROCESS_STATE_TOP);
15787                    conni--) {
15788                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15789                for (int i = 0;
15790                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15791                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15792                                || procState > ActivityManager.PROCESS_STATE_TOP);
15793                        i++) {
15794                    // XXX should compute this based on the max of
15795                    // all connected clients.
15796                    ConnectionRecord cr = clist.get(i);
15797                    if (cr.binding.client == app) {
15798                        // Binding to ourself is not interesting.
15799                        continue;
15800                    }
15801                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15802                        ProcessRecord client = cr.binding.client;
15803                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15804                                TOP_APP, doingAll, now);
15805                        int clientProcState = client.curProcState;
15806                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15807                            // If the other app is cached for any reason, for purposes here
15808                            // we are going to consider it empty.  The specific cached state
15809                            // doesn't propagate except under certain conditions.
15810                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15811                        }
15812                        String adjType = null;
15813                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15814                            // Not doing bind OOM management, so treat
15815                            // this guy more like a started service.
15816                            if (app.hasShownUi && app != mHomeProcess) {
15817                                // If this process has shown some UI, let it immediately
15818                                // go to the LRU list because it may be pretty heavy with
15819                                // UI stuff.  We'll tag it with a label just to help
15820                                // debug and understand what is going on.
15821                                if (adj > clientAdj) {
15822                                    adjType = "cch-bound-ui-services";
15823                                }
15824                                app.cached = false;
15825                                clientAdj = adj;
15826                                clientProcState = procState;
15827                            } else {
15828                                if (now >= (s.lastActivity
15829                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15830                                    // This service has not seen activity within
15831                                    // recent memory, so allow it to drop to the
15832                                    // LRU list if there is no other reason to keep
15833                                    // it around.  We'll also tag it with a label just
15834                                    // to help debug and undertand what is going on.
15835                                    if (adj > clientAdj) {
15836                                        adjType = "cch-bound-services";
15837                                    }
15838                                    clientAdj = adj;
15839                                }
15840                            }
15841                        }
15842                        if (adj > clientAdj) {
15843                            // If this process has recently shown UI, and
15844                            // the process that is binding to it is less
15845                            // important than being visible, then we don't
15846                            // care about the binding as much as we care
15847                            // about letting this process get into the LRU
15848                            // list to be killed and restarted if needed for
15849                            // memory.
15850                            if (app.hasShownUi && app != mHomeProcess
15851                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15852                                adjType = "cch-bound-ui-services";
15853                            } else {
15854                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15855                                        |Context.BIND_IMPORTANT)) != 0) {
15856                                    adj = clientAdj;
15857                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15858                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15859                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15860                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15861                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15862                                    adj = clientAdj;
15863                                } else {
15864                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15865                                        adj = ProcessList.VISIBLE_APP_ADJ;
15866                                    }
15867                                }
15868                                if (!client.cached) {
15869                                    app.cached = false;
15870                                }
15871                                adjType = "service";
15872                            }
15873                        }
15874                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15875                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15876                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15877                            }
15878                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15879                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15880                                    // Special handling of clients who are in the top state.
15881                                    // We *may* want to consider this process to be in the
15882                                    // top state as well, but only if there is not another
15883                                    // reason for it to be running.  Being on the top is a
15884                                    // special state, meaning you are specifically running
15885                                    // for the current top app.  If the process is already
15886                                    // running in the background for some other reason, it
15887                                    // is more important to continue considering it to be
15888                                    // in the background state.
15889                                    mayBeTop = true;
15890                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15891                                } else {
15892                                    // Special handling for above-top states (persistent
15893                                    // processes).  These should not bring the current process
15894                                    // into the top state, since they are not on top.  Instead
15895                                    // give them the best state after that.
15896                                    clientProcState =
15897                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15898                                }
15899                            }
15900                        } else {
15901                            if (clientProcState <
15902                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15903                                clientProcState =
15904                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15905                            }
15906                        }
15907                        if (procState > clientProcState) {
15908                            procState = clientProcState;
15909                        }
15910                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15911                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15912                            app.pendingUiClean = true;
15913                        }
15914                        if (adjType != null) {
15915                            app.adjType = adjType;
15916                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15917                                    .REASON_SERVICE_IN_USE;
15918                            app.adjSource = cr.binding.client;
15919                            app.adjSourceProcState = clientProcState;
15920                            app.adjTarget = s.name;
15921                        }
15922                    }
15923                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15924                        app.treatLikeActivity = true;
15925                    }
15926                    final ActivityRecord a = cr.activity;
15927                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15928                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15929                                (a.visible || a.state == ActivityState.RESUMED
15930                                 || a.state == ActivityState.PAUSING)) {
15931                            adj = ProcessList.FOREGROUND_APP_ADJ;
15932                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15933                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15934                            }
15935                            app.cached = false;
15936                            app.adjType = "service";
15937                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15938                                    .REASON_SERVICE_IN_USE;
15939                            app.adjSource = a;
15940                            app.adjSourceProcState = procState;
15941                            app.adjTarget = s.name;
15942                        }
15943                    }
15944                }
15945            }
15946        }
15947
15948        for (int provi = app.pubProviders.size()-1;
15949                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15950                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15951                        || procState > ActivityManager.PROCESS_STATE_TOP);
15952                provi--) {
15953            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15954            for (int i = cpr.connections.size()-1;
15955                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15956                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15957                            || procState > ActivityManager.PROCESS_STATE_TOP);
15958                    i--) {
15959                ContentProviderConnection conn = cpr.connections.get(i);
15960                ProcessRecord client = conn.client;
15961                if (client == app) {
15962                    // Being our own client is not interesting.
15963                    continue;
15964                }
15965                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15966                int clientProcState = client.curProcState;
15967                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15968                    // If the other app is cached for any reason, for purposes here
15969                    // we are going to consider it empty.
15970                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15971                }
15972                if (adj > clientAdj) {
15973                    if (app.hasShownUi && app != mHomeProcess
15974                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15975                        app.adjType = "cch-ui-provider";
15976                    } else {
15977                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15978                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15979                        app.adjType = "provider";
15980                    }
15981                    app.cached &= client.cached;
15982                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15983                            .REASON_PROVIDER_IN_USE;
15984                    app.adjSource = client;
15985                    app.adjSourceProcState = clientProcState;
15986                    app.adjTarget = cpr.name;
15987                }
15988                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15989                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15990                        // Special handling of clients who are in the top state.
15991                        // We *may* want to consider this process to be in the
15992                        // top state as well, but only if there is not another
15993                        // reason for it to be running.  Being on the top is a
15994                        // special state, meaning you are specifically running
15995                        // for the current top app.  If the process is already
15996                        // running in the background for some other reason, it
15997                        // is more important to continue considering it to be
15998                        // in the background state.
15999                        mayBeTop = true;
16000                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16001                    } else {
16002                        // Special handling for above-top states (persistent
16003                        // processes).  These should not bring the current process
16004                        // into the top state, since they are not on top.  Instead
16005                        // give them the best state after that.
16006                        clientProcState =
16007                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16008                    }
16009                }
16010                if (procState > clientProcState) {
16011                    procState = clientProcState;
16012                }
16013                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16014                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16015                }
16016            }
16017            // If the provider has external (non-framework) process
16018            // dependencies, ensure that its adjustment is at least
16019            // FOREGROUND_APP_ADJ.
16020            if (cpr.hasExternalProcessHandles()) {
16021                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16022                    adj = ProcessList.FOREGROUND_APP_ADJ;
16023                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16024                    app.cached = false;
16025                    app.adjType = "provider";
16026                    app.adjTarget = cpr.name;
16027                }
16028                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16029                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16030                }
16031            }
16032        }
16033
16034        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16035            // A client of one of our services or providers is in the top state.  We
16036            // *may* want to be in the top state, but not if we are already running in
16037            // the background for some other reason.  For the decision here, we are going
16038            // to pick out a few specific states that we want to remain in when a client
16039            // is top (states that tend to be longer-term) and otherwise allow it to go
16040            // to the top state.
16041            switch (procState) {
16042                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16043                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16044                case ActivityManager.PROCESS_STATE_SERVICE:
16045                    // These all are longer-term states, so pull them up to the top
16046                    // of the background states, but not all the way to the top state.
16047                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16048                    break;
16049                default:
16050                    // Otherwise, top is a better choice, so take it.
16051                    procState = ActivityManager.PROCESS_STATE_TOP;
16052                    break;
16053            }
16054        }
16055
16056        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16057            if (app.hasClientActivities) {
16058                // This is a cached process, but with client activities.  Mark it so.
16059                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16060                app.adjType = "cch-client-act";
16061            } else if (app.treatLikeActivity) {
16062                // This is a cached process, but somebody wants us to treat it like it has
16063                // an activity, okay!
16064                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16065                app.adjType = "cch-as-act";
16066            }
16067        }
16068
16069        if (adj == ProcessList.SERVICE_ADJ) {
16070            if (doingAll) {
16071                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16072                mNewNumServiceProcs++;
16073                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16074                if (!app.serviceb) {
16075                    // This service isn't far enough down on the LRU list to
16076                    // normally be a B service, but if we are low on RAM and it
16077                    // is large we want to force it down since we would prefer to
16078                    // keep launcher over it.
16079                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16080                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16081                        app.serviceHighRam = true;
16082                        app.serviceb = true;
16083                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16084                    } else {
16085                        mNewNumAServiceProcs++;
16086                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16087                    }
16088                } else {
16089                    app.serviceHighRam = false;
16090                }
16091            }
16092            if (app.serviceb) {
16093                adj = ProcessList.SERVICE_B_ADJ;
16094            }
16095        }
16096
16097        app.curRawAdj = adj;
16098
16099        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16100        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16101        if (adj > app.maxAdj) {
16102            adj = app.maxAdj;
16103            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16104                schedGroup = Process.THREAD_GROUP_DEFAULT;
16105            }
16106        }
16107
16108        // Do final modification to adj.  Everything we do between here and applying
16109        // the final setAdj must be done in this function, because we will also use
16110        // it when computing the final cached adj later.  Note that we don't need to
16111        // worry about this for max adj above, since max adj will always be used to
16112        // keep it out of the cached vaues.
16113        app.curAdj = app.modifyRawOomAdj(adj);
16114        app.curSchedGroup = schedGroup;
16115        app.curProcState = procState;
16116        app.foregroundActivities = foregroundActivities;
16117
16118        return app.curRawAdj;
16119    }
16120
16121    /**
16122     * Schedule PSS collection of a process.
16123     */
16124    void requestPssLocked(ProcessRecord proc, int procState) {
16125        if (mPendingPssProcesses.contains(proc)) {
16126            return;
16127        }
16128        if (mPendingPssProcesses.size() == 0) {
16129            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16130        }
16131        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16132        proc.pssProcState = procState;
16133        mPendingPssProcesses.add(proc);
16134    }
16135
16136    /**
16137     * Schedule PSS collection of all processes.
16138     */
16139    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16140        if (!always) {
16141            if (now < (mLastFullPssTime +
16142                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16143                return;
16144            }
16145        }
16146        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16147        mLastFullPssTime = now;
16148        mFullPssPending = true;
16149        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16150        mPendingPssProcesses.clear();
16151        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16152            ProcessRecord app = mLruProcesses.get(i);
16153            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16154                app.pssProcState = app.setProcState;
16155                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16156                        isSleeping(), now);
16157                mPendingPssProcesses.add(app);
16158            }
16159        }
16160        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16161    }
16162
16163    /**
16164     * Ask a given process to GC right now.
16165     */
16166    final void performAppGcLocked(ProcessRecord app) {
16167        try {
16168            app.lastRequestedGc = SystemClock.uptimeMillis();
16169            if (app.thread != null) {
16170                if (app.reportLowMemory) {
16171                    app.reportLowMemory = false;
16172                    app.thread.scheduleLowMemory();
16173                } else {
16174                    app.thread.processInBackground();
16175                }
16176            }
16177        } catch (Exception e) {
16178            // whatever.
16179        }
16180    }
16181
16182    /**
16183     * Returns true if things are idle enough to perform GCs.
16184     */
16185    private final boolean canGcNowLocked() {
16186        boolean processingBroadcasts = false;
16187        for (BroadcastQueue q : mBroadcastQueues) {
16188            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16189                processingBroadcasts = true;
16190            }
16191        }
16192        return !processingBroadcasts
16193                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16194    }
16195
16196    /**
16197     * Perform GCs on all processes that are waiting for it, but only
16198     * if things are idle.
16199     */
16200    final void performAppGcsLocked() {
16201        final int N = mProcessesToGc.size();
16202        if (N <= 0) {
16203            return;
16204        }
16205        if (canGcNowLocked()) {
16206            while (mProcessesToGc.size() > 0) {
16207                ProcessRecord proc = mProcessesToGc.remove(0);
16208                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16209                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16210                            <= SystemClock.uptimeMillis()) {
16211                        // To avoid spamming the system, we will GC processes one
16212                        // at a time, waiting a few seconds between each.
16213                        performAppGcLocked(proc);
16214                        scheduleAppGcsLocked();
16215                        return;
16216                    } else {
16217                        // It hasn't been long enough since we last GCed this
16218                        // process...  put it in the list to wait for its time.
16219                        addProcessToGcListLocked(proc);
16220                        break;
16221                    }
16222                }
16223            }
16224
16225            scheduleAppGcsLocked();
16226        }
16227    }
16228
16229    /**
16230     * If all looks good, perform GCs on all processes waiting for them.
16231     */
16232    final void performAppGcsIfAppropriateLocked() {
16233        if (canGcNowLocked()) {
16234            performAppGcsLocked();
16235            return;
16236        }
16237        // Still not idle, wait some more.
16238        scheduleAppGcsLocked();
16239    }
16240
16241    /**
16242     * Schedule the execution of all pending app GCs.
16243     */
16244    final void scheduleAppGcsLocked() {
16245        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16246
16247        if (mProcessesToGc.size() > 0) {
16248            // Schedule a GC for the time to the next process.
16249            ProcessRecord proc = mProcessesToGc.get(0);
16250            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16251
16252            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16253            long now = SystemClock.uptimeMillis();
16254            if (when < (now+GC_TIMEOUT)) {
16255                when = now + GC_TIMEOUT;
16256            }
16257            mHandler.sendMessageAtTime(msg, when);
16258        }
16259    }
16260
16261    /**
16262     * Add a process to the array of processes waiting to be GCed.  Keeps the
16263     * list in sorted order by the last GC time.  The process can't already be
16264     * on the list.
16265     */
16266    final void addProcessToGcListLocked(ProcessRecord proc) {
16267        boolean added = false;
16268        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16269            if (mProcessesToGc.get(i).lastRequestedGc <
16270                    proc.lastRequestedGc) {
16271                added = true;
16272                mProcessesToGc.add(i+1, proc);
16273                break;
16274            }
16275        }
16276        if (!added) {
16277            mProcessesToGc.add(0, proc);
16278        }
16279    }
16280
16281    /**
16282     * Set up to ask a process to GC itself.  This will either do it
16283     * immediately, or put it on the list of processes to gc the next
16284     * time things are idle.
16285     */
16286    final void scheduleAppGcLocked(ProcessRecord app) {
16287        long now = SystemClock.uptimeMillis();
16288        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16289            return;
16290        }
16291        if (!mProcessesToGc.contains(app)) {
16292            addProcessToGcListLocked(app);
16293            scheduleAppGcsLocked();
16294        }
16295    }
16296
16297    final void checkExcessivePowerUsageLocked(boolean doKills) {
16298        updateCpuStatsNow();
16299
16300        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16301        boolean doWakeKills = doKills;
16302        boolean doCpuKills = doKills;
16303        if (mLastPowerCheckRealtime == 0) {
16304            doWakeKills = false;
16305        }
16306        if (mLastPowerCheckUptime == 0) {
16307            doCpuKills = false;
16308        }
16309        if (stats.isScreenOn()) {
16310            doWakeKills = false;
16311        }
16312        final long curRealtime = SystemClock.elapsedRealtime();
16313        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16314        final long curUptime = SystemClock.uptimeMillis();
16315        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16316        mLastPowerCheckRealtime = curRealtime;
16317        mLastPowerCheckUptime = curUptime;
16318        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16319            doWakeKills = false;
16320        }
16321        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16322            doCpuKills = false;
16323        }
16324        int i = mLruProcesses.size();
16325        while (i > 0) {
16326            i--;
16327            ProcessRecord app = mLruProcesses.get(i);
16328            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16329                long wtime;
16330                synchronized (stats) {
16331                    wtime = stats.getProcessWakeTime(app.info.uid,
16332                            app.pid, curRealtime);
16333                }
16334                long wtimeUsed = wtime - app.lastWakeTime;
16335                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16336                if (DEBUG_POWER) {
16337                    StringBuilder sb = new StringBuilder(128);
16338                    sb.append("Wake for ");
16339                    app.toShortString(sb);
16340                    sb.append(": over ");
16341                    TimeUtils.formatDuration(realtimeSince, sb);
16342                    sb.append(" used ");
16343                    TimeUtils.formatDuration(wtimeUsed, sb);
16344                    sb.append(" (");
16345                    sb.append((wtimeUsed*100)/realtimeSince);
16346                    sb.append("%)");
16347                    Slog.i(TAG, sb.toString());
16348                    sb.setLength(0);
16349                    sb.append("CPU for ");
16350                    app.toShortString(sb);
16351                    sb.append(": over ");
16352                    TimeUtils.formatDuration(uptimeSince, sb);
16353                    sb.append(" used ");
16354                    TimeUtils.formatDuration(cputimeUsed, sb);
16355                    sb.append(" (");
16356                    sb.append((cputimeUsed*100)/uptimeSince);
16357                    sb.append("%)");
16358                    Slog.i(TAG, sb.toString());
16359                }
16360                // If a process has held a wake lock for more
16361                // than 50% of the time during this period,
16362                // that sounds bad.  Kill!
16363                if (doWakeKills && realtimeSince > 0
16364                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16365                    synchronized (stats) {
16366                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16367                                realtimeSince, wtimeUsed);
16368                    }
16369                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16370                            + " during " + realtimeSince);
16371                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16372                } else if (doCpuKills && uptimeSince > 0
16373                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16374                    synchronized (stats) {
16375                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16376                                uptimeSince, cputimeUsed);
16377                    }
16378                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16379                            + " during " + uptimeSince);
16380                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16381                } else {
16382                    app.lastWakeTime = wtime;
16383                    app.lastCpuTime = app.curCpuTime;
16384                }
16385            }
16386        }
16387    }
16388
16389    private final boolean applyOomAdjLocked(ProcessRecord app,
16390            ProcessRecord TOP_APP, boolean doingAll, long now) {
16391        boolean success = true;
16392
16393        if (app.curRawAdj != app.setRawAdj) {
16394            app.setRawAdj = app.curRawAdj;
16395        }
16396
16397        int changes = 0;
16398
16399        if (app.curAdj != app.setAdj) {
16400            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16401            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16402                TAG, "Set " + app.pid + " " + app.processName +
16403                " adj " + app.curAdj + ": " + app.adjType);
16404            app.setAdj = app.curAdj;
16405        }
16406
16407        if (app.setSchedGroup != app.curSchedGroup) {
16408            app.setSchedGroup = app.curSchedGroup;
16409            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16410                    "Setting process group of " + app.processName
16411                    + " to " + app.curSchedGroup);
16412            if (app.waitingToKill != null &&
16413                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16414                killUnneededProcessLocked(app, app.waitingToKill);
16415                success = false;
16416            } else {
16417                if (true) {
16418                    long oldId = Binder.clearCallingIdentity();
16419                    try {
16420                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16421                    } catch (Exception e) {
16422                        Slog.w(TAG, "Failed setting process group of " + app.pid
16423                                + " to " + app.curSchedGroup);
16424                        e.printStackTrace();
16425                    } finally {
16426                        Binder.restoreCallingIdentity(oldId);
16427                    }
16428                } else {
16429                    if (app.thread != null) {
16430                        try {
16431                            app.thread.setSchedulingGroup(app.curSchedGroup);
16432                        } catch (RemoteException e) {
16433                        }
16434                    }
16435                }
16436                Process.setSwappiness(app.pid,
16437                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16438            }
16439        }
16440        if (app.repForegroundActivities != app.foregroundActivities) {
16441            app.repForegroundActivities = app.foregroundActivities;
16442            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16443        }
16444        if (app.repProcState != app.curProcState) {
16445            app.repProcState = app.curProcState;
16446            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16447            if (app.thread != null) {
16448                try {
16449                    if (false) {
16450                        //RuntimeException h = new RuntimeException("here");
16451                        Slog.i(TAG, "Sending new process state " + app.repProcState
16452                                + " to " + app /*, h*/);
16453                    }
16454                    app.thread.setProcessState(app.repProcState);
16455                } catch (RemoteException e) {
16456                }
16457            }
16458        }
16459        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16460                app.setProcState)) {
16461            app.lastStateTime = now;
16462            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16463                    isSleeping(), now);
16464            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16465                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16466                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16467                    + (app.nextPssTime-now) + ": " + app);
16468        } else {
16469            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16470                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16471                requestPssLocked(app, app.setProcState);
16472                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16473                        isSleeping(), now);
16474            } else if (false && DEBUG_PSS) {
16475                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16476            }
16477        }
16478        if (app.setProcState != app.curProcState) {
16479            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16480                    "Proc state change of " + app.processName
16481                    + " to " + app.curProcState);
16482            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16483            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16484            if (setImportant && !curImportant) {
16485                // This app is no longer something we consider important enough to allow to
16486                // use arbitrary amounts of battery power.  Note
16487                // its current wake lock time to later know to kill it if
16488                // it is not behaving well.
16489                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16490                synchronized (stats) {
16491                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16492                            app.pid, SystemClock.elapsedRealtime());
16493                }
16494                app.lastCpuTime = app.curCpuTime;
16495
16496            }
16497            app.setProcState = app.curProcState;
16498            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16499                app.notCachedSinceIdle = false;
16500            }
16501            if (!doingAll) {
16502                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16503            } else {
16504                app.procStateChanged = true;
16505            }
16506        }
16507
16508        if (changes != 0) {
16509            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16510            int i = mPendingProcessChanges.size()-1;
16511            ProcessChangeItem item = null;
16512            while (i >= 0) {
16513                item = mPendingProcessChanges.get(i);
16514                if (item.pid == app.pid) {
16515                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16516                    break;
16517                }
16518                i--;
16519            }
16520            if (i < 0) {
16521                // No existing item in pending changes; need a new one.
16522                final int NA = mAvailProcessChanges.size();
16523                if (NA > 0) {
16524                    item = mAvailProcessChanges.remove(NA-1);
16525                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16526                } else {
16527                    item = new ProcessChangeItem();
16528                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16529                }
16530                item.changes = 0;
16531                item.pid = app.pid;
16532                item.uid = app.info.uid;
16533                if (mPendingProcessChanges.size() == 0) {
16534                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16535                            "*** Enqueueing dispatch processes changed!");
16536                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16537                }
16538                mPendingProcessChanges.add(item);
16539            }
16540            item.changes |= changes;
16541            item.processState = app.repProcState;
16542            item.foregroundActivities = app.repForegroundActivities;
16543            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16544                    + Integer.toHexString(System.identityHashCode(item))
16545                    + " " + app.toShortString() + ": changes=" + item.changes
16546                    + " procState=" + item.processState
16547                    + " foreground=" + item.foregroundActivities
16548                    + " type=" + app.adjType + " source=" + app.adjSource
16549                    + " target=" + app.adjTarget);
16550        }
16551
16552        return success;
16553    }
16554
16555    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16556        if (proc.thread != null) {
16557            if (proc.baseProcessTracker != null) {
16558                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16559            }
16560            if (proc.repProcState >= 0) {
16561                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16562                        proc.repProcState);
16563            }
16564        }
16565    }
16566
16567    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16568            ProcessRecord TOP_APP, boolean doingAll, long now) {
16569        if (app.thread == null) {
16570            return false;
16571        }
16572
16573        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16574
16575        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16576    }
16577
16578    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16579            boolean oomAdj) {
16580        if (isForeground != proc.foregroundServices) {
16581            proc.foregroundServices = isForeground;
16582            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16583                    proc.info.uid);
16584            if (isForeground) {
16585                if (curProcs == null) {
16586                    curProcs = new ArrayList<ProcessRecord>();
16587                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16588                }
16589                if (!curProcs.contains(proc)) {
16590                    curProcs.add(proc);
16591                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16592                            proc.info.packageName, proc.info.uid);
16593                }
16594            } else {
16595                if (curProcs != null) {
16596                    if (curProcs.remove(proc)) {
16597                        mBatteryStatsService.noteEvent(
16598                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16599                                proc.info.packageName, proc.info.uid);
16600                        if (curProcs.size() <= 0) {
16601                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16602                        }
16603                    }
16604                }
16605            }
16606            if (oomAdj) {
16607                updateOomAdjLocked();
16608            }
16609        }
16610    }
16611
16612    private final ActivityRecord resumedAppLocked() {
16613        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16614        String pkg;
16615        int uid;
16616        if (act != null) {
16617            pkg = act.packageName;
16618            uid = act.info.applicationInfo.uid;
16619        } else {
16620            pkg = null;
16621            uid = -1;
16622        }
16623        // Has the UID or resumed package name changed?
16624        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16625                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16626            if (mCurResumedPackage != null) {
16627                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16628                        mCurResumedPackage, mCurResumedUid);
16629            }
16630            mCurResumedPackage = pkg;
16631            mCurResumedUid = uid;
16632            if (mCurResumedPackage != null) {
16633                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16634                        mCurResumedPackage, mCurResumedUid);
16635            }
16636        }
16637        return act;
16638    }
16639
16640    final boolean updateOomAdjLocked(ProcessRecord app) {
16641        final ActivityRecord TOP_ACT = resumedAppLocked();
16642        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16643        final boolean wasCached = app.cached;
16644
16645        mAdjSeq++;
16646
16647        // This is the desired cached adjusment we want to tell it to use.
16648        // If our app is currently cached, we know it, and that is it.  Otherwise,
16649        // we don't know it yet, and it needs to now be cached we will then
16650        // need to do a complete oom adj.
16651        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16652                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16653        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16654                SystemClock.uptimeMillis());
16655        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16656            // Changed to/from cached state, so apps after it in the LRU
16657            // list may also be changed.
16658            updateOomAdjLocked();
16659        }
16660        return success;
16661    }
16662
16663    final void updateOomAdjLocked() {
16664        final ActivityRecord TOP_ACT = resumedAppLocked();
16665        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16666        final long now = SystemClock.uptimeMillis();
16667        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16668        final int N = mLruProcesses.size();
16669
16670        if (false) {
16671            RuntimeException e = new RuntimeException();
16672            e.fillInStackTrace();
16673            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16674        }
16675
16676        mAdjSeq++;
16677        mNewNumServiceProcs = 0;
16678        mNewNumAServiceProcs = 0;
16679
16680        final int emptyProcessLimit;
16681        final int cachedProcessLimit;
16682        if (mProcessLimit <= 0) {
16683            emptyProcessLimit = cachedProcessLimit = 0;
16684        } else if (mProcessLimit == 1) {
16685            emptyProcessLimit = 1;
16686            cachedProcessLimit = 0;
16687        } else {
16688            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16689            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16690        }
16691
16692        // Let's determine how many processes we have running vs.
16693        // how many slots we have for background processes; we may want
16694        // to put multiple processes in a slot of there are enough of
16695        // them.
16696        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16697                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16698        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16699        if (numEmptyProcs > cachedProcessLimit) {
16700            // If there are more empty processes than our limit on cached
16701            // processes, then use the cached process limit for the factor.
16702            // This ensures that the really old empty processes get pushed
16703            // down to the bottom, so if we are running low on memory we will
16704            // have a better chance at keeping around more cached processes
16705            // instead of a gazillion empty processes.
16706            numEmptyProcs = cachedProcessLimit;
16707        }
16708        int emptyFactor = numEmptyProcs/numSlots;
16709        if (emptyFactor < 1) emptyFactor = 1;
16710        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16711        if (cachedFactor < 1) cachedFactor = 1;
16712        int stepCached = 0;
16713        int stepEmpty = 0;
16714        int numCached = 0;
16715        int numEmpty = 0;
16716        int numTrimming = 0;
16717
16718        mNumNonCachedProcs = 0;
16719        mNumCachedHiddenProcs = 0;
16720
16721        // First update the OOM adjustment for each of the
16722        // application processes based on their current state.
16723        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16724        int nextCachedAdj = curCachedAdj+1;
16725        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16726        int nextEmptyAdj = curEmptyAdj+2;
16727        for (int i=N-1; i>=0; i--) {
16728            ProcessRecord app = mLruProcesses.get(i);
16729            if (!app.killedByAm && app.thread != null) {
16730                app.procStateChanged = false;
16731                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16732
16733                // If we haven't yet assigned the final cached adj
16734                // to the process, do that now.
16735                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16736                    switch (app.curProcState) {
16737                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16738                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16739                            // This process is a cached process holding activities...
16740                            // assign it the next cached value for that type, and then
16741                            // step that cached level.
16742                            app.curRawAdj = curCachedAdj;
16743                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16744                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16745                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16746                                    + ")");
16747                            if (curCachedAdj != nextCachedAdj) {
16748                                stepCached++;
16749                                if (stepCached >= cachedFactor) {
16750                                    stepCached = 0;
16751                                    curCachedAdj = nextCachedAdj;
16752                                    nextCachedAdj += 2;
16753                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16754                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16755                                    }
16756                                }
16757                            }
16758                            break;
16759                        default:
16760                            // For everything else, assign next empty cached process
16761                            // level and bump that up.  Note that this means that
16762                            // long-running services that have dropped down to the
16763                            // cached level will be treated as empty (since their process
16764                            // state is still as a service), which is what we want.
16765                            app.curRawAdj = curEmptyAdj;
16766                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16767                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16768                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16769                                    + ")");
16770                            if (curEmptyAdj != nextEmptyAdj) {
16771                                stepEmpty++;
16772                                if (stepEmpty >= emptyFactor) {
16773                                    stepEmpty = 0;
16774                                    curEmptyAdj = nextEmptyAdj;
16775                                    nextEmptyAdj += 2;
16776                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16777                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16778                                    }
16779                                }
16780                            }
16781                            break;
16782                    }
16783                }
16784
16785                applyOomAdjLocked(app, TOP_APP, true, now);
16786
16787                // Count the number of process types.
16788                switch (app.curProcState) {
16789                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16790                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16791                        mNumCachedHiddenProcs++;
16792                        numCached++;
16793                        if (numCached > cachedProcessLimit) {
16794                            killUnneededProcessLocked(app, "cached #" + numCached);
16795                        }
16796                        break;
16797                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16798                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16799                                && app.lastActivityTime < oldTime) {
16800                            killUnneededProcessLocked(app, "empty for "
16801                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16802                                    / 1000) + "s");
16803                        } else {
16804                            numEmpty++;
16805                            if (numEmpty > emptyProcessLimit) {
16806                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16807                            }
16808                        }
16809                        break;
16810                    default:
16811                        mNumNonCachedProcs++;
16812                        break;
16813                }
16814
16815                if (app.isolated && app.services.size() <= 0) {
16816                    // If this is an isolated process, and there are no
16817                    // services running in it, then the process is no longer
16818                    // needed.  We agressively kill these because we can by
16819                    // definition not re-use the same process again, and it is
16820                    // good to avoid having whatever code was running in them
16821                    // left sitting around after no longer needed.
16822                    killUnneededProcessLocked(app, "isolated not needed");
16823                }
16824
16825                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16826                        && !app.killedByAm) {
16827                    numTrimming++;
16828                }
16829            }
16830        }
16831
16832        mNumServiceProcs = mNewNumServiceProcs;
16833
16834        // Now determine the memory trimming level of background processes.
16835        // Unfortunately we need to start at the back of the list to do this
16836        // properly.  We only do this if the number of background apps we
16837        // are managing to keep around is less than half the maximum we desire;
16838        // if we are keeping a good number around, we'll let them use whatever
16839        // memory they want.
16840        final int numCachedAndEmpty = numCached + numEmpty;
16841        int memFactor;
16842        if (numCached <= ProcessList.TRIM_CACHED_APPS
16843                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16844            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16845                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16846            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16847                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16848            } else {
16849                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16850            }
16851        } else {
16852            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16853        }
16854        // We always allow the memory level to go up (better).  We only allow it to go
16855        // down if we are in a state where that is allowed, *and* the total number of processes
16856        // has gone down since last time.
16857        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16858                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16859                + " last=" + mLastNumProcesses);
16860        if (memFactor > mLastMemoryLevel) {
16861            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16862                memFactor = mLastMemoryLevel;
16863                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16864            }
16865        }
16866        mLastMemoryLevel = memFactor;
16867        mLastNumProcesses = mLruProcesses.size();
16868        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16869        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16870        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16871            if (mLowRamStartTime == 0) {
16872                mLowRamStartTime = now;
16873            }
16874            int step = 0;
16875            int fgTrimLevel;
16876            switch (memFactor) {
16877                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16878                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16879                    break;
16880                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16881                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16882                    break;
16883                default:
16884                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16885                    break;
16886            }
16887            int factor = numTrimming/3;
16888            int minFactor = 2;
16889            if (mHomeProcess != null) minFactor++;
16890            if (mPreviousProcess != null) minFactor++;
16891            if (factor < minFactor) factor = minFactor;
16892            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16893            for (int i=N-1; i>=0; i--) {
16894                ProcessRecord app = mLruProcesses.get(i);
16895                if (allChanged || app.procStateChanged) {
16896                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16897                    app.procStateChanged = false;
16898                }
16899                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16900                        && !app.killedByAm) {
16901                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16902                        try {
16903                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16904                                    "Trimming memory of " + app.processName
16905                                    + " to " + curLevel);
16906                            app.thread.scheduleTrimMemory(curLevel);
16907                        } catch (RemoteException e) {
16908                        }
16909                        if (false) {
16910                            // For now we won't do this; our memory trimming seems
16911                            // to be good enough at this point that destroying
16912                            // activities causes more harm than good.
16913                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16914                                    && app != mHomeProcess && app != mPreviousProcess) {
16915                                // Need to do this on its own message because the stack may not
16916                                // be in a consistent state at this point.
16917                                // For these apps we will also finish their activities
16918                                // to help them free memory.
16919                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16920                            }
16921                        }
16922                    }
16923                    app.trimMemoryLevel = curLevel;
16924                    step++;
16925                    if (step >= factor) {
16926                        step = 0;
16927                        switch (curLevel) {
16928                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16929                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16930                                break;
16931                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16932                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16933                                break;
16934                        }
16935                    }
16936                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16937                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16938                            && app.thread != null) {
16939                        try {
16940                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16941                                    "Trimming memory of heavy-weight " + app.processName
16942                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16943                            app.thread.scheduleTrimMemory(
16944                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16945                        } catch (RemoteException e) {
16946                        }
16947                    }
16948                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16949                } else {
16950                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16951                            || app.systemNoUi) && app.pendingUiClean) {
16952                        // If this application is now in the background and it
16953                        // had done UI, then give it the special trim level to
16954                        // have it free UI resources.
16955                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16956                        if (app.trimMemoryLevel < level && app.thread != null) {
16957                            try {
16958                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16959                                        "Trimming memory of bg-ui " + app.processName
16960                                        + " to " + level);
16961                                app.thread.scheduleTrimMemory(level);
16962                            } catch (RemoteException e) {
16963                            }
16964                        }
16965                        app.pendingUiClean = false;
16966                    }
16967                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16968                        try {
16969                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16970                                    "Trimming memory of fg " + app.processName
16971                                    + " to " + fgTrimLevel);
16972                            app.thread.scheduleTrimMemory(fgTrimLevel);
16973                        } catch (RemoteException e) {
16974                        }
16975                    }
16976                    app.trimMemoryLevel = fgTrimLevel;
16977                }
16978            }
16979        } else {
16980            if (mLowRamStartTime != 0) {
16981                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16982                mLowRamStartTime = 0;
16983            }
16984            for (int i=N-1; i>=0; i--) {
16985                ProcessRecord app = mLruProcesses.get(i);
16986                if (allChanged || app.procStateChanged) {
16987                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16988                    app.procStateChanged = false;
16989                }
16990                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16991                        || app.systemNoUi) && app.pendingUiClean) {
16992                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16993                            && app.thread != null) {
16994                        try {
16995                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16996                                    "Trimming memory of ui hidden " + app.processName
16997                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16998                            app.thread.scheduleTrimMemory(
16999                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17000                        } catch (RemoteException e) {
17001                        }
17002                    }
17003                    app.pendingUiClean = false;
17004                }
17005                app.trimMemoryLevel = 0;
17006            }
17007        }
17008
17009        if (mAlwaysFinishActivities) {
17010            // Need to do this on its own message because the stack may not
17011            // be in a consistent state at this point.
17012            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17013        }
17014
17015        if (allChanged) {
17016            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17017        }
17018
17019        if (mProcessStats.shouldWriteNowLocked(now)) {
17020            mHandler.post(new Runnable() {
17021                @Override public void run() {
17022                    synchronized (ActivityManagerService.this) {
17023                        mProcessStats.writeStateAsyncLocked();
17024                    }
17025                }
17026            });
17027        }
17028
17029        if (DEBUG_OOM_ADJ) {
17030            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17031        }
17032    }
17033
17034    final void trimApplications() {
17035        synchronized (this) {
17036            int i;
17037
17038            // First remove any unused application processes whose package
17039            // has been removed.
17040            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17041                final ProcessRecord app = mRemovedProcesses.get(i);
17042                if (app.activities.size() == 0
17043                        && app.curReceiver == null && app.services.size() == 0) {
17044                    Slog.i(
17045                        TAG, "Exiting empty application process "
17046                        + app.processName + " ("
17047                        + (app.thread != null ? app.thread.asBinder() : null)
17048                        + ")\n");
17049                    if (app.pid > 0 && app.pid != MY_PID) {
17050                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
17051                                app.processName, app.setAdj, "empty");
17052                        app.killedByAm = true;
17053                        Process.killProcessQuiet(app.pid);
17054                        Process.killProcessGroup(app.info.uid, app.pid);
17055                    } else {
17056                        try {
17057                            app.thread.scheduleExit();
17058                        } catch (Exception e) {
17059                            // Ignore exceptions.
17060                        }
17061                    }
17062                    cleanUpApplicationRecordLocked(app, false, true, -1);
17063                    mRemovedProcesses.remove(i);
17064
17065                    if (app.persistent) {
17066                        addAppLocked(app.info, false, null /* ABI override */);
17067                    }
17068                }
17069            }
17070
17071            // Now update the oom adj for all processes.
17072            updateOomAdjLocked();
17073        }
17074    }
17075
17076    /** This method sends the specified signal to each of the persistent apps */
17077    public void signalPersistentProcesses(int sig) throws RemoteException {
17078        if (sig != Process.SIGNAL_USR1) {
17079            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17080        }
17081
17082        synchronized (this) {
17083            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17084                    != PackageManager.PERMISSION_GRANTED) {
17085                throw new SecurityException("Requires permission "
17086                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17087            }
17088
17089            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17090                ProcessRecord r = mLruProcesses.get(i);
17091                if (r.thread != null && r.persistent) {
17092                    Process.sendSignal(r.pid, sig);
17093                }
17094            }
17095        }
17096    }
17097
17098    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
17099        if (proc == null || proc == mProfileProc) {
17100            proc = mProfileProc;
17101            path = mProfileFile;
17102            profileType = mProfileType;
17103            clearProfilerLocked();
17104        }
17105        if (proc == null) {
17106            return;
17107        }
17108        try {
17109            proc.thread.profilerControl(false, path, null, profileType);
17110        } catch (RemoteException e) {
17111            throw new IllegalStateException("Process disappeared");
17112        }
17113    }
17114
17115    private void clearProfilerLocked() {
17116        if (mProfileFd != null) {
17117            try {
17118                mProfileFd.close();
17119            } catch (IOException e) {
17120            }
17121        }
17122        mProfileApp = null;
17123        mProfileProc = null;
17124        mProfileFile = null;
17125        mProfileType = 0;
17126        mAutoStopProfiler = false;
17127    }
17128
17129    public boolean profileControl(String process, int userId, boolean start,
17130            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
17131
17132        try {
17133            synchronized (this) {
17134                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17135                // its own permission.
17136                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17137                        != PackageManager.PERMISSION_GRANTED) {
17138                    throw new SecurityException("Requires permission "
17139                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17140                }
17141
17142                if (start && fd == null) {
17143                    throw new IllegalArgumentException("null fd");
17144                }
17145
17146                ProcessRecord proc = null;
17147                if (process != null) {
17148                    proc = findProcessLocked(process, userId, "profileControl");
17149                }
17150
17151                if (start && (proc == null || proc.thread == null)) {
17152                    throw new IllegalArgumentException("Unknown process: " + process);
17153                }
17154
17155                if (start) {
17156                    stopProfilerLocked(null, null, 0);
17157                    setProfileApp(proc.info, proc.processName, path, fd, false);
17158                    mProfileProc = proc;
17159                    mProfileType = profileType;
17160                    try {
17161                        fd = fd.dup();
17162                    } catch (IOException e) {
17163                        fd = null;
17164                    }
17165                    proc.thread.profilerControl(start, path, fd, profileType);
17166                    fd = null;
17167                    mProfileFd = null;
17168                } else {
17169                    stopProfilerLocked(proc, path, profileType);
17170                    if (fd != null) {
17171                        try {
17172                            fd.close();
17173                        } catch (IOException e) {
17174                        }
17175                    }
17176                }
17177
17178                return true;
17179            }
17180        } catch (RemoteException e) {
17181            throw new IllegalStateException("Process disappeared");
17182        } finally {
17183            if (fd != null) {
17184                try {
17185                    fd.close();
17186                } catch (IOException e) {
17187                }
17188            }
17189        }
17190    }
17191
17192    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17193        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17194                userId, true, ALLOW_FULL_ONLY, callName, null);
17195        ProcessRecord proc = null;
17196        try {
17197            int pid = Integer.parseInt(process);
17198            synchronized (mPidsSelfLocked) {
17199                proc = mPidsSelfLocked.get(pid);
17200            }
17201        } catch (NumberFormatException e) {
17202        }
17203
17204        if (proc == null) {
17205            ArrayMap<String, SparseArray<ProcessRecord>> all
17206                    = mProcessNames.getMap();
17207            SparseArray<ProcessRecord> procs = all.get(process);
17208            if (procs != null && procs.size() > 0) {
17209                proc = procs.valueAt(0);
17210                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17211                    for (int i=1; i<procs.size(); i++) {
17212                        ProcessRecord thisProc = procs.valueAt(i);
17213                        if (thisProc.userId == userId) {
17214                            proc = thisProc;
17215                            break;
17216                        }
17217                    }
17218                }
17219            }
17220        }
17221
17222        return proc;
17223    }
17224
17225    public boolean dumpHeap(String process, int userId, boolean managed,
17226            String path, ParcelFileDescriptor fd) throws RemoteException {
17227
17228        try {
17229            synchronized (this) {
17230                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17231                // its own permission (same as profileControl).
17232                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17233                        != PackageManager.PERMISSION_GRANTED) {
17234                    throw new SecurityException("Requires permission "
17235                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17236                }
17237
17238                if (fd == null) {
17239                    throw new IllegalArgumentException("null fd");
17240                }
17241
17242                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17243                if (proc == null || proc.thread == null) {
17244                    throw new IllegalArgumentException("Unknown process: " + process);
17245                }
17246
17247                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17248                if (!isDebuggable) {
17249                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17250                        throw new SecurityException("Process not debuggable: " + proc);
17251                    }
17252                }
17253
17254                proc.thread.dumpHeap(managed, path, fd);
17255                fd = null;
17256                return true;
17257            }
17258        } catch (RemoteException e) {
17259            throw new IllegalStateException("Process disappeared");
17260        } finally {
17261            if (fd != null) {
17262                try {
17263                    fd.close();
17264                } catch (IOException e) {
17265                }
17266            }
17267        }
17268    }
17269
17270    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17271    public void monitor() {
17272        synchronized (this) { }
17273    }
17274
17275    void onCoreSettingsChange(Bundle settings) {
17276        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17277            ProcessRecord processRecord = mLruProcesses.get(i);
17278            try {
17279                if (processRecord.thread != null) {
17280                    processRecord.thread.setCoreSettings(settings);
17281                }
17282            } catch (RemoteException re) {
17283                /* ignore */
17284            }
17285        }
17286    }
17287
17288    // Multi-user methods
17289
17290    /**
17291     * Start user, if its not already running, but don't bring it to foreground.
17292     */
17293    @Override
17294    public boolean startUserInBackground(final int userId) {
17295        return startUser(userId, /* foreground */ false);
17296    }
17297
17298    /**
17299     * Refreshes the list of users related to the current user when either a
17300     * user switch happens or when a new related user is started in the
17301     * background.
17302     */
17303    private void updateCurrentProfileIdsLocked() {
17304        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17305                mCurrentUserId, false /* enabledOnly */);
17306        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17307        for (int i = 0; i < currentProfileIds.length; i++) {
17308            currentProfileIds[i] = profiles.get(i).id;
17309        }
17310        mCurrentProfileIds = currentProfileIds;
17311
17312        synchronized (mUserProfileGroupIdsSelfLocked) {
17313            mUserProfileGroupIdsSelfLocked.clear();
17314            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17315            for (int i = 0; i < users.size(); i++) {
17316                UserInfo user = users.get(i);
17317                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17318                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17319                }
17320            }
17321        }
17322    }
17323
17324    private Set getProfileIdsLocked(int userId) {
17325        Set userIds = new HashSet<Integer>();
17326        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17327                userId, false /* enabledOnly */);
17328        for (UserInfo user : profiles) {
17329            userIds.add(Integer.valueOf(user.id));
17330        }
17331        return userIds;
17332    }
17333
17334    @Override
17335    public boolean switchUser(final int userId) {
17336        return startUser(userId, /* foregound */ true);
17337    }
17338
17339    private boolean startUser(final int userId, boolean foreground) {
17340        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17341                != PackageManager.PERMISSION_GRANTED) {
17342            String msg = "Permission Denial: switchUser() from pid="
17343                    + Binder.getCallingPid()
17344                    + ", uid=" + Binder.getCallingUid()
17345                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17346            Slog.w(TAG, msg);
17347            throw new SecurityException(msg);
17348        }
17349
17350        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17351
17352        final long ident = Binder.clearCallingIdentity();
17353        try {
17354            synchronized (this) {
17355                final int oldUserId = mCurrentUserId;
17356                if (oldUserId == userId) {
17357                    return true;
17358                }
17359
17360                mStackSupervisor.setLockTaskModeLocked(null, false);
17361
17362                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17363                if (userInfo == null) {
17364                    Slog.w(TAG, "No user info for user #" + userId);
17365                    return false;
17366                }
17367                if (foreground && userInfo.isManagedProfile()) {
17368                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17369                    return false;
17370                }
17371
17372                if (foreground) {
17373                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17374                            R.anim.screen_user_enter);
17375                }
17376
17377                boolean needStart = false;
17378
17379                // If the user we are switching to is not currently started, then
17380                // we need to start it now.
17381                if (mStartedUsers.get(userId) == null) {
17382                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17383                    updateStartedUserArrayLocked();
17384                    needStart = true;
17385                }
17386
17387                final Integer userIdInt = Integer.valueOf(userId);
17388                mUserLru.remove(userIdInt);
17389                mUserLru.add(userIdInt);
17390
17391                if (foreground) {
17392                    mCurrentUserId = userId;
17393                    updateCurrentProfileIdsLocked();
17394                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17395                    // Once the internal notion of the active user has switched, we lock the device
17396                    // with the option to show the user switcher on the keyguard.
17397                    mWindowManager.lockNow(null);
17398                } else {
17399                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17400                    updateCurrentProfileIdsLocked();
17401                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17402                    mUserLru.remove(currentUserIdInt);
17403                    mUserLru.add(currentUserIdInt);
17404                }
17405
17406                final UserStartedState uss = mStartedUsers.get(userId);
17407
17408                // Make sure user is in the started state.  If it is currently
17409                // stopping, we need to knock that off.
17410                if (uss.mState == UserStartedState.STATE_STOPPING) {
17411                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17412                    // so we can just fairly silently bring the user back from
17413                    // the almost-dead.
17414                    uss.mState = UserStartedState.STATE_RUNNING;
17415                    updateStartedUserArrayLocked();
17416                    needStart = true;
17417                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17418                    // This means ACTION_SHUTDOWN has been sent, so we will
17419                    // need to treat this as a new boot of the user.
17420                    uss.mState = UserStartedState.STATE_BOOTING;
17421                    updateStartedUserArrayLocked();
17422                    needStart = true;
17423                }
17424
17425                if (uss.mState == UserStartedState.STATE_BOOTING) {
17426                    // Booting up a new user, need to tell system services about it.
17427                    // Note that this is on the same handler as scheduling of broadcasts,
17428                    // which is important because it needs to go first.
17429                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
17430                }
17431
17432                if (foreground) {
17433                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17434                            oldUserId));
17435                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17436                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17437                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17438                            oldUserId, userId, uss));
17439                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17440                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17441                }
17442
17443                if (needStart) {
17444                    // Send USER_STARTED broadcast
17445                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17446                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17447                            | Intent.FLAG_RECEIVER_FOREGROUND);
17448                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17449                    broadcastIntentLocked(null, null, intent,
17450                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17451                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17452                }
17453
17454                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17455                    if (userId != UserHandle.USER_OWNER) {
17456                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17457                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17458                        broadcastIntentLocked(null, null, intent, null,
17459                                new IIntentReceiver.Stub() {
17460                                    public void performReceive(Intent intent, int resultCode,
17461                                            String data, Bundle extras, boolean ordered,
17462                                            boolean sticky, int sendingUser) {
17463                                        userInitialized(uss, userId);
17464                                    }
17465                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17466                                true, false, MY_PID, Process.SYSTEM_UID,
17467                                userId);
17468                        uss.initializing = true;
17469                    } else {
17470                        getUserManagerLocked().makeInitialized(userInfo.id);
17471                    }
17472                }
17473
17474                if (foreground) {
17475                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17476                    if (homeInFront) {
17477                        startHomeActivityLocked(userId);
17478                    } else {
17479                        mStackSupervisor.resumeTopActivitiesLocked();
17480                    }
17481                    EventLogTags.writeAmSwitchUser(userId);
17482                    getUserManagerLocked().userForeground(userId);
17483                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17484                } else {
17485                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17486                }
17487
17488                if (needStart) {
17489                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17490                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17491                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17492                    broadcastIntentLocked(null, null, intent,
17493                            null, new IIntentReceiver.Stub() {
17494                                @Override
17495                                public void performReceive(Intent intent, int resultCode, String data,
17496                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17497                                        throws RemoteException {
17498                                }
17499                            }, 0, null, null,
17500                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17501                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17502                }
17503            }
17504        } finally {
17505            Binder.restoreCallingIdentity(ident);
17506        }
17507
17508        return true;
17509    }
17510
17511    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17512        long ident = Binder.clearCallingIdentity();
17513        try {
17514            Intent intent;
17515            if (oldUserId >= 0) {
17516                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17517                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17518                int count = profiles.size();
17519                for (int i = 0; i < count; i++) {
17520                    int profileUserId = profiles.get(i).id;
17521                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17522                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17523                            | Intent.FLAG_RECEIVER_FOREGROUND);
17524                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17525                    broadcastIntentLocked(null, null, intent,
17526                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17527                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17528                }
17529            }
17530            if (newUserId >= 0) {
17531                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17532                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17533                int count = profiles.size();
17534                for (int i = 0; i < count; i++) {
17535                    int profileUserId = profiles.get(i).id;
17536                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17537                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17538                            | Intent.FLAG_RECEIVER_FOREGROUND);
17539                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17540                    broadcastIntentLocked(null, null, intent,
17541                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17542                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17543                }
17544                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17545                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17546                        | Intent.FLAG_RECEIVER_FOREGROUND);
17547                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17548                broadcastIntentLocked(null, null, intent,
17549                        null, null, 0, null, null,
17550                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17551                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17552            }
17553        } finally {
17554            Binder.restoreCallingIdentity(ident);
17555        }
17556    }
17557
17558    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17559            final int newUserId) {
17560        final int N = mUserSwitchObservers.beginBroadcast();
17561        if (N > 0) {
17562            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17563                int mCount = 0;
17564                @Override
17565                public void sendResult(Bundle data) throws RemoteException {
17566                    synchronized (ActivityManagerService.this) {
17567                        if (mCurUserSwitchCallback == this) {
17568                            mCount++;
17569                            if (mCount == N) {
17570                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17571                            }
17572                        }
17573                    }
17574                }
17575            };
17576            synchronized (this) {
17577                uss.switching = true;
17578                mCurUserSwitchCallback = callback;
17579            }
17580            for (int i=0; i<N; i++) {
17581                try {
17582                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17583                            newUserId, callback);
17584                } catch (RemoteException e) {
17585                }
17586            }
17587        } else {
17588            synchronized (this) {
17589                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17590            }
17591        }
17592        mUserSwitchObservers.finishBroadcast();
17593    }
17594
17595    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17596        synchronized (this) {
17597            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17598            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17599        }
17600    }
17601
17602    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17603        mCurUserSwitchCallback = null;
17604        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17605        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17606                oldUserId, newUserId, uss));
17607    }
17608
17609    void userInitialized(UserStartedState uss, int newUserId) {
17610        completeSwitchAndInitalize(uss, newUserId, true, false);
17611    }
17612
17613    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17614        completeSwitchAndInitalize(uss, newUserId, false, true);
17615    }
17616
17617    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17618            boolean clearInitializing, boolean clearSwitching) {
17619        boolean unfrozen = false;
17620        synchronized (this) {
17621            if (clearInitializing) {
17622                uss.initializing = false;
17623                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17624            }
17625            if (clearSwitching) {
17626                uss.switching = false;
17627            }
17628            if (!uss.switching && !uss.initializing) {
17629                mWindowManager.stopFreezingScreen();
17630                unfrozen = true;
17631            }
17632        }
17633        if (unfrozen) {
17634            final int N = mUserSwitchObservers.beginBroadcast();
17635            for (int i=0; i<N; i++) {
17636                try {
17637                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17638                } catch (RemoteException e) {
17639                }
17640            }
17641            mUserSwitchObservers.finishBroadcast();
17642        }
17643    }
17644
17645    void scheduleStartProfilesLocked() {
17646        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17647            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17648                    DateUtils.SECOND_IN_MILLIS);
17649        }
17650    }
17651
17652    void startProfilesLocked() {
17653        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17654        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17655                mCurrentUserId, false /* enabledOnly */);
17656        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17657        for (UserInfo user : profiles) {
17658            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17659                    && user.id != mCurrentUserId) {
17660                toStart.add(user);
17661            }
17662        }
17663        final int n = toStart.size();
17664        int i = 0;
17665        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17666            startUserInBackground(toStart.get(i).id);
17667        }
17668        if (i < n) {
17669            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17670        }
17671    }
17672
17673    void finishUserBoot(UserStartedState uss) {
17674        synchronized (this) {
17675            if (uss.mState == UserStartedState.STATE_BOOTING
17676                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17677                uss.mState = UserStartedState.STATE_RUNNING;
17678                final int userId = uss.mHandle.getIdentifier();
17679                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17680                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17681                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17682                broadcastIntentLocked(null, null, intent,
17683                        null, null, 0, null, null,
17684                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17685                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17686            }
17687        }
17688    }
17689
17690    void finishUserSwitch(UserStartedState uss) {
17691        synchronized (this) {
17692            finishUserBoot(uss);
17693
17694            startProfilesLocked();
17695
17696            int num = mUserLru.size();
17697            int i = 0;
17698            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17699                Integer oldUserId = mUserLru.get(i);
17700                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17701                if (oldUss == null) {
17702                    // Shouldn't happen, but be sane if it does.
17703                    mUserLru.remove(i);
17704                    num--;
17705                    continue;
17706                }
17707                if (oldUss.mState == UserStartedState.STATE_STOPPING
17708                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17709                    // This user is already stopping, doesn't count.
17710                    num--;
17711                    i++;
17712                    continue;
17713                }
17714                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17715                    // Owner and current can't be stopped, but count as running.
17716                    i++;
17717                    continue;
17718                }
17719                // This is a user to be stopped.
17720                stopUserLocked(oldUserId, null);
17721                num--;
17722                i++;
17723            }
17724        }
17725    }
17726
17727    @Override
17728    public int stopUser(final int userId, final IStopUserCallback callback) {
17729        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17730                != PackageManager.PERMISSION_GRANTED) {
17731            String msg = "Permission Denial: switchUser() from pid="
17732                    + Binder.getCallingPid()
17733                    + ", uid=" + Binder.getCallingUid()
17734                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17735            Slog.w(TAG, msg);
17736            throw new SecurityException(msg);
17737        }
17738        if (userId <= 0) {
17739            throw new IllegalArgumentException("Can't stop primary user " + userId);
17740        }
17741        synchronized (this) {
17742            return stopUserLocked(userId, callback);
17743        }
17744    }
17745
17746    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17747        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17748        if (mCurrentUserId == userId) {
17749            return ActivityManager.USER_OP_IS_CURRENT;
17750        }
17751
17752        final UserStartedState uss = mStartedUsers.get(userId);
17753        if (uss == null) {
17754            // User is not started, nothing to do...  but we do need to
17755            // callback if requested.
17756            if (callback != null) {
17757                mHandler.post(new Runnable() {
17758                    @Override
17759                    public void run() {
17760                        try {
17761                            callback.userStopped(userId);
17762                        } catch (RemoteException e) {
17763                        }
17764                    }
17765                });
17766            }
17767            return ActivityManager.USER_OP_SUCCESS;
17768        }
17769
17770        if (callback != null) {
17771            uss.mStopCallbacks.add(callback);
17772        }
17773
17774        if (uss.mState != UserStartedState.STATE_STOPPING
17775                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17776            uss.mState = UserStartedState.STATE_STOPPING;
17777            updateStartedUserArrayLocked();
17778
17779            long ident = Binder.clearCallingIdentity();
17780            try {
17781                // We are going to broadcast ACTION_USER_STOPPING and then
17782                // once that is done send a final ACTION_SHUTDOWN and then
17783                // stop the user.
17784                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17785                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17786                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17787                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17788                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17789                // This is the result receiver for the final shutdown broadcast.
17790                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17791                    @Override
17792                    public void performReceive(Intent intent, int resultCode, String data,
17793                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17794                        finishUserStop(uss);
17795                    }
17796                };
17797                // This is the result receiver for the initial stopping broadcast.
17798                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17799                    @Override
17800                    public void performReceive(Intent intent, int resultCode, String data,
17801                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17802                        // On to the next.
17803                        synchronized (ActivityManagerService.this) {
17804                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17805                                // Whoops, we are being started back up.  Abort, abort!
17806                                return;
17807                            }
17808                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17809                        }
17810                        mBatteryStatsService.noteEvent(
17811                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17812                                Integer.toString(userId), userId);
17813                        mSystemServiceManager.stopUser(userId);
17814                        broadcastIntentLocked(null, null, shutdownIntent,
17815                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17816                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17817                    }
17818                };
17819                // Kick things off.
17820                broadcastIntentLocked(null, null, stoppingIntent,
17821                        null, stoppingReceiver, 0, null, null,
17822                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17823                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17824            } finally {
17825                Binder.restoreCallingIdentity(ident);
17826            }
17827        }
17828
17829        return ActivityManager.USER_OP_SUCCESS;
17830    }
17831
17832    void finishUserStop(UserStartedState uss) {
17833        final int userId = uss.mHandle.getIdentifier();
17834        boolean stopped;
17835        ArrayList<IStopUserCallback> callbacks;
17836        synchronized (this) {
17837            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17838            if (mStartedUsers.get(userId) != uss) {
17839                stopped = false;
17840            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17841                stopped = false;
17842            } else {
17843                stopped = true;
17844                // User can no longer run.
17845                mStartedUsers.remove(userId);
17846                mUserLru.remove(Integer.valueOf(userId));
17847                updateStartedUserArrayLocked();
17848
17849                // Clean up all state and processes associated with the user.
17850                // Kill all the processes for the user.
17851                forceStopUserLocked(userId, "finish user");
17852            }
17853
17854            // Explicitly remove the old information in mRecentTasks.
17855            removeRecentTasksForUserLocked(userId);
17856        }
17857
17858        for (int i=0; i<callbacks.size(); i++) {
17859            try {
17860                if (stopped) callbacks.get(i).userStopped(userId);
17861                else callbacks.get(i).userStopAborted(userId);
17862            } catch (RemoteException e) {
17863            }
17864        }
17865
17866        if (stopped) {
17867            mSystemServiceManager.cleanupUser(userId);
17868            synchronized (this) {
17869                mStackSupervisor.removeUserLocked(userId);
17870            }
17871        }
17872    }
17873
17874    @Override
17875    public UserInfo getCurrentUser() {
17876        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17877                != PackageManager.PERMISSION_GRANTED) && (
17878                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17879                != PackageManager.PERMISSION_GRANTED)) {
17880            String msg = "Permission Denial: getCurrentUser() from pid="
17881                    + Binder.getCallingPid()
17882                    + ", uid=" + Binder.getCallingUid()
17883                    + " requires " + INTERACT_ACROSS_USERS;
17884            Slog.w(TAG, msg);
17885            throw new SecurityException(msg);
17886        }
17887        synchronized (this) {
17888            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17889        }
17890    }
17891
17892    int getCurrentUserIdLocked() {
17893        return mCurrentUserId;
17894    }
17895
17896    @Override
17897    public boolean isUserRunning(int userId, boolean orStopped) {
17898        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17899                != PackageManager.PERMISSION_GRANTED) {
17900            String msg = "Permission Denial: isUserRunning() from pid="
17901                    + Binder.getCallingPid()
17902                    + ", uid=" + Binder.getCallingUid()
17903                    + " requires " + INTERACT_ACROSS_USERS;
17904            Slog.w(TAG, msg);
17905            throw new SecurityException(msg);
17906        }
17907        synchronized (this) {
17908            return isUserRunningLocked(userId, orStopped);
17909        }
17910    }
17911
17912    boolean isUserRunningLocked(int userId, boolean orStopped) {
17913        UserStartedState state = mStartedUsers.get(userId);
17914        if (state == null) {
17915            return false;
17916        }
17917        if (orStopped) {
17918            return true;
17919        }
17920        return state.mState != UserStartedState.STATE_STOPPING
17921                && state.mState != UserStartedState.STATE_SHUTDOWN;
17922    }
17923
17924    @Override
17925    public int[] getRunningUserIds() {
17926        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17927                != PackageManager.PERMISSION_GRANTED) {
17928            String msg = "Permission Denial: isUserRunning() from pid="
17929                    + Binder.getCallingPid()
17930                    + ", uid=" + Binder.getCallingUid()
17931                    + " requires " + INTERACT_ACROSS_USERS;
17932            Slog.w(TAG, msg);
17933            throw new SecurityException(msg);
17934        }
17935        synchronized (this) {
17936            return mStartedUserArray;
17937        }
17938    }
17939
17940    private void updateStartedUserArrayLocked() {
17941        int num = 0;
17942        for (int i=0; i<mStartedUsers.size();  i++) {
17943            UserStartedState uss = mStartedUsers.valueAt(i);
17944            // This list does not include stopping users.
17945            if (uss.mState != UserStartedState.STATE_STOPPING
17946                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17947                num++;
17948            }
17949        }
17950        mStartedUserArray = new int[num];
17951        num = 0;
17952        for (int i=0; i<mStartedUsers.size();  i++) {
17953            UserStartedState uss = mStartedUsers.valueAt(i);
17954            if (uss.mState != UserStartedState.STATE_STOPPING
17955                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17956                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17957                num++;
17958            }
17959        }
17960    }
17961
17962    @Override
17963    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17964        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17965                != PackageManager.PERMISSION_GRANTED) {
17966            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17967                    + Binder.getCallingPid()
17968                    + ", uid=" + Binder.getCallingUid()
17969                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17970            Slog.w(TAG, msg);
17971            throw new SecurityException(msg);
17972        }
17973
17974        mUserSwitchObservers.register(observer);
17975    }
17976
17977    @Override
17978    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17979        mUserSwitchObservers.unregister(observer);
17980    }
17981
17982    private boolean userExists(int userId) {
17983        if (userId == 0) {
17984            return true;
17985        }
17986        UserManagerService ums = getUserManagerLocked();
17987        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17988    }
17989
17990    int[] getUsersLocked() {
17991        UserManagerService ums = getUserManagerLocked();
17992        return ums != null ? ums.getUserIds() : new int[] { 0 };
17993    }
17994
17995    UserManagerService getUserManagerLocked() {
17996        if (mUserManager == null) {
17997            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17998            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17999        }
18000        return mUserManager;
18001    }
18002
18003    private int applyUserId(int uid, int userId) {
18004        return UserHandle.getUid(userId, uid);
18005    }
18006
18007    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18008        if (info == null) return null;
18009        ApplicationInfo newInfo = new ApplicationInfo(info);
18010        newInfo.uid = applyUserId(info.uid, userId);
18011        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18012                + info.packageName;
18013        return newInfo;
18014    }
18015
18016    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18017        if (aInfo == null
18018                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18019            return aInfo;
18020        }
18021
18022        ActivityInfo info = new ActivityInfo(aInfo);
18023        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18024        return info;
18025    }
18026
18027    private final class LocalService extends ActivityManagerInternal {
18028        @Override
18029        public void goingToSleep() {
18030            ActivityManagerService.this.goingToSleep();
18031        }
18032
18033        @Override
18034        public void wakingUp() {
18035            ActivityManagerService.this.wakingUp();
18036        }
18037
18038        @Override
18039        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18040                String processName, String abiOverride, int uid, Runnable crashHandler) {
18041            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18042                    processName, abiOverride, uid, crashHandler);
18043        }
18044    }
18045
18046    /**
18047     * An implementation of IAppTask, that allows an app to manage its own tasks via
18048     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18049     * only the process that calls getAppTasks() can call the AppTask methods.
18050     */
18051    class AppTaskImpl extends IAppTask.Stub {
18052        private int mTaskId;
18053        private int mCallingUid;
18054
18055        public AppTaskImpl(int taskId, int callingUid) {
18056            mTaskId = taskId;
18057            mCallingUid = callingUid;
18058        }
18059
18060        @Override
18061        public void finishAndRemoveTask() {
18062            // Ensure that we are called from the same process that created this AppTask
18063            if (mCallingUid != Binder.getCallingUid()) {
18064                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
18065                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18066                return;
18067            }
18068
18069            synchronized (ActivityManagerService.this) {
18070                long origId = Binder.clearCallingIdentity();
18071                try {
18072                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18073                    if (tr != null) {
18074                        // Only kill the process if we are not a new document
18075                        int flags = tr.getBaseIntent().getFlags();
18076                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18077                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18078                        removeTaskByIdLocked(mTaskId,
18079                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18080                    }
18081                } finally {
18082                    Binder.restoreCallingIdentity(origId);
18083                }
18084            }
18085        }
18086
18087        @Override
18088        public ActivityManager.RecentTaskInfo getTaskInfo() {
18089            // Ensure that we are called from the same process that created this AppTask
18090            if (mCallingUid != Binder.getCallingUid()) {
18091                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
18092                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18093                return null;
18094            }
18095
18096            synchronized (ActivityManagerService.this) {
18097                long origId = Binder.clearCallingIdentity();
18098                try {
18099                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18100                    if (tr != null) {
18101                        return createRecentTaskInfoFromTaskRecord(tr);
18102                    }
18103                } finally {
18104                    Binder.restoreCallingIdentity(origId);
18105                }
18106                return null;
18107            }
18108        }
18109    }
18110}
18111