ActivityManagerService.java revision 994e219da8ebee85d8c6b9564995e8ed9eae81e4
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.UsageStats;
41import android.app.usage.UsageStatsManagerInternal;
42import android.appwidget.AppWidgetManager;
43import android.graphics.Rect;
44import android.os.BatteryStats;
45import android.os.PersistableBundle;
46import android.service.voice.IVoiceInteractionSession;
47import android.util.ArrayMap;
48import android.util.ArraySet;
49import android.util.SparseIntArray;
50
51import com.android.internal.R;
52import com.android.internal.annotations.GuardedBy;
53import com.android.internal.app.IAppOpsService;
54import com.android.internal.app.IVoiceInteractor;
55import com.android.internal.app.ProcessMap;
56import com.android.internal.app.ProcessStats;
57import com.android.internal.content.PackageMonitor;
58import com.android.internal.os.BackgroundThread;
59import com.android.internal.os.BatteryStatsImpl;
60import com.android.internal.os.ProcessCpuTracker;
61import com.android.internal.os.TransferPipe;
62import com.android.internal.os.Zygote;
63import com.android.internal.util.FastPrintWriter;
64import com.android.internal.util.FastXmlSerializer;
65import com.android.internal.util.MemInfoReader;
66import com.android.internal.util.Preconditions;
67import com.android.server.AppOpsService;
68import com.android.server.AttributeCache;
69import com.android.server.IntentResolver;
70import com.android.server.LocalServices;
71import com.android.server.ServiceThread;
72import com.android.server.SystemService;
73import com.android.server.SystemServiceManager;
74import com.android.server.Watchdog;
75import com.android.server.am.ActivityStack.ActivityState;
76import com.android.server.firewall.IntentFirewall;
77import com.android.server.pm.UserManagerService;
78import com.android.server.wm.AppTransition;
79import com.android.server.wm.WindowManagerService;
80import com.google.android.collect.Lists;
81import com.google.android.collect.Maps;
82
83import libcore.io.IoUtils;
84
85import org.xmlpull.v1.XmlPullParser;
86import org.xmlpull.v1.XmlPullParserException;
87import org.xmlpull.v1.XmlSerializer;
88
89import android.app.Activity;
90import android.app.ActivityManager;
91import android.app.ActivityManager.RunningTaskInfo;
92import android.app.ActivityManager.StackInfo;
93import android.app.ActivityManagerInternal;
94import android.app.ActivityManagerNative;
95import android.app.ActivityOptions;
96import android.app.ActivityThread;
97import android.app.AlertDialog;
98import android.app.AppGlobals;
99import android.app.ApplicationErrorReport;
100import android.app.Dialog;
101import android.app.IActivityController;
102import android.app.IApplicationThread;
103import android.app.IInstrumentationWatcher;
104import android.app.INotificationManager;
105import android.app.IProcessObserver;
106import android.app.IServiceConnection;
107import android.app.IStopUserCallback;
108import android.app.IUiAutomationConnection;
109import android.app.IUserSwitchObserver;
110import android.app.Instrumentation;
111import android.app.Notification;
112import android.app.NotificationManager;
113import android.app.PendingIntent;
114import android.app.backup.IBackupManager;
115import android.content.ActivityNotFoundException;
116import android.content.BroadcastReceiver;
117import android.content.ClipData;
118import android.content.ComponentCallbacks2;
119import android.content.ComponentName;
120import android.content.ContentProvider;
121import android.content.ContentResolver;
122import android.content.Context;
123import android.content.DialogInterface;
124import android.content.IContentProvider;
125import android.content.IIntentReceiver;
126import android.content.IIntentSender;
127import android.content.Intent;
128import android.content.IntentFilter;
129import android.content.IntentSender;
130import android.content.pm.ActivityInfo;
131import android.content.pm.ApplicationInfo;
132import android.content.pm.ConfigurationInfo;
133import android.content.pm.IPackageDataObserver;
134import android.content.pm.IPackageManager;
135import android.content.pm.InstrumentationInfo;
136import android.content.pm.PackageInfo;
137import android.content.pm.PackageManager;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.UserInfo;
140import android.content.pm.PackageManager.NameNotFoundException;
141import android.content.pm.PathPermission;
142import android.content.pm.ProviderInfo;
143import android.content.pm.ResolveInfo;
144import android.content.pm.ServiceInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.net.Proxy;
148import android.net.ProxyInfo;
149import android.net.Uri;
150import android.os.Binder;
151import android.os.Build;
152import android.os.Bundle;
153import android.os.Debug;
154import android.os.DropBoxManager;
155import android.os.Environment;
156import android.os.FactoryTest;
157import android.os.FileObserver;
158import android.os.FileUtils;
159import android.os.Handler;
160import android.os.IBinder;
161import android.os.IPermissionController;
162import android.os.IRemoteCallback;
163import android.os.IUserManager;
164import android.os.Looper;
165import android.os.Message;
166import android.os.Parcel;
167import android.os.ParcelFileDescriptor;
168import android.os.Process;
169import android.os.RemoteCallbackList;
170import android.os.RemoteException;
171import android.os.SELinux;
172import android.os.ServiceManager;
173import android.os.StrictMode;
174import android.os.SystemClock;
175import android.os.SystemProperties;
176import android.os.UpdateLock;
177import android.os.UserHandle;
178import android.provider.Settings;
179import android.text.format.DateUtils;
180import android.text.format.Time;
181import android.util.AtomicFile;
182import android.util.EventLog;
183import android.util.Log;
184import android.util.Pair;
185import android.util.PrintWriterPrinter;
186import android.util.Slog;
187import android.util.SparseArray;
188import android.util.TimeUtils;
189import android.util.Xml;
190import android.view.Gravity;
191import android.view.LayoutInflater;
192import android.view.View;
193import android.view.WindowManager;
194
195import java.io.BufferedInputStream;
196import java.io.BufferedOutputStream;
197import java.io.DataInputStream;
198import java.io.DataOutputStream;
199import java.io.File;
200import java.io.FileDescriptor;
201import java.io.FileInputStream;
202import java.io.FileNotFoundException;
203import java.io.FileOutputStream;
204import java.io.IOException;
205import java.io.InputStreamReader;
206import java.io.PrintWriter;
207import java.io.StringWriter;
208import java.lang.ref.WeakReference;
209import java.util.ArrayList;
210import java.util.Arrays;
211import java.util.Collections;
212import java.util.Comparator;
213import java.util.HashMap;
214import java.util.HashSet;
215import java.util.Iterator;
216import java.util.List;
217import java.util.Locale;
218import java.util.Map;
219import java.util.Set;
220import java.util.concurrent.atomic.AtomicBoolean;
221import java.util.concurrent.atomic.AtomicLong;
222
223public final class ActivityManagerService extends ActivityManagerNative
224        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
225
226    private static final String USER_DATA_DIR = "/data/user/";
227    // File that stores last updated system version and called preboot receivers
228    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
229
230    static final String TAG = "ActivityManager";
231    static final String TAG_MU = "ActivityManagerServiceMU";
232    static final boolean DEBUG = false;
233    static final boolean localLOGV = DEBUG;
234    static final boolean DEBUG_BACKUP = localLOGV || false;
235    static final boolean DEBUG_BROADCAST = localLOGV || false;
236    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
237    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
238    static final boolean DEBUG_CLEANUP = localLOGV || false;
239    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
240    static final boolean DEBUG_FOCUS = false;
241    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
242    static final boolean DEBUG_MU = localLOGV || false;
243    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
244    static final boolean DEBUG_LRU = localLOGV || false;
245    static final boolean DEBUG_PAUSE = localLOGV || false;
246    static final boolean DEBUG_POWER = localLOGV || false;
247    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
248    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
249    static final boolean DEBUG_PROCESSES = localLOGV || false;
250    static final boolean DEBUG_PROVIDER = localLOGV || false;
251    static final boolean DEBUG_RESULTS = localLOGV || false;
252    static final boolean DEBUG_SERVICE = localLOGV || false;
253    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
254    static final boolean DEBUG_STACK = localLOGV || false;
255    static final boolean DEBUG_SWITCH = localLOGV || false;
256    static final boolean DEBUG_TASKS = localLOGV || false;
257    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
258    static final boolean DEBUG_TRANSITION = localLOGV || false;
259    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
260    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
261    static final boolean DEBUG_VISBILITY = localLOGV || false;
262    static final boolean DEBUG_PSS = localLOGV || false;
263    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
264    static final boolean VALIDATE_TOKENS = false;
265    static final boolean SHOW_ACTIVITY_START_TIME = true;
266
267    // Control over CPU and battery monitoring.
268    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
269    static final boolean MONITOR_CPU_USAGE = true;
270    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
271    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
272    static final boolean MONITOR_THREAD_CPU_USAGE = false;
273
274    // The flags that are set for all calls we make to the package manager.
275    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
276
277    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
278
279    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
280
281    // Maximum number of recent tasks that we can remember.
282    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
283
284    // Maximum number recent bitmaps to keep in memory.
285    static final int MAX_RECENT_BITMAPS = 5;
286
287    // Amount of time after a call to stopAppSwitches() during which we will
288    // prevent further untrusted switches from happening.
289    static final long APP_SWITCH_DELAY_TIME = 5*1000;
290
291    // How long we wait for a launched process to attach to the activity manager
292    // before we decide it's never going to come up for real.
293    static final int PROC_START_TIMEOUT = 10*1000;
294
295    // How long we wait for a launched process to attach to the activity manager
296    // before we decide it's never going to come up for real, when the process was
297    // started with a wrapper for instrumentation (such as Valgrind) because it
298    // could take much longer than usual.
299    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
300
301    // How long to wait after going idle before forcing apps to GC.
302    static final int GC_TIMEOUT = 5*1000;
303
304    // The minimum amount of time between successive GC requests for a process.
305    static final int GC_MIN_INTERVAL = 60*1000;
306
307    // The minimum amount of time between successive PSS requests for a process.
308    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
309
310    // The minimum amount of time between successive PSS requests for a process
311    // when the request is due to the memory state being lowered.
312    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
313
314    // The rate at which we check for apps using excessive power -- 15 mins.
315    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
316
317    // The minimum sample duration we will allow before deciding we have
318    // enough data on wake locks to start killing things.
319    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
320
321    // The minimum sample duration we will allow before deciding we have
322    // enough data on CPU usage to start killing things.
323    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
324
325    // How long we allow a receiver to run before giving up on it.
326    static final int BROADCAST_FG_TIMEOUT = 10*1000;
327    static final int BROADCAST_BG_TIMEOUT = 60*1000;
328
329    // How long we wait until we timeout on key dispatching.
330    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
331
332    // How long we wait until we timeout on key dispatching during instrumentation.
333    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
334
335    // Amount of time we wait for observers to handle a user switch before
336    // giving up on them and unfreezing the screen.
337    static final int USER_SWITCH_TIMEOUT = 2*1000;
338
339    // Maximum number of users we allow to be running at a time.
340    static final int MAX_RUNNING_USERS = 3;
341
342    // How long to wait in getAssistContextExtras for the activity and foreground services
343    // to respond with the result.
344    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
345
346    // Maximum number of persisted Uri grants a package is allowed
347    static final int MAX_PERSISTED_URI_GRANTS = 128;
348
349    static final int MY_PID = Process.myPid();
350
351    static final String[] EMPTY_STRING_ARRAY = new String[0];
352
353    // How many bytes to write into the dropbox log before truncating
354    static final int DROPBOX_MAX_SIZE = 256 * 1024;
355
356    // Access modes for handleIncomingUser.
357    static final int ALLOW_NON_FULL = 0;
358    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
359    static final int ALLOW_FULL_ONLY = 2;
360
361    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
362
363    /** All system services */
364    SystemServiceManager mSystemServiceManager;
365
366    /** Run all ActivityStacks through this */
367    ActivityStackSupervisor mStackSupervisor;
368
369    public IntentFirewall mIntentFirewall;
370
371    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
372    // default actuion automatically.  Important for devices without direct input
373    // devices.
374    private boolean mShowDialogs = true;
375
376    BroadcastQueue mFgBroadcastQueue;
377    BroadcastQueue mBgBroadcastQueue;
378    // Convenient for easy iteration over the queues. Foreground is first
379    // so that dispatch of foreground broadcasts gets precedence.
380    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
381
382    BroadcastQueue broadcastQueueForIntent(Intent intent) {
383        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
384        if (DEBUG_BACKGROUND_BROADCAST) {
385            Slog.i(TAG, "Broadcast intent " + intent + " on "
386                    + (isFg ? "foreground" : "background")
387                    + " queue");
388        }
389        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
390    }
391
392    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
393        for (BroadcastQueue queue : mBroadcastQueues) {
394            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
395            if (r != null) {
396                return r;
397            }
398        }
399        return null;
400    }
401
402    /**
403     * Activity we have told the window manager to have key focus.
404     */
405    ActivityRecord mFocusedActivity = null;
406
407    /**
408     * List of intents that were used to start the most recent tasks.
409     */
410    ArrayList<TaskRecord> mRecentTasks;
411    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
412
413    public class PendingAssistExtras extends Binder implements Runnable {
414        public final ActivityRecord activity;
415        public boolean haveResult = false;
416        public Bundle result = null;
417        public PendingAssistExtras(ActivityRecord _activity) {
418            activity = _activity;
419        }
420        @Override
421        public void run() {
422            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
423            synchronized (this) {
424                haveResult = true;
425                notifyAll();
426            }
427        }
428    }
429
430    final ArrayList<PendingAssistExtras> mPendingAssistExtras
431            = new ArrayList<PendingAssistExtras>();
432
433    /**
434     * Process management.
435     */
436    final ProcessList mProcessList = new ProcessList();
437
438    /**
439     * All of the applications we currently have running organized by name.
440     * The keys are strings of the application package name (as
441     * returned by the package manager), and the keys are ApplicationRecord
442     * objects.
443     */
444    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
445
446    /**
447     * Tracking long-term execution of processes to look for abuse and other
448     * bad app behavior.
449     */
450    final ProcessStatsService mProcessStats;
451
452    /**
453     * The currently running isolated processes.
454     */
455    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
456
457    /**
458     * Counter for assigning isolated process uids, to avoid frequently reusing the
459     * same ones.
460     */
461    int mNextIsolatedProcessUid = 0;
462
463    /**
464     * The currently running heavy-weight process, if any.
465     */
466    ProcessRecord mHeavyWeightProcess = null;
467
468    /**
469     * The last time that various processes have crashed.
470     */
471    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
472
473    /**
474     * Information about a process that is currently marked as bad.
475     */
476    static final class BadProcessInfo {
477        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
478            this.time = time;
479            this.shortMsg = shortMsg;
480            this.longMsg = longMsg;
481            this.stack = stack;
482        }
483
484        final long time;
485        final String shortMsg;
486        final String longMsg;
487        final String stack;
488    }
489
490    /**
491     * Set of applications that we consider to be bad, and will reject
492     * incoming broadcasts from (which the user has no control over).
493     * Processes are added to this set when they have crashed twice within
494     * a minimum amount of time; they are removed from it when they are
495     * later restarted (hopefully due to some user action).  The value is the
496     * time it was added to the list.
497     */
498    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
499
500    /**
501     * All of the processes we currently have running organized by pid.
502     * The keys are the pid running the application.
503     *
504     * <p>NOTE: This object is protected by its own lock, NOT the global
505     * activity manager lock!
506     */
507    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
508
509    /**
510     * All of the processes that have been forced to be foreground.  The key
511     * is the pid of the caller who requested it (we hold a death
512     * link on it).
513     */
514    abstract class ForegroundToken implements IBinder.DeathRecipient {
515        int pid;
516        IBinder token;
517    }
518    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
519
520    /**
521     * List of records for processes that someone had tried to start before the
522     * system was ready.  We don't start them at that point, but ensure they
523     * are started by the time booting is complete.
524     */
525    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
526
527    /**
528     * List of persistent applications that are in the process
529     * of being started.
530     */
531    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
532
533    /**
534     * Processes that are being forcibly torn down.
535     */
536    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
537
538    /**
539     * List of running applications, sorted by recent usage.
540     * The first entry in the list is the least recently used.
541     */
542    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
543
544    /**
545     * Where in mLruProcesses that the processes hosting activities start.
546     */
547    int mLruProcessActivityStart = 0;
548
549    /**
550     * Where in mLruProcesses that the processes hosting services start.
551     * This is after (lower index) than mLruProcessesActivityStart.
552     */
553    int mLruProcessServiceStart = 0;
554
555    /**
556     * List of processes that should gc as soon as things are idle.
557     */
558    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
559
560    /**
561     * Processes we want to collect PSS data from.
562     */
563    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
564
565    /**
566     * Last time we requested PSS data of all processes.
567     */
568    long mLastFullPssTime = SystemClock.uptimeMillis();
569
570    /**
571     * If set, the next time we collect PSS data we should do a full collection
572     * with data from native processes and the kernel.
573     */
574    boolean mFullPssPending = false;
575
576    /**
577     * This is the process holding what we currently consider to be
578     * the "home" activity.
579     */
580    ProcessRecord mHomeProcess;
581
582    /**
583     * This is the process holding the activity the user last visited that
584     * is in a different process from the one they are currently in.
585     */
586    ProcessRecord mPreviousProcess;
587
588    /**
589     * The time at which the previous process was last visible.
590     */
591    long mPreviousProcessVisibleTime;
592
593    /**
594     * Which uses have been started, so are allowed to run code.
595     */
596    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
597
598    /**
599     * LRU list of history of current users.  Most recently current is at the end.
600     */
601    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
602
603    /**
604     * Constant array of the users that are currently started.
605     */
606    int[] mStartedUserArray = new int[] { 0 };
607
608    /**
609     * Registered observers of the user switching mechanics.
610     */
611    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
612            = new RemoteCallbackList<IUserSwitchObserver>();
613
614    /**
615     * Currently active user switch.
616     */
617    Object mCurUserSwitchCallback;
618
619    /**
620     * Packages that the user has asked to have run in screen size
621     * compatibility mode instead of filling the screen.
622     */
623    final CompatModePackages mCompatModePackages;
624
625    /**
626     * Set of IntentSenderRecord objects that are currently active.
627     */
628    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
629            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
630
631    /**
632     * Fingerprints (hashCode()) of stack traces that we've
633     * already logged DropBox entries for.  Guarded by itself.  If
634     * something (rogue user app) forces this over
635     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
636     */
637    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
638    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
639
640    /**
641     * Strict Mode background batched logging state.
642     *
643     * The string buffer is guarded by itself, and its lock is also
644     * used to determine if another batched write is already
645     * in-flight.
646     */
647    private final StringBuilder mStrictModeBuffer = new StringBuilder();
648
649    /**
650     * Keeps track of all IIntentReceivers that have been registered for
651     * broadcasts.  Hash keys are the receiver IBinder, hash value is
652     * a ReceiverList.
653     */
654    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
655            new HashMap<IBinder, ReceiverList>();
656
657    /**
658     * Resolver for broadcast intents to registered receivers.
659     * Holds BroadcastFilter (subclass of IntentFilter).
660     */
661    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
662            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
663        @Override
664        protected boolean allowFilterResult(
665                BroadcastFilter filter, List<BroadcastFilter> dest) {
666            IBinder target = filter.receiverList.receiver.asBinder();
667            for (int i=dest.size()-1; i>=0; i--) {
668                if (dest.get(i).receiverList.receiver.asBinder() == target) {
669                    return false;
670                }
671            }
672            return true;
673        }
674
675        @Override
676        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
677            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
678                    || userId == filter.owningUserId) {
679                return super.newResult(filter, match, userId);
680            }
681            return null;
682        }
683
684        @Override
685        protected BroadcastFilter[] newArray(int size) {
686            return new BroadcastFilter[size];
687        }
688
689        @Override
690        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
691            return packageName.equals(filter.packageName);
692        }
693    };
694
695    /**
696     * State of all active sticky broadcasts per user.  Keys are the action of the
697     * sticky Intent, values are an ArrayList of all broadcasted intents with
698     * that action (which should usually be one).  The SparseArray is keyed
699     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
700     * for stickies that are sent to all users.
701     */
702    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
703            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
704
705    final ActiveServices mServices;
706
707    /**
708     * Backup/restore process management
709     */
710    String mBackupAppName = null;
711    BackupRecord mBackupTarget = null;
712
713    final ProviderMap mProviderMap;
714
715    /**
716     * List of content providers who have clients waiting for them.  The
717     * application is currently being launched and the provider will be
718     * removed from this list once it is published.
719     */
720    final ArrayList<ContentProviderRecord> mLaunchingProviders
721            = new ArrayList<ContentProviderRecord>();
722
723    /**
724     * File storing persisted {@link #mGrantedUriPermissions}.
725     */
726    private final AtomicFile mGrantFile;
727
728    /** XML constants used in {@link #mGrantFile} */
729    private static final String TAG_URI_GRANTS = "uri-grants";
730    private static final String TAG_URI_GRANT = "uri-grant";
731    private static final String ATTR_USER_HANDLE = "userHandle";
732    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
733    private static final String ATTR_TARGET_USER_ID = "targetUserId";
734    private static final String ATTR_SOURCE_PKG = "sourcePkg";
735    private static final String ATTR_TARGET_PKG = "targetPkg";
736    private static final String ATTR_URI = "uri";
737    private static final String ATTR_MODE_FLAGS = "modeFlags";
738    private static final String ATTR_CREATED_TIME = "createdTime";
739    private static final String ATTR_PREFIX = "prefix";
740
741    /**
742     * Global set of specific {@link Uri} permissions that have been granted.
743     * This optimized lookup structure maps from {@link UriPermission#targetUid}
744     * to {@link UriPermission#uri} to {@link UriPermission}.
745     */
746    @GuardedBy("this")
747    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
748            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
749
750    public static class GrantUri {
751        public final int sourceUserId;
752        public final Uri uri;
753        public boolean prefix;
754
755        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
756            this.sourceUserId = sourceUserId;
757            this.uri = uri;
758            this.prefix = prefix;
759        }
760
761        @Override
762        public int hashCode() {
763            return toString().hashCode();
764        }
765
766        @Override
767        public boolean equals(Object o) {
768            if (o instanceof GrantUri) {
769                GrantUri other = (GrantUri) o;
770                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
771                        && prefix == other.prefix;
772            }
773            return false;
774        }
775
776        @Override
777        public String toString() {
778            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
779            if (prefix) result += " [prefix]";
780            return result;
781        }
782
783        public String toSafeString() {
784            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
785            if (prefix) result += " [prefix]";
786            return result;
787        }
788
789        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
790            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
791                    ContentProvider.getUriWithoutUserId(uri), false);
792        }
793    }
794
795    CoreSettingsObserver mCoreSettingsObserver;
796
797    /**
798     * Thread-local storage used to carry caller permissions over through
799     * indirect content-provider access.
800     */
801    private class Identity {
802        public int pid;
803        public int uid;
804
805        Identity(int _pid, int _uid) {
806            pid = _pid;
807            uid = _uid;
808        }
809    }
810
811    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
812
813    /**
814     * All information we have collected about the runtime performance of
815     * any user id that can impact battery performance.
816     */
817    final BatteryStatsService mBatteryStatsService;
818
819    /**
820     * Information about component usage
821     */
822    UsageStatsManagerInternal mUsageStatsService;
823
824    /**
825     * Information about and control over application operations
826     */
827    final AppOpsService mAppOpsService;
828
829    /**
830     * Save recent tasks information across reboots.
831     */
832    final TaskPersister mTaskPersister;
833
834    /**
835     * Current configuration information.  HistoryRecord objects are given
836     * a reference to this object to indicate which configuration they are
837     * currently running in, so this object must be kept immutable.
838     */
839    Configuration mConfiguration = new Configuration();
840
841    /**
842     * Current sequencing integer of the configuration, for skipping old
843     * configurations.
844     */
845    int mConfigurationSeq = 0;
846
847    /**
848     * Hardware-reported OpenGLES version.
849     */
850    final int GL_ES_VERSION;
851
852    /**
853     * List of initialization arguments to pass to all processes when binding applications to them.
854     * For example, references to the commonly used services.
855     */
856    HashMap<String, IBinder> mAppBindArgs;
857
858    /**
859     * Temporary to avoid allocations.  Protected by main lock.
860     */
861    final StringBuilder mStringBuilder = new StringBuilder(256);
862
863    /**
864     * Used to control how we initialize the service.
865     */
866    ComponentName mTopComponent;
867    String mTopAction = Intent.ACTION_MAIN;
868    String mTopData;
869    boolean mProcessesReady = false;
870    boolean mSystemReady = false;
871    boolean mBooting = false;
872    boolean mWaitingUpdate = false;
873    boolean mDidUpdate = false;
874    boolean mOnBattery = false;
875    boolean mLaunchWarningShown = false;
876
877    Context mContext;
878
879    int mFactoryTest;
880
881    boolean mCheckedForSetup;
882
883    /**
884     * The time at which we will allow normal application switches again,
885     * after a call to {@link #stopAppSwitches()}.
886     */
887    long mAppSwitchesAllowedTime;
888
889    /**
890     * This is set to true after the first switch after mAppSwitchesAllowedTime
891     * is set; any switches after that will clear the time.
892     */
893    boolean mDidAppSwitch;
894
895    /**
896     * Last time (in realtime) at which we checked for power usage.
897     */
898    long mLastPowerCheckRealtime;
899
900    /**
901     * Last time (in uptime) at which we checked for power usage.
902     */
903    long mLastPowerCheckUptime;
904
905    /**
906     * Set while we are wanting to sleep, to prevent any
907     * activities from being started/resumed.
908     */
909    private boolean mSleeping = false;
910
911    /**
912     * Set while we are running a voice interaction.  This overrides
913     * sleeping while it is active.
914     */
915    private boolean mRunningVoice = false;
916
917    /**
918     * State of external calls telling us if the device is asleep.
919     */
920    private boolean mWentToSleep = false;
921
922    /**
923     * State of external call telling us if the lock screen is shown.
924     */
925    private boolean mLockScreenShown = false;
926
927    /**
928     * Set if we are shutting down the system, similar to sleeping.
929     */
930    boolean mShuttingDown = false;
931
932    /**
933     * Current sequence id for oom_adj computation traversal.
934     */
935    int mAdjSeq = 0;
936
937    /**
938     * Current sequence id for process LRU updating.
939     */
940    int mLruSeq = 0;
941
942    /**
943     * Keep track of the non-cached/empty process we last found, to help
944     * determine how to distribute cached/empty processes next time.
945     */
946    int mNumNonCachedProcs = 0;
947
948    /**
949     * Keep track of the number of cached hidden procs, to balance oom adj
950     * distribution between those and empty procs.
951     */
952    int mNumCachedHiddenProcs = 0;
953
954    /**
955     * Keep track of the number of service processes we last found, to
956     * determine on the next iteration which should be B services.
957     */
958    int mNumServiceProcs = 0;
959    int mNewNumAServiceProcs = 0;
960    int mNewNumServiceProcs = 0;
961
962    /**
963     * Allow the current computed overall memory level of the system to go down?
964     * This is set to false when we are killing processes for reasons other than
965     * memory management, so that the now smaller process list will not be taken as
966     * an indication that memory is tighter.
967     */
968    boolean mAllowLowerMemLevel = false;
969
970    /**
971     * The last computed memory level, for holding when we are in a state that
972     * processes are going away for other reasons.
973     */
974    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
975
976    /**
977     * The last total number of process we have, to determine if changes actually look
978     * like a shrinking number of process due to lower RAM.
979     */
980    int mLastNumProcesses;
981
982    /**
983     * The uptime of the last time we performed idle maintenance.
984     */
985    long mLastIdleTime = SystemClock.uptimeMillis();
986
987    /**
988     * Total time spent with RAM that has been added in the past since the last idle time.
989     */
990    long mLowRamTimeSinceLastIdle = 0;
991
992    /**
993     * If RAM is currently low, when that horrible situation started.
994     */
995    long mLowRamStartTime = 0;
996
997    /**
998     * For reporting to battery stats the current top application.
999     */
1000    private String mCurResumedPackage = null;
1001    private int mCurResumedUid = -1;
1002
1003    /**
1004     * For reporting to battery stats the apps currently running foreground
1005     * service.  The ProcessMap is package/uid tuples; each of these contain
1006     * an array of the currently foreground processes.
1007     */
1008    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1009            = new ProcessMap<ArrayList<ProcessRecord>>();
1010
1011    /**
1012     * This is set if we had to do a delayed dexopt of an app before launching
1013     * it, to increase the ANR timeouts in that case.
1014     */
1015    boolean mDidDexOpt;
1016
1017    /**
1018     * Set if the systemServer made a call to enterSafeMode.
1019     */
1020    boolean mSafeMode;
1021
1022    String mDebugApp = null;
1023    boolean mWaitForDebugger = false;
1024    boolean mDebugTransient = false;
1025    String mOrigDebugApp = null;
1026    boolean mOrigWaitForDebugger = false;
1027    boolean mAlwaysFinishActivities = false;
1028    IActivityController mController = null;
1029    String mProfileApp = null;
1030    ProcessRecord mProfileProc = null;
1031    String mProfileFile;
1032    ParcelFileDescriptor mProfileFd;
1033    int mProfileType = 0;
1034    boolean mAutoStopProfiler = false;
1035    String mOpenGlTraceApp = null;
1036
1037    static class ProcessChangeItem {
1038        static final int CHANGE_ACTIVITIES = 1<<0;
1039        static final int CHANGE_PROCESS_STATE = 1<<1;
1040        int changes;
1041        int uid;
1042        int pid;
1043        int processState;
1044        boolean foregroundActivities;
1045    }
1046
1047    final RemoteCallbackList<IProcessObserver> mProcessObservers
1048            = new RemoteCallbackList<IProcessObserver>();
1049    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1050
1051    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1052            = new ArrayList<ProcessChangeItem>();
1053    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1054            = new ArrayList<ProcessChangeItem>();
1055
1056    /**
1057     * Runtime CPU use collection thread.  This object's lock is used to
1058     * protect all related state.
1059     */
1060    final Thread mProcessCpuThread;
1061
1062    /**
1063     * Used to collect process stats when showing not responding dialog.
1064     * Protected by mProcessCpuThread.
1065     */
1066    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1067            MONITOR_THREAD_CPU_USAGE);
1068    final AtomicLong mLastCpuTime = new AtomicLong(0);
1069    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1070
1071    long mLastWriteTime = 0;
1072
1073    /**
1074     * Used to retain an update lock when the foreground activity is in
1075     * immersive mode.
1076     */
1077    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1078
1079    /**
1080     * Set to true after the system has finished booting.
1081     */
1082    boolean mBooted = false;
1083
1084    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1085    int mProcessLimitOverride = -1;
1086
1087    WindowManagerService mWindowManager;
1088
1089    final ActivityThread mSystemThread;
1090
1091    int mCurrentUserId = 0;
1092    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1093
1094    /**
1095     * Mapping from each known user ID to the profile group ID it is associated with.
1096     */
1097    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1098
1099    private UserManagerService mUserManager;
1100
1101    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1102        final ProcessRecord mApp;
1103        final int mPid;
1104        final IApplicationThread mAppThread;
1105
1106        AppDeathRecipient(ProcessRecord app, int pid,
1107                IApplicationThread thread) {
1108            if (localLOGV) Slog.v(
1109                TAG, "New death recipient " + this
1110                + " for thread " + thread.asBinder());
1111            mApp = app;
1112            mPid = pid;
1113            mAppThread = thread;
1114        }
1115
1116        @Override
1117        public void binderDied() {
1118            if (localLOGV) Slog.v(
1119                TAG, "Death received in " + this
1120                + " for thread " + mAppThread.asBinder());
1121            synchronized(ActivityManagerService.this) {
1122                appDiedLocked(mApp, mPid, mAppThread);
1123            }
1124        }
1125    }
1126
1127    static final int SHOW_ERROR_MSG = 1;
1128    static final int SHOW_NOT_RESPONDING_MSG = 2;
1129    static final int SHOW_FACTORY_ERROR_MSG = 3;
1130    static final int UPDATE_CONFIGURATION_MSG = 4;
1131    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1132    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1133    static final int SERVICE_TIMEOUT_MSG = 12;
1134    static final int UPDATE_TIME_ZONE = 13;
1135    static final int SHOW_UID_ERROR_MSG = 14;
1136    static final int IM_FEELING_LUCKY_MSG = 15;
1137    static final int PROC_START_TIMEOUT_MSG = 20;
1138    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1139    static final int KILL_APPLICATION_MSG = 22;
1140    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1141    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1142    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1143    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1144    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1145    static final int CLEAR_DNS_CACHE_MSG = 28;
1146    static final int UPDATE_HTTP_PROXY_MSG = 29;
1147    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1148    static final int DISPATCH_PROCESSES_CHANGED = 31;
1149    static final int DISPATCH_PROCESS_DIED = 32;
1150    static final int REPORT_MEM_USAGE_MSG = 33;
1151    static final int REPORT_USER_SWITCH_MSG = 34;
1152    static final int CONTINUE_USER_SWITCH_MSG = 35;
1153    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1154    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1155    static final int PERSIST_URI_GRANTS_MSG = 38;
1156    static final int REQUEST_ALL_PSS_MSG = 39;
1157    static final int START_PROFILES_MSG = 40;
1158    static final int UPDATE_TIME = 41;
1159    static final int SYSTEM_USER_START_MSG = 42;
1160    static final int SYSTEM_USER_CURRENT_MSG = 43;
1161    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1162    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1163
1164    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1165    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1166    static final int FIRST_COMPAT_MODE_MSG = 300;
1167    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1168
1169    AlertDialog mUidAlert;
1170    CompatModeDialog mCompatModeDialog;
1171    long mLastMemUsageReportTime = 0;
1172
1173    private LockToAppRequestDialog mLockToAppRequest;
1174
1175    /**
1176     * Flag whether the current user is a "monkey", i.e. whether
1177     * the UI is driven by a UI automation tool.
1178     */
1179    private boolean mUserIsMonkey;
1180
1181    /** Flag whether the device has a recents UI */
1182    final boolean mHasRecents;
1183
1184    final ServiceThread mHandlerThread;
1185    final MainHandler mHandler;
1186
1187    final class MainHandler extends Handler {
1188        public MainHandler(Looper looper) {
1189            super(looper, null, true);
1190        }
1191
1192        @Override
1193        public void handleMessage(Message msg) {
1194            switch (msg.what) {
1195            case SHOW_ERROR_MSG: {
1196                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1197                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1198                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1199                synchronized (ActivityManagerService.this) {
1200                    ProcessRecord proc = (ProcessRecord)data.get("app");
1201                    AppErrorResult res = (AppErrorResult) data.get("result");
1202                    if (proc != null && proc.crashDialog != null) {
1203                        Slog.e(TAG, "App already has crash dialog: " + proc);
1204                        if (res != null) {
1205                            res.set(0);
1206                        }
1207                        return;
1208                    }
1209                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1210                            >= Process.FIRST_APPLICATION_UID
1211                            && proc.pid != MY_PID);
1212                    for (int userId : mCurrentProfileIds) {
1213                        isBackground &= (proc.userId != userId);
1214                    }
1215                    if (isBackground && !showBackground) {
1216                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1217                        if (res != null) {
1218                            res.set(0);
1219                        }
1220                        return;
1221                    }
1222                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1223                        Dialog d = new AppErrorDialog(mContext,
1224                                ActivityManagerService.this, res, proc);
1225                        d.show();
1226                        proc.crashDialog = d;
1227                    } else {
1228                        // The device is asleep, so just pretend that the user
1229                        // saw a crash dialog and hit "force quit".
1230                        if (res != null) {
1231                            res.set(0);
1232                        }
1233                    }
1234                }
1235
1236                ensureBootCompleted();
1237            } break;
1238            case SHOW_NOT_RESPONDING_MSG: {
1239                synchronized (ActivityManagerService.this) {
1240                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1241                    ProcessRecord proc = (ProcessRecord)data.get("app");
1242                    if (proc != null && proc.anrDialog != null) {
1243                        Slog.e(TAG, "App already has anr dialog: " + proc);
1244                        return;
1245                    }
1246
1247                    Intent intent = new Intent("android.intent.action.ANR");
1248                    if (!mProcessesReady) {
1249                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1250                                | Intent.FLAG_RECEIVER_FOREGROUND);
1251                    }
1252                    broadcastIntentLocked(null, null, intent,
1253                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1254                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1255
1256                    if (mShowDialogs) {
1257                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1258                                mContext, proc, (ActivityRecord)data.get("activity"),
1259                                msg.arg1 != 0);
1260                        d.show();
1261                        proc.anrDialog = d;
1262                    } else {
1263                        // Just kill the app if there is no dialog to be shown.
1264                        killAppAtUsersRequest(proc, null);
1265                    }
1266                }
1267
1268                ensureBootCompleted();
1269            } break;
1270            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1271                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1272                synchronized (ActivityManagerService.this) {
1273                    ProcessRecord proc = (ProcessRecord) data.get("app");
1274                    if (proc == null) {
1275                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1276                        break;
1277                    }
1278                    if (proc.crashDialog != null) {
1279                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1280                        return;
1281                    }
1282                    AppErrorResult res = (AppErrorResult) data.get("result");
1283                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1284                        Dialog d = new StrictModeViolationDialog(mContext,
1285                                ActivityManagerService.this, res, proc);
1286                        d.show();
1287                        proc.crashDialog = d;
1288                    } else {
1289                        // The device is asleep, so just pretend that the user
1290                        // saw a crash dialog and hit "force quit".
1291                        res.set(0);
1292                    }
1293                }
1294                ensureBootCompleted();
1295            } break;
1296            case SHOW_FACTORY_ERROR_MSG: {
1297                Dialog d = new FactoryErrorDialog(
1298                    mContext, msg.getData().getCharSequence("msg"));
1299                d.show();
1300                ensureBootCompleted();
1301            } break;
1302            case UPDATE_CONFIGURATION_MSG: {
1303                final ContentResolver resolver = mContext.getContentResolver();
1304                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1305            } break;
1306            case GC_BACKGROUND_PROCESSES_MSG: {
1307                synchronized (ActivityManagerService.this) {
1308                    performAppGcsIfAppropriateLocked();
1309                }
1310            } break;
1311            case WAIT_FOR_DEBUGGER_MSG: {
1312                synchronized (ActivityManagerService.this) {
1313                    ProcessRecord app = (ProcessRecord)msg.obj;
1314                    if (msg.arg1 != 0) {
1315                        if (!app.waitedForDebugger) {
1316                            Dialog d = new AppWaitingForDebuggerDialog(
1317                                    ActivityManagerService.this,
1318                                    mContext, app);
1319                            app.waitDialog = d;
1320                            app.waitedForDebugger = true;
1321                            d.show();
1322                        }
1323                    } else {
1324                        if (app.waitDialog != null) {
1325                            app.waitDialog.dismiss();
1326                            app.waitDialog = null;
1327                        }
1328                    }
1329                }
1330            } break;
1331            case SERVICE_TIMEOUT_MSG: {
1332                if (mDidDexOpt) {
1333                    mDidDexOpt = false;
1334                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1335                    nmsg.obj = msg.obj;
1336                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1337                    return;
1338                }
1339                mServices.serviceTimeout((ProcessRecord)msg.obj);
1340            } break;
1341            case UPDATE_TIME_ZONE: {
1342                synchronized (ActivityManagerService.this) {
1343                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1344                        ProcessRecord r = mLruProcesses.get(i);
1345                        if (r.thread != null) {
1346                            try {
1347                                r.thread.updateTimeZone();
1348                            } catch (RemoteException ex) {
1349                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1350                            }
1351                        }
1352                    }
1353                }
1354            } break;
1355            case CLEAR_DNS_CACHE_MSG: {
1356                synchronized (ActivityManagerService.this) {
1357                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1358                        ProcessRecord r = mLruProcesses.get(i);
1359                        if (r.thread != null) {
1360                            try {
1361                                r.thread.clearDnsCache();
1362                            } catch (RemoteException ex) {
1363                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1364                            }
1365                        }
1366                    }
1367                }
1368            } break;
1369            case UPDATE_HTTP_PROXY_MSG: {
1370                ProxyInfo proxy = (ProxyInfo)msg.obj;
1371                String host = "";
1372                String port = "";
1373                String exclList = "";
1374                Uri pacFileUrl = Uri.EMPTY;
1375                if (proxy != null) {
1376                    host = proxy.getHost();
1377                    port = Integer.toString(proxy.getPort());
1378                    exclList = proxy.getExclusionListAsString();
1379                    pacFileUrl = proxy.getPacFileUrl();
1380                }
1381                synchronized (ActivityManagerService.this) {
1382                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1383                        ProcessRecord r = mLruProcesses.get(i);
1384                        if (r.thread != null) {
1385                            try {
1386                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1387                            } catch (RemoteException ex) {
1388                                Slog.w(TAG, "Failed to update http proxy for: " +
1389                                        r.info.processName);
1390                            }
1391                        }
1392                    }
1393                }
1394            } break;
1395            case SHOW_UID_ERROR_MSG: {
1396                String title = "System UIDs Inconsistent";
1397                String text = "UIDs on the system are inconsistent, you need to wipe your"
1398                        + " data partition or your device will be unstable.";
1399                Log.e(TAG, title + ": " + text);
1400                if (mShowDialogs) {
1401                    // XXX This is a temporary dialog, no need to localize.
1402                    AlertDialog d = new BaseErrorDialog(mContext);
1403                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1404                    d.setCancelable(false);
1405                    d.setTitle(title);
1406                    d.setMessage(text);
1407                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1408                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1409                    mUidAlert = d;
1410                    d.show();
1411                }
1412            } break;
1413            case IM_FEELING_LUCKY_MSG: {
1414                if (mUidAlert != null) {
1415                    mUidAlert.dismiss();
1416                    mUidAlert = null;
1417                }
1418            } break;
1419            case PROC_START_TIMEOUT_MSG: {
1420                if (mDidDexOpt) {
1421                    mDidDexOpt = false;
1422                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1423                    nmsg.obj = msg.obj;
1424                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1425                    return;
1426                }
1427                ProcessRecord app = (ProcessRecord)msg.obj;
1428                synchronized (ActivityManagerService.this) {
1429                    processStartTimedOutLocked(app);
1430                }
1431            } break;
1432            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1433                synchronized (ActivityManagerService.this) {
1434                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1435                }
1436            } break;
1437            case KILL_APPLICATION_MSG: {
1438                synchronized (ActivityManagerService.this) {
1439                    int appid = msg.arg1;
1440                    boolean restart = (msg.arg2 == 1);
1441                    Bundle bundle = (Bundle)msg.obj;
1442                    String pkg = bundle.getString("pkg");
1443                    String reason = bundle.getString("reason");
1444                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1445                            false, UserHandle.USER_ALL, reason);
1446                }
1447            } break;
1448            case FINALIZE_PENDING_INTENT_MSG: {
1449                ((PendingIntentRecord)msg.obj).completeFinalize();
1450            } break;
1451            case POST_HEAVY_NOTIFICATION_MSG: {
1452                INotificationManager inm = NotificationManager.getService();
1453                if (inm == null) {
1454                    return;
1455                }
1456
1457                ActivityRecord root = (ActivityRecord)msg.obj;
1458                ProcessRecord process = root.app;
1459                if (process == null) {
1460                    return;
1461                }
1462
1463                try {
1464                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1465                    String text = mContext.getString(R.string.heavy_weight_notification,
1466                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1467                    Notification notification = new Notification();
1468                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1469                    notification.when = 0;
1470                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1471                    notification.tickerText = text;
1472                    notification.defaults = 0; // please be quiet
1473                    notification.sound = null;
1474                    notification.vibrate = null;
1475                    notification.setLatestEventInfo(context, text,
1476                            mContext.getText(R.string.heavy_weight_notification_detail),
1477                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1478                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1479                                    new UserHandle(root.userId)));
1480
1481                    try {
1482                        int[] outId = new int[1];
1483                        inm.enqueueNotificationWithTag("android", "android", null,
1484                                R.string.heavy_weight_notification,
1485                                notification, outId, root.userId);
1486                    } catch (RuntimeException e) {
1487                        Slog.w(ActivityManagerService.TAG,
1488                                "Error showing notification for heavy-weight app", e);
1489                    } catch (RemoteException e) {
1490                    }
1491                } catch (NameNotFoundException e) {
1492                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1493                }
1494            } break;
1495            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1496                INotificationManager inm = NotificationManager.getService();
1497                if (inm == null) {
1498                    return;
1499                }
1500                try {
1501                    inm.cancelNotificationWithTag("android", null,
1502                            R.string.heavy_weight_notification,  msg.arg1);
1503                } catch (RuntimeException e) {
1504                    Slog.w(ActivityManagerService.TAG,
1505                            "Error canceling notification for service", e);
1506                } catch (RemoteException e) {
1507                }
1508            } break;
1509            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1510                synchronized (ActivityManagerService.this) {
1511                    checkExcessivePowerUsageLocked(true);
1512                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1513                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1514                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1515                }
1516            } break;
1517            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1518                synchronized (ActivityManagerService.this) {
1519                    ActivityRecord ar = (ActivityRecord)msg.obj;
1520                    if (mCompatModeDialog != null) {
1521                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1522                                ar.info.applicationInfo.packageName)) {
1523                            return;
1524                        }
1525                        mCompatModeDialog.dismiss();
1526                        mCompatModeDialog = null;
1527                    }
1528                    if (ar != null && false) {
1529                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1530                                ar.packageName)) {
1531                            int mode = mCompatModePackages.computeCompatModeLocked(
1532                                    ar.info.applicationInfo);
1533                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1534                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1535                                mCompatModeDialog = new CompatModeDialog(
1536                                        ActivityManagerService.this, mContext,
1537                                        ar.info.applicationInfo);
1538                                mCompatModeDialog.show();
1539                            }
1540                        }
1541                    }
1542                }
1543                break;
1544            }
1545            case DISPATCH_PROCESSES_CHANGED: {
1546                dispatchProcessesChanged();
1547                break;
1548            }
1549            case DISPATCH_PROCESS_DIED: {
1550                final int pid = msg.arg1;
1551                final int uid = msg.arg2;
1552                dispatchProcessDied(pid, uid);
1553                break;
1554            }
1555            case REPORT_MEM_USAGE_MSG: {
1556                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1557                Thread thread = new Thread() {
1558                    @Override public void run() {
1559                        final SparseArray<ProcessMemInfo> infoMap
1560                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1561                        for (int i=0, N=memInfos.size(); i<N; i++) {
1562                            ProcessMemInfo mi = memInfos.get(i);
1563                            infoMap.put(mi.pid, mi);
1564                        }
1565                        updateCpuStatsNow();
1566                        synchronized (mProcessCpuThread) {
1567                            final int N = mProcessCpuTracker.countStats();
1568                            for (int i=0; i<N; i++) {
1569                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1570                                if (st.vsize > 0) {
1571                                    long pss = Debug.getPss(st.pid, null);
1572                                    if (pss > 0) {
1573                                        if (infoMap.indexOfKey(st.pid) < 0) {
1574                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1575                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1576                                            mi.pss = pss;
1577                                            memInfos.add(mi);
1578                                        }
1579                                    }
1580                                }
1581                            }
1582                        }
1583
1584                        long totalPss = 0;
1585                        for (int i=0, N=memInfos.size(); i<N; i++) {
1586                            ProcessMemInfo mi = memInfos.get(i);
1587                            if (mi.pss == 0) {
1588                                mi.pss = Debug.getPss(mi.pid, null);
1589                            }
1590                            totalPss += mi.pss;
1591                        }
1592                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1593                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1594                                if (lhs.oomAdj != rhs.oomAdj) {
1595                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1596                                }
1597                                if (lhs.pss != rhs.pss) {
1598                                    return lhs.pss < rhs.pss ? 1 : -1;
1599                                }
1600                                return 0;
1601                            }
1602                        });
1603
1604                        StringBuilder tag = new StringBuilder(128);
1605                        StringBuilder stack = new StringBuilder(128);
1606                        tag.append("Low on memory -- ");
1607                        appendMemBucket(tag, totalPss, "total", false);
1608                        appendMemBucket(stack, totalPss, "total", true);
1609
1610                        StringBuilder logBuilder = new StringBuilder(1024);
1611                        logBuilder.append("Low on memory:\n");
1612
1613                        boolean firstLine = true;
1614                        int lastOomAdj = Integer.MIN_VALUE;
1615                        for (int i=0, N=memInfos.size(); i<N; i++) {
1616                            ProcessMemInfo mi = memInfos.get(i);
1617
1618                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1619                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1620                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1621                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1622                                if (lastOomAdj != mi.oomAdj) {
1623                                    lastOomAdj = mi.oomAdj;
1624                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1625                                        tag.append(" / ");
1626                                    }
1627                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1628                                        if (firstLine) {
1629                                            stack.append(":");
1630                                            firstLine = false;
1631                                        }
1632                                        stack.append("\n\t at ");
1633                                    } else {
1634                                        stack.append("$");
1635                                    }
1636                                } else {
1637                                    tag.append(" ");
1638                                    stack.append("$");
1639                                }
1640                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1641                                    appendMemBucket(tag, mi.pss, mi.name, false);
1642                                }
1643                                appendMemBucket(stack, mi.pss, mi.name, true);
1644                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1645                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1646                                    stack.append("(");
1647                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1648                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1649                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1650                                            stack.append(":");
1651                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1652                                        }
1653                                    }
1654                                    stack.append(")");
1655                                }
1656                            }
1657
1658                            logBuilder.append("  ");
1659                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1660                            logBuilder.append(' ');
1661                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1662                            logBuilder.append(' ');
1663                            ProcessList.appendRamKb(logBuilder, mi.pss);
1664                            logBuilder.append(" kB: ");
1665                            logBuilder.append(mi.name);
1666                            logBuilder.append(" (");
1667                            logBuilder.append(mi.pid);
1668                            logBuilder.append(") ");
1669                            logBuilder.append(mi.adjType);
1670                            logBuilder.append('\n');
1671                            if (mi.adjReason != null) {
1672                                logBuilder.append("                      ");
1673                                logBuilder.append(mi.adjReason);
1674                                logBuilder.append('\n');
1675                            }
1676                        }
1677
1678                        logBuilder.append("           ");
1679                        ProcessList.appendRamKb(logBuilder, totalPss);
1680                        logBuilder.append(" kB: TOTAL\n");
1681
1682                        long[] infos = new long[Debug.MEMINFO_COUNT];
1683                        Debug.getMemInfo(infos);
1684                        logBuilder.append("  MemInfo: ");
1685                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1686                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1687                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1688                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1689                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1690                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1691                            logBuilder.append("  ZRAM: ");
1692                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1693                            logBuilder.append(" kB RAM, ");
1694                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1695                            logBuilder.append(" kB swap total, ");
1696                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1697                            logBuilder.append(" kB swap free\n");
1698                        }
1699                        Slog.i(TAG, logBuilder.toString());
1700
1701                        StringBuilder dropBuilder = new StringBuilder(1024);
1702                        /*
1703                        StringWriter oomSw = new StringWriter();
1704                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1705                        StringWriter catSw = new StringWriter();
1706                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1707                        String[] emptyArgs = new String[] { };
1708                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1709                        oomPw.flush();
1710                        String oomString = oomSw.toString();
1711                        */
1712                        dropBuilder.append(stack);
1713                        dropBuilder.append('\n');
1714                        dropBuilder.append('\n');
1715                        dropBuilder.append(logBuilder);
1716                        dropBuilder.append('\n');
1717                        /*
1718                        dropBuilder.append(oomString);
1719                        dropBuilder.append('\n');
1720                        */
1721                        StringWriter catSw = new StringWriter();
1722                        synchronized (ActivityManagerService.this) {
1723                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1724                            String[] emptyArgs = new String[] { };
1725                            catPw.println();
1726                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1727                            catPw.println();
1728                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1729                                    false, false, null);
1730                            catPw.println();
1731                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1732                            catPw.flush();
1733                        }
1734                        dropBuilder.append(catSw.toString());
1735                        addErrorToDropBox("lowmem", null, "system_server", null,
1736                                null, tag.toString(), dropBuilder.toString(), null, null);
1737                        //Slog.i(TAG, "Sent to dropbox:");
1738                        //Slog.i(TAG, dropBuilder.toString());
1739                        synchronized (ActivityManagerService.this) {
1740                            long now = SystemClock.uptimeMillis();
1741                            if (mLastMemUsageReportTime < now) {
1742                                mLastMemUsageReportTime = now;
1743                            }
1744                        }
1745                    }
1746                };
1747                thread.start();
1748                break;
1749            }
1750            case REPORT_USER_SWITCH_MSG: {
1751                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1752                break;
1753            }
1754            case CONTINUE_USER_SWITCH_MSG: {
1755                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1756                break;
1757            }
1758            case USER_SWITCH_TIMEOUT_MSG: {
1759                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1760                break;
1761            }
1762            case IMMERSIVE_MODE_LOCK_MSG: {
1763                final boolean nextState = (msg.arg1 != 0);
1764                if (mUpdateLock.isHeld() != nextState) {
1765                    if (DEBUG_IMMERSIVE) {
1766                        final ActivityRecord r = (ActivityRecord) msg.obj;
1767                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1768                    }
1769                    if (nextState) {
1770                        mUpdateLock.acquire();
1771                    } else {
1772                        mUpdateLock.release();
1773                    }
1774                }
1775                break;
1776            }
1777            case PERSIST_URI_GRANTS_MSG: {
1778                writeGrantedUriPermissions();
1779                break;
1780            }
1781            case REQUEST_ALL_PSS_MSG: {
1782                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1783                break;
1784            }
1785            case START_PROFILES_MSG: {
1786                synchronized (ActivityManagerService.this) {
1787                    startProfilesLocked();
1788                }
1789                break;
1790            }
1791            case UPDATE_TIME: {
1792                synchronized (ActivityManagerService.this) {
1793                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1794                        ProcessRecord r = mLruProcesses.get(i);
1795                        if (r.thread != null) {
1796                            try {
1797                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1798                            } catch (RemoteException ex) {
1799                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1800                            }
1801                        }
1802                    }
1803                }
1804                break;
1805            }
1806            case SYSTEM_USER_START_MSG: {
1807                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1808                        Integer.toString(msg.arg1), msg.arg1);
1809                mSystemServiceManager.startUser(msg.arg1);
1810                break;
1811            }
1812            case SYSTEM_USER_CURRENT_MSG: {
1813                mBatteryStatsService.noteEvent(
1814                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1815                        Integer.toString(msg.arg2), msg.arg2);
1816                mBatteryStatsService.noteEvent(
1817                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1818                        Integer.toString(msg.arg1), msg.arg1);
1819                mSystemServiceManager.switchUser(msg.arg1);
1820                break;
1821            }
1822            case ENTER_ANIMATION_COMPLETE_MSG: {
1823                synchronized (ActivityManagerService.this) {
1824                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1825                    if (r != null && r.app != null && r.app.thread != null) {
1826                        try {
1827                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1828                        } catch (RemoteException e) {
1829                        }
1830                    }
1831                }
1832                break;
1833            }
1834            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1835                enableScreenAfterBoot();
1836                break;
1837            }
1838            }
1839        }
1840    };
1841
1842    static final int COLLECT_PSS_BG_MSG = 1;
1843
1844    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1845        @Override
1846        public void handleMessage(Message msg) {
1847            switch (msg.what) {
1848            case COLLECT_PSS_BG_MSG: {
1849                long start = SystemClock.uptimeMillis();
1850                MemInfoReader memInfo = null;
1851                synchronized (ActivityManagerService.this) {
1852                    if (mFullPssPending) {
1853                        mFullPssPending = false;
1854                        memInfo = new MemInfoReader();
1855                    }
1856                }
1857                if (memInfo != null) {
1858                    updateCpuStatsNow();
1859                    long nativeTotalPss = 0;
1860                    synchronized (mProcessCpuThread) {
1861                        final int N = mProcessCpuTracker.countStats();
1862                        for (int j=0; j<N; j++) {
1863                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1864                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1865                                // This is definitely an application process; skip it.
1866                                continue;
1867                            }
1868                            synchronized (mPidsSelfLocked) {
1869                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1870                                    // This is one of our own processes; skip it.
1871                                    continue;
1872                                }
1873                            }
1874                            nativeTotalPss += Debug.getPss(st.pid, null);
1875                        }
1876                    }
1877                    memInfo.readMemInfo();
1878                    synchronized (this) {
1879                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1880                                + (SystemClock.uptimeMillis()-start) + "ms");
1881                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1882                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1883                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1884                                        +memInfo.getSlabSizeKb(),
1885                                nativeTotalPss);
1886                    }
1887                }
1888
1889                int i=0, num=0;
1890                long[] tmp = new long[1];
1891                do {
1892                    ProcessRecord proc;
1893                    int procState;
1894                    int pid;
1895                    synchronized (ActivityManagerService.this) {
1896                        if (i >= mPendingPssProcesses.size()) {
1897                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1898                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1899                            mPendingPssProcesses.clear();
1900                            return;
1901                        }
1902                        proc = mPendingPssProcesses.get(i);
1903                        procState = proc.pssProcState;
1904                        if (proc.thread != null && procState == proc.setProcState) {
1905                            pid = proc.pid;
1906                        } else {
1907                            proc = null;
1908                            pid = 0;
1909                        }
1910                        i++;
1911                    }
1912                    if (proc != null) {
1913                        long pss = Debug.getPss(pid, tmp);
1914                        synchronized (ActivityManagerService.this) {
1915                            if (proc.thread != null && proc.setProcState == procState
1916                                    && proc.pid == pid) {
1917                                num++;
1918                                proc.lastPssTime = SystemClock.uptimeMillis();
1919                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1920                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1921                                        + ": " + pss + " lastPss=" + proc.lastPss
1922                                        + " state=" + ProcessList.makeProcStateString(procState));
1923                                if (proc.initialIdlePss == 0) {
1924                                    proc.initialIdlePss = pss;
1925                                }
1926                                proc.lastPss = pss;
1927                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1928                                    proc.lastCachedPss = pss;
1929                                }
1930                            }
1931                        }
1932                    }
1933                } while (true);
1934            }
1935            }
1936        }
1937    };
1938
1939    /**
1940     * Monitor for package changes and update our internal state.
1941     */
1942    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1943        @Override
1944        public void onPackageRemoved(String packageName, int uid) {
1945            // Remove all tasks with activities in the specified package from the list of recent tasks
1946            synchronized (ActivityManagerService.this) {
1947                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1948                    TaskRecord tr = mRecentTasks.get(i);
1949                    ComponentName cn = tr.intent.getComponent();
1950                    if (cn != null && cn.getPackageName().equals(packageName)) {
1951                        // If the package name matches, remove the task and kill the process
1952                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1953                    }
1954                }
1955            }
1956        }
1957
1958        @Override
1959        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1960            onPackageModified(packageName);
1961            return true;
1962        }
1963
1964        @Override
1965        public void onPackageModified(String packageName) {
1966            final PackageManager pm = mContext.getPackageManager();
1967            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1968                    new ArrayList<Pair<Intent, Integer>>();
1969            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1970            // Copy the list of recent tasks so that we don't hold onto the lock on
1971            // ActivityManagerService for long periods while checking if components exist.
1972            synchronized (ActivityManagerService.this) {
1973                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1974                    TaskRecord tr = mRecentTasks.get(i);
1975                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1976                }
1977            }
1978            // Check the recent tasks and filter out all tasks with components that no longer exist.
1979            Intent tmpI = new Intent();
1980            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1981                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1982                ComponentName cn = p.first.getComponent();
1983                if (cn != null && cn.getPackageName().equals(packageName)) {
1984                    try {
1985                        // Add the task to the list to remove if the component no longer exists
1986                        tmpI.setComponent(cn);
1987                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1988                            tasksToRemove.add(p.second);
1989                        }
1990                    } catch (Exception e) {}
1991                }
1992            }
1993            // Prune all the tasks with removed components from the list of recent tasks
1994            synchronized (ActivityManagerService.this) {
1995                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1996                    // Remove the task but don't kill the process (since other components in that
1997                    // package may still be running and in the background)
1998                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1999                }
2000            }
2001        }
2002
2003        @Override
2004        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2005            // Force stop the specified packages
2006            if (packages != null) {
2007                for (String pkg : packages) {
2008                    synchronized (ActivityManagerService.this) {
2009                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2010                                "finished booting")) {
2011                            return true;
2012                        }
2013                    }
2014                }
2015            }
2016            return false;
2017        }
2018    };
2019
2020    public void setSystemProcess() {
2021        try {
2022            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2023            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2024            ServiceManager.addService("meminfo", new MemBinder(this));
2025            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2026            ServiceManager.addService("dbinfo", new DbBinder(this));
2027            if (MONITOR_CPU_USAGE) {
2028                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2029            }
2030            ServiceManager.addService("permission", new PermissionController(this));
2031
2032            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2033                    "android", STOCK_PM_FLAGS);
2034            mSystemThread.installSystemApplicationInfo(info);
2035
2036            synchronized (this) {
2037                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2038                app.persistent = true;
2039                app.pid = MY_PID;
2040                app.maxAdj = ProcessList.SYSTEM_ADJ;
2041                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2042                mProcessNames.put(app.processName, app.uid, app);
2043                synchronized (mPidsSelfLocked) {
2044                    mPidsSelfLocked.put(app.pid, app);
2045                }
2046                updateLruProcessLocked(app, false, null);
2047                updateOomAdjLocked();
2048            }
2049        } catch (PackageManager.NameNotFoundException e) {
2050            throw new RuntimeException(
2051                    "Unable to find android system package", e);
2052        }
2053    }
2054
2055    public void setWindowManager(WindowManagerService wm) {
2056        mWindowManager = wm;
2057        mStackSupervisor.setWindowManager(wm);
2058    }
2059
2060    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2061        mUsageStatsService = usageStatsManager;
2062    }
2063
2064    public void startObservingNativeCrashes() {
2065        final NativeCrashListener ncl = new NativeCrashListener(this);
2066        ncl.start();
2067    }
2068
2069    public IAppOpsService getAppOpsService() {
2070        return mAppOpsService;
2071    }
2072
2073    static class MemBinder extends Binder {
2074        ActivityManagerService mActivityManagerService;
2075        MemBinder(ActivityManagerService activityManagerService) {
2076            mActivityManagerService = activityManagerService;
2077        }
2078
2079        @Override
2080        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2081            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2082                    != PackageManager.PERMISSION_GRANTED) {
2083                pw.println("Permission Denial: can't dump meminfo from from pid="
2084                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2085                        + " without permission " + android.Manifest.permission.DUMP);
2086                return;
2087            }
2088
2089            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2090        }
2091    }
2092
2093    static class GraphicsBinder extends Binder {
2094        ActivityManagerService mActivityManagerService;
2095        GraphicsBinder(ActivityManagerService activityManagerService) {
2096            mActivityManagerService = activityManagerService;
2097        }
2098
2099        @Override
2100        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2101            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2102                    != PackageManager.PERMISSION_GRANTED) {
2103                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2104                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2105                        + " without permission " + android.Manifest.permission.DUMP);
2106                return;
2107            }
2108
2109            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2110        }
2111    }
2112
2113    static class DbBinder extends Binder {
2114        ActivityManagerService mActivityManagerService;
2115        DbBinder(ActivityManagerService activityManagerService) {
2116            mActivityManagerService = activityManagerService;
2117        }
2118
2119        @Override
2120        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2121            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2122                    != PackageManager.PERMISSION_GRANTED) {
2123                pw.println("Permission Denial: can't dump dbinfo from from pid="
2124                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2125                        + " without permission " + android.Manifest.permission.DUMP);
2126                return;
2127            }
2128
2129            mActivityManagerService.dumpDbInfo(fd, pw, args);
2130        }
2131    }
2132
2133    static class CpuBinder extends Binder {
2134        ActivityManagerService mActivityManagerService;
2135        CpuBinder(ActivityManagerService activityManagerService) {
2136            mActivityManagerService = activityManagerService;
2137        }
2138
2139        @Override
2140        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2141            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2142                    != PackageManager.PERMISSION_GRANTED) {
2143                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2144                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2145                        + " without permission " + android.Manifest.permission.DUMP);
2146                return;
2147            }
2148
2149            synchronized (mActivityManagerService.mProcessCpuThread) {
2150                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2151                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2152                        SystemClock.uptimeMillis()));
2153            }
2154        }
2155    }
2156
2157    public static final class Lifecycle extends SystemService {
2158        private final ActivityManagerService mService;
2159
2160        public Lifecycle(Context context) {
2161            super(context);
2162            mService = new ActivityManagerService(context);
2163        }
2164
2165        @Override
2166        public void onStart() {
2167            mService.start();
2168        }
2169
2170        public ActivityManagerService getService() {
2171            return mService;
2172        }
2173    }
2174
2175    // Note: This method is invoked on the main thread but may need to attach various
2176    // handlers to other threads.  So take care to be explicit about the looper.
2177    public ActivityManagerService(Context systemContext) {
2178        mContext = systemContext;
2179        mFactoryTest = FactoryTest.getMode();
2180        mSystemThread = ActivityThread.currentActivityThread();
2181
2182        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2183
2184        mHandlerThread = new ServiceThread(TAG,
2185                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2186        mHandlerThread.start();
2187        mHandler = new MainHandler(mHandlerThread.getLooper());
2188
2189        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2190                "foreground", BROADCAST_FG_TIMEOUT, false);
2191        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2192                "background", BROADCAST_BG_TIMEOUT, true);
2193        mBroadcastQueues[0] = mFgBroadcastQueue;
2194        mBroadcastQueues[1] = mBgBroadcastQueue;
2195
2196        mServices = new ActiveServices(this);
2197        mProviderMap = new ProviderMap(this);
2198
2199        // TODO: Move creation of battery stats service outside of activity manager service.
2200        File dataDir = Environment.getDataDirectory();
2201        File systemDir = new File(dataDir, "system");
2202        systemDir.mkdirs();
2203        mBatteryStatsService = new BatteryStatsService(new File(
2204                systemDir, "batterystats.bin").toString(), mHandler);
2205        mBatteryStatsService.getActiveStatistics().readLocked();
2206        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2207        mOnBattery = DEBUG_POWER ? true
2208                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2209        mBatteryStatsService.getActiveStatistics().setCallback(this);
2210
2211        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2212
2213        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2214
2215        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2216
2217        // User 0 is the first and only user that runs at boot.
2218        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2219        mUserLru.add(Integer.valueOf(0));
2220        updateStartedUserArrayLocked();
2221
2222        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2223            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2224
2225        mConfiguration.setToDefaults();
2226        mConfiguration.setLocale(Locale.getDefault());
2227
2228        mConfigurationSeq = mConfiguration.seq = 1;
2229        mProcessCpuTracker.init();
2230
2231        mHasRecents = mContext.getResources().getBoolean(
2232                com.android.internal.R.bool.config_hasRecents);
2233
2234        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2235        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2236        mStackSupervisor = new ActivityStackSupervisor(this);
2237        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2238
2239        mProcessCpuThread = new Thread("CpuTracker") {
2240            @Override
2241            public void run() {
2242                while (true) {
2243                    try {
2244                        try {
2245                            synchronized(this) {
2246                                final long now = SystemClock.uptimeMillis();
2247                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2248                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2249                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2250                                //        + ", write delay=" + nextWriteDelay);
2251                                if (nextWriteDelay < nextCpuDelay) {
2252                                    nextCpuDelay = nextWriteDelay;
2253                                }
2254                                if (nextCpuDelay > 0) {
2255                                    mProcessCpuMutexFree.set(true);
2256                                    this.wait(nextCpuDelay);
2257                                }
2258                            }
2259                        } catch (InterruptedException e) {
2260                        }
2261                        updateCpuStatsNow();
2262                    } catch (Exception e) {
2263                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2264                    }
2265                }
2266            }
2267        };
2268
2269        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2270
2271        Watchdog.getInstance().addMonitor(this);
2272        Watchdog.getInstance().addThread(mHandler);
2273    }
2274
2275    public void setSystemServiceManager(SystemServiceManager mgr) {
2276        mSystemServiceManager = mgr;
2277    }
2278
2279    private void start() {
2280        Process.removeAllProcessGroups();
2281        mProcessCpuThread.start();
2282
2283        mBatteryStatsService.publish(mContext);
2284        mAppOpsService.publish(mContext);
2285        Slog.d("AppOps", "AppOpsService published");
2286        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2287    }
2288
2289    public void initPowerManagement() {
2290        mStackSupervisor.initPowerManagement();
2291        mBatteryStatsService.initPowerManagement();
2292    }
2293
2294    @Override
2295    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2296            throws RemoteException {
2297        if (code == SYSPROPS_TRANSACTION) {
2298            // We need to tell all apps about the system property change.
2299            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2300            synchronized(this) {
2301                final int NP = mProcessNames.getMap().size();
2302                for (int ip=0; ip<NP; ip++) {
2303                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2304                    final int NA = apps.size();
2305                    for (int ia=0; ia<NA; ia++) {
2306                        ProcessRecord app = apps.valueAt(ia);
2307                        if (app.thread != null) {
2308                            procs.add(app.thread.asBinder());
2309                        }
2310                    }
2311                }
2312            }
2313
2314            int N = procs.size();
2315            for (int i=0; i<N; i++) {
2316                Parcel data2 = Parcel.obtain();
2317                try {
2318                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2319                } catch (RemoteException e) {
2320                }
2321                data2.recycle();
2322            }
2323        }
2324        try {
2325            return super.onTransact(code, data, reply, flags);
2326        } catch (RuntimeException e) {
2327            // The activity manager only throws security exceptions, so let's
2328            // log all others.
2329            if (!(e instanceof SecurityException)) {
2330                Slog.wtf(TAG, "Activity Manager Crash", e);
2331            }
2332            throw e;
2333        }
2334    }
2335
2336    void updateCpuStats() {
2337        final long now = SystemClock.uptimeMillis();
2338        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2339            return;
2340        }
2341        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2342            synchronized (mProcessCpuThread) {
2343                mProcessCpuThread.notify();
2344            }
2345        }
2346    }
2347
2348    void updateCpuStatsNow() {
2349        synchronized (mProcessCpuThread) {
2350            mProcessCpuMutexFree.set(false);
2351            final long now = SystemClock.uptimeMillis();
2352            boolean haveNewCpuStats = false;
2353
2354            if (MONITOR_CPU_USAGE &&
2355                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2356                mLastCpuTime.set(now);
2357                haveNewCpuStats = true;
2358                mProcessCpuTracker.update();
2359                //Slog.i(TAG, mProcessCpu.printCurrentState());
2360                //Slog.i(TAG, "Total CPU usage: "
2361                //        + mProcessCpu.getTotalCpuPercent() + "%");
2362
2363                // Slog the cpu usage if the property is set.
2364                if ("true".equals(SystemProperties.get("events.cpu"))) {
2365                    int user = mProcessCpuTracker.getLastUserTime();
2366                    int system = mProcessCpuTracker.getLastSystemTime();
2367                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2368                    int irq = mProcessCpuTracker.getLastIrqTime();
2369                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2370                    int idle = mProcessCpuTracker.getLastIdleTime();
2371
2372                    int total = user + system + iowait + irq + softIrq + idle;
2373                    if (total == 0) total = 1;
2374
2375                    EventLog.writeEvent(EventLogTags.CPU,
2376                            ((user+system+iowait+irq+softIrq) * 100) / total,
2377                            (user * 100) / total,
2378                            (system * 100) / total,
2379                            (iowait * 100) / total,
2380                            (irq * 100) / total,
2381                            (softIrq * 100) / total);
2382                }
2383            }
2384
2385            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2386            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2387            synchronized(bstats) {
2388                synchronized(mPidsSelfLocked) {
2389                    if (haveNewCpuStats) {
2390                        if (mOnBattery) {
2391                            int perc = bstats.startAddingCpuLocked();
2392                            int totalUTime = 0;
2393                            int totalSTime = 0;
2394                            final int N = mProcessCpuTracker.countStats();
2395                            for (int i=0; i<N; i++) {
2396                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2397                                if (!st.working) {
2398                                    continue;
2399                                }
2400                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2401                                int otherUTime = (st.rel_utime*perc)/100;
2402                                int otherSTime = (st.rel_stime*perc)/100;
2403                                totalUTime += otherUTime;
2404                                totalSTime += otherSTime;
2405                                if (pr != null) {
2406                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2407                                    if (ps == null || !ps.isActive()) {
2408                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2409                                                pr.info.uid, pr.processName);
2410                                    }
2411                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2412                                            st.rel_stime-otherSTime);
2413                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2414                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2415                                } else {
2416                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2417                                    if (ps == null || !ps.isActive()) {
2418                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2419                                                bstats.mapUid(st.uid), st.name);
2420                                    }
2421                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2422                                            st.rel_stime-otherSTime);
2423                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2424                                }
2425                            }
2426                            bstats.finishAddingCpuLocked(perc, totalUTime,
2427                                    totalSTime, cpuSpeedTimes);
2428                        }
2429                    }
2430                }
2431
2432                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2433                    mLastWriteTime = now;
2434                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2435                }
2436            }
2437        }
2438    }
2439
2440    @Override
2441    public void batteryNeedsCpuUpdate() {
2442        updateCpuStatsNow();
2443    }
2444
2445    @Override
2446    public void batteryPowerChanged(boolean onBattery) {
2447        // When plugging in, update the CPU stats first before changing
2448        // the plug state.
2449        updateCpuStatsNow();
2450        synchronized (this) {
2451            synchronized(mPidsSelfLocked) {
2452                mOnBattery = DEBUG_POWER ? true : onBattery;
2453            }
2454        }
2455    }
2456
2457    /**
2458     * Initialize the application bind args. These are passed to each
2459     * process when the bindApplication() IPC is sent to the process. They're
2460     * lazily setup to make sure the services are running when they're asked for.
2461     */
2462    private HashMap<String, IBinder> getCommonServicesLocked() {
2463        if (mAppBindArgs == null) {
2464            mAppBindArgs = new HashMap<String, IBinder>();
2465
2466            // Setup the application init args
2467            mAppBindArgs.put("package", ServiceManager.getService("package"));
2468            mAppBindArgs.put("window", ServiceManager.getService("window"));
2469            mAppBindArgs.put(Context.ALARM_SERVICE,
2470                    ServiceManager.getService(Context.ALARM_SERVICE));
2471        }
2472        return mAppBindArgs;
2473    }
2474
2475    final void setFocusedActivityLocked(ActivityRecord r) {
2476        if (mFocusedActivity != r) {
2477            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2478            mFocusedActivity = r;
2479            if (r.task != null && r.task.voiceInteractor != null) {
2480                startRunningVoiceLocked();
2481            } else {
2482                finishRunningVoiceLocked();
2483            }
2484            mStackSupervisor.setFocusedStack(r);
2485            if (r != null) {
2486                mWindowManager.setFocusedApp(r.appToken, true);
2487            }
2488            applyUpdateLockStateLocked(r);
2489        }
2490    }
2491
2492    final void clearFocusedActivity(ActivityRecord r) {
2493        if (mFocusedActivity == r) {
2494            mFocusedActivity = null;
2495        }
2496    }
2497
2498    @Override
2499    public void setFocusedStack(int stackId) {
2500        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2501        synchronized (ActivityManagerService.this) {
2502            ActivityStack stack = mStackSupervisor.getStack(stackId);
2503            if (stack != null) {
2504                ActivityRecord r = stack.topRunningActivityLocked(null);
2505                if (r != null) {
2506                    setFocusedActivityLocked(r);
2507                }
2508            }
2509        }
2510    }
2511
2512    @Override
2513    public void notifyActivityDrawn(IBinder token) {
2514        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2515        synchronized (this) {
2516            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2517            if (r != null) {
2518                r.task.stack.notifyActivityDrawnLocked(r);
2519            }
2520        }
2521    }
2522
2523    final void applyUpdateLockStateLocked(ActivityRecord r) {
2524        // Modifications to the UpdateLock state are done on our handler, outside
2525        // the activity manager's locks.  The new state is determined based on the
2526        // state *now* of the relevant activity record.  The object is passed to
2527        // the handler solely for logging detail, not to be consulted/modified.
2528        final boolean nextState = r != null && r.immersive;
2529        mHandler.sendMessage(
2530                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2531    }
2532
2533    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2534        Message msg = Message.obtain();
2535        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2536        msg.obj = r.task.askedCompatMode ? null : r;
2537        mHandler.sendMessage(msg);
2538    }
2539
2540    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2541            String what, Object obj, ProcessRecord srcApp) {
2542        app.lastActivityTime = now;
2543
2544        if (app.activities.size() > 0) {
2545            // Don't want to touch dependent processes that are hosting activities.
2546            return index;
2547        }
2548
2549        int lrui = mLruProcesses.lastIndexOf(app);
2550        if (lrui < 0) {
2551            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2552                    + what + " " + obj + " from " + srcApp);
2553            return index;
2554        }
2555
2556        if (lrui >= index) {
2557            // Don't want to cause this to move dependent processes *back* in the
2558            // list as if they were less frequently used.
2559            return index;
2560        }
2561
2562        if (lrui >= mLruProcessActivityStart) {
2563            // Don't want to touch dependent processes that are hosting activities.
2564            return index;
2565        }
2566
2567        mLruProcesses.remove(lrui);
2568        if (index > 0) {
2569            index--;
2570        }
2571        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2572                + " in LRU list: " + app);
2573        mLruProcesses.add(index, app);
2574        return index;
2575    }
2576
2577    final void removeLruProcessLocked(ProcessRecord app) {
2578        int lrui = mLruProcesses.lastIndexOf(app);
2579        if (lrui >= 0) {
2580            if (lrui <= mLruProcessActivityStart) {
2581                mLruProcessActivityStart--;
2582            }
2583            if (lrui <= mLruProcessServiceStart) {
2584                mLruProcessServiceStart--;
2585            }
2586            mLruProcesses.remove(lrui);
2587        }
2588    }
2589
2590    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2591            ProcessRecord client) {
2592        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2593                || app.treatLikeActivity;
2594        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2595        if (!activityChange && hasActivity) {
2596            // The process has activities, so we are only allowing activity-based adjustments
2597            // to move it.  It should be kept in the front of the list with other
2598            // processes that have activities, and we don't want those to change their
2599            // order except due to activity operations.
2600            return;
2601        }
2602
2603        mLruSeq++;
2604        final long now = SystemClock.uptimeMillis();
2605        app.lastActivityTime = now;
2606
2607        // First a quick reject: if the app is already at the position we will
2608        // put it, then there is nothing to do.
2609        if (hasActivity) {
2610            final int N = mLruProcesses.size();
2611            if (N > 0 && mLruProcesses.get(N-1) == app) {
2612                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2613                return;
2614            }
2615        } else {
2616            if (mLruProcessServiceStart > 0
2617                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2618                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2619                return;
2620            }
2621        }
2622
2623        int lrui = mLruProcesses.lastIndexOf(app);
2624
2625        if (app.persistent && lrui >= 0) {
2626            // We don't care about the position of persistent processes, as long as
2627            // they are in the list.
2628            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2629            return;
2630        }
2631
2632        /* In progress: compute new position first, so we can avoid doing work
2633           if the process is not actually going to move.  Not yet working.
2634        int addIndex;
2635        int nextIndex;
2636        boolean inActivity = false, inService = false;
2637        if (hasActivity) {
2638            // Process has activities, put it at the very tipsy-top.
2639            addIndex = mLruProcesses.size();
2640            nextIndex = mLruProcessServiceStart;
2641            inActivity = true;
2642        } else if (hasService) {
2643            // Process has services, put it at the top of the service list.
2644            addIndex = mLruProcessActivityStart;
2645            nextIndex = mLruProcessServiceStart;
2646            inActivity = true;
2647            inService = true;
2648        } else  {
2649            // Process not otherwise of interest, it goes to the top of the non-service area.
2650            addIndex = mLruProcessServiceStart;
2651            if (client != null) {
2652                int clientIndex = mLruProcesses.lastIndexOf(client);
2653                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2654                        + app);
2655                if (clientIndex >= 0 && addIndex > clientIndex) {
2656                    addIndex = clientIndex;
2657                }
2658            }
2659            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2660        }
2661
2662        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2663                + mLruProcessActivityStart + "): " + app);
2664        */
2665
2666        if (lrui >= 0) {
2667            if (lrui < mLruProcessActivityStart) {
2668                mLruProcessActivityStart--;
2669            }
2670            if (lrui < mLruProcessServiceStart) {
2671                mLruProcessServiceStart--;
2672            }
2673            /*
2674            if (addIndex > lrui) {
2675                addIndex--;
2676            }
2677            if (nextIndex > lrui) {
2678                nextIndex--;
2679            }
2680            */
2681            mLruProcesses.remove(lrui);
2682        }
2683
2684        /*
2685        mLruProcesses.add(addIndex, app);
2686        if (inActivity) {
2687            mLruProcessActivityStart++;
2688        }
2689        if (inService) {
2690            mLruProcessActivityStart++;
2691        }
2692        */
2693
2694        int nextIndex;
2695        if (hasActivity) {
2696            final int N = mLruProcesses.size();
2697            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2698                // Process doesn't have activities, but has clients with
2699                // activities...  move it up, but one below the top (the top
2700                // should always have a real activity).
2701                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2702                mLruProcesses.add(N-1, app);
2703                // To keep it from spamming the LRU list (by making a bunch of clients),
2704                // we will push down any other entries owned by the app.
2705                final int uid = app.info.uid;
2706                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2707                    ProcessRecord subProc = mLruProcesses.get(i);
2708                    if (subProc.info.uid == uid) {
2709                        // We want to push this one down the list.  If the process after
2710                        // it is for the same uid, however, don't do so, because we don't
2711                        // want them internally to be re-ordered.
2712                        if (mLruProcesses.get(i-1).info.uid != uid) {
2713                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2714                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2715                            ProcessRecord tmp = mLruProcesses.get(i);
2716                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2717                            mLruProcesses.set(i-1, tmp);
2718                            i--;
2719                        }
2720                    } else {
2721                        // A gap, we can stop here.
2722                        break;
2723                    }
2724                }
2725            } else {
2726                // Process has activities, put it at the very tipsy-top.
2727                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2728                mLruProcesses.add(app);
2729            }
2730            nextIndex = mLruProcessServiceStart;
2731        } else if (hasService) {
2732            // Process has services, put it at the top of the service list.
2733            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2734            mLruProcesses.add(mLruProcessActivityStart, app);
2735            nextIndex = mLruProcessServiceStart;
2736            mLruProcessActivityStart++;
2737        } else  {
2738            // Process not otherwise of interest, it goes to the top of the non-service area.
2739            int index = mLruProcessServiceStart;
2740            if (client != null) {
2741                // If there is a client, don't allow the process to be moved up higher
2742                // in the list than that client.
2743                int clientIndex = mLruProcesses.lastIndexOf(client);
2744                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2745                        + " when updating " + app);
2746                if (clientIndex <= lrui) {
2747                    // Don't allow the client index restriction to push it down farther in the
2748                    // list than it already is.
2749                    clientIndex = lrui;
2750                }
2751                if (clientIndex >= 0 && index > clientIndex) {
2752                    index = clientIndex;
2753                }
2754            }
2755            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2756            mLruProcesses.add(index, app);
2757            nextIndex = index-1;
2758            mLruProcessActivityStart++;
2759            mLruProcessServiceStart++;
2760        }
2761
2762        // If the app is currently using a content provider or service,
2763        // bump those processes as well.
2764        for (int j=app.connections.size()-1; j>=0; j--) {
2765            ConnectionRecord cr = app.connections.valueAt(j);
2766            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2767                    && cr.binding.service.app != null
2768                    && cr.binding.service.app.lruSeq != mLruSeq
2769                    && !cr.binding.service.app.persistent) {
2770                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2771                        "service connection", cr, app);
2772            }
2773        }
2774        for (int j=app.conProviders.size()-1; j>=0; j--) {
2775            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2776            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2777                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2778                        "provider reference", cpr, app);
2779            }
2780        }
2781    }
2782
2783    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2784        if (uid == Process.SYSTEM_UID) {
2785            // The system gets to run in any process.  If there are multiple
2786            // processes with the same uid, just pick the first (this
2787            // should never happen).
2788            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2789            if (procs == null) return null;
2790            final int N = procs.size();
2791            for (int i = 0; i < N; i++) {
2792                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2793            }
2794        }
2795        ProcessRecord proc = mProcessNames.get(processName, uid);
2796        if (false && proc != null && !keepIfLarge
2797                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2798                && proc.lastCachedPss >= 4000) {
2799            // Turn this condition on to cause killing to happen regularly, for testing.
2800            if (proc.baseProcessTracker != null) {
2801                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2802            }
2803            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2804                    + "k from cached");
2805        } else if (proc != null && !keepIfLarge
2806                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2807                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2808            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2809            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2810                if (proc.baseProcessTracker != null) {
2811                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2812                }
2813                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2814                        + "k from cached");
2815            }
2816        }
2817        return proc;
2818    }
2819
2820    void ensurePackageDexOpt(String packageName) {
2821        IPackageManager pm = AppGlobals.getPackageManager();
2822        try {
2823            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2824                mDidDexOpt = true;
2825            }
2826        } catch (RemoteException e) {
2827        }
2828    }
2829
2830    boolean isNextTransitionForward() {
2831        int transit = mWindowManager.getPendingAppTransition();
2832        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2833                || transit == AppTransition.TRANSIT_TASK_OPEN
2834                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2835    }
2836
2837    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2838            String processName, String abiOverride, int uid, Runnable crashHandler) {
2839        synchronized(this) {
2840            ApplicationInfo info = new ApplicationInfo();
2841            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2842            // For isolated processes, the former contains the parent's uid and the latter the
2843            // actual uid of the isolated process.
2844            // In the special case introduced by this method (which is, starting an isolated
2845            // process directly from the SystemServer without an actual parent app process) the
2846            // closest thing to a parent's uid is SYSTEM_UID.
2847            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2848            // the |isolated| logic in the ProcessRecord constructor.
2849            info.uid = Process.SYSTEM_UID;
2850            info.processName = processName;
2851            info.className = entryPoint;
2852            info.packageName = "android";
2853            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2854                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2855                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2856                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2857                    crashHandler);
2858            return proc != null ? proc.pid : 0;
2859        }
2860    }
2861
2862    final ProcessRecord startProcessLocked(String processName,
2863            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2864            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2865            boolean isolated, boolean keepIfLarge) {
2866        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2867                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2868                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2869                null /* crashHandler */);
2870    }
2871
2872    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2873            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2874            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2875            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2876        ProcessRecord app;
2877        if (!isolated) {
2878            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2879        } else {
2880            // If this is an isolated process, it can't re-use an existing process.
2881            app = null;
2882        }
2883        // We don't have to do anything more if:
2884        // (1) There is an existing application record; and
2885        // (2) The caller doesn't think it is dead, OR there is no thread
2886        //     object attached to it so we know it couldn't have crashed; and
2887        // (3) There is a pid assigned to it, so it is either starting or
2888        //     already running.
2889        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2890                + " app=" + app + " knownToBeDead=" + knownToBeDead
2891                + " thread=" + (app != null ? app.thread : null)
2892                + " pid=" + (app != null ? app.pid : -1));
2893        if (app != null && app.pid > 0) {
2894            if (!knownToBeDead || app.thread == null) {
2895                // We already have the app running, or are waiting for it to
2896                // come up (we have a pid but not yet its thread), so keep it.
2897                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2898                // If this is a new package in the process, add the package to the list
2899                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2900                return app;
2901            }
2902
2903            // An application record is attached to a previous process,
2904            // clean it up now.
2905            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2906            Process.killProcessGroup(app.info.uid, app.pid);
2907            handleAppDiedLocked(app, true, true);
2908        }
2909
2910        String hostingNameStr = hostingName != null
2911                ? hostingName.flattenToShortString() : null;
2912
2913        if (!isolated) {
2914            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2915                // If we are in the background, then check to see if this process
2916                // is bad.  If so, we will just silently fail.
2917                if (mBadProcesses.get(info.processName, info.uid) != null) {
2918                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2919                            + "/" + info.processName);
2920                    return null;
2921                }
2922            } else {
2923                // When the user is explicitly starting a process, then clear its
2924                // crash count so that we won't make it bad until they see at
2925                // least one crash dialog again, and make the process good again
2926                // if it had been bad.
2927                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2928                        + "/" + info.processName);
2929                mProcessCrashTimes.remove(info.processName, info.uid);
2930                if (mBadProcesses.get(info.processName, info.uid) != null) {
2931                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2932                            UserHandle.getUserId(info.uid), info.uid,
2933                            info.processName);
2934                    mBadProcesses.remove(info.processName, info.uid);
2935                    if (app != null) {
2936                        app.bad = false;
2937                    }
2938                }
2939            }
2940        }
2941
2942        if (app == null) {
2943            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2944            app.crashHandler = crashHandler;
2945            if (app == null) {
2946                Slog.w(TAG, "Failed making new process record for "
2947                        + processName + "/" + info.uid + " isolated=" + isolated);
2948                return null;
2949            }
2950            mProcessNames.put(processName, app.uid, app);
2951            if (isolated) {
2952                mIsolatedProcesses.put(app.uid, app);
2953            }
2954        } else {
2955            // If this is a new package in the process, add the package to the list
2956            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2957        }
2958
2959        // If the system is not ready yet, then hold off on starting this
2960        // process until it is.
2961        if (!mProcessesReady
2962                && !isAllowedWhileBooting(info)
2963                && !allowWhileBooting) {
2964            if (!mProcessesOnHold.contains(app)) {
2965                mProcessesOnHold.add(app);
2966            }
2967            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2968            return app;
2969        }
2970
2971        startProcessLocked(
2972                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2973        return (app.pid != 0) ? app : null;
2974    }
2975
2976    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2977        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2978    }
2979
2980    private final void startProcessLocked(ProcessRecord app,
2981            String hostingType, String hostingNameStr) {
2982        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2983                null /* entryPoint */, null /* entryPointArgs */);
2984    }
2985
2986    private final void startProcessLocked(ProcessRecord app, String hostingType,
2987            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2988        if (app.pid > 0 && app.pid != MY_PID) {
2989            synchronized (mPidsSelfLocked) {
2990                mPidsSelfLocked.remove(app.pid);
2991                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2992            }
2993            app.setPid(0);
2994        }
2995
2996        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2997                "startProcessLocked removing on hold: " + app);
2998        mProcessesOnHold.remove(app);
2999
3000        updateCpuStats();
3001
3002        try {
3003            int uid = app.uid;
3004
3005            int[] gids = null;
3006            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3007            if (!app.isolated) {
3008                int[] permGids = null;
3009                try {
3010                    final PackageManager pm = mContext.getPackageManager();
3011                    permGids = pm.getPackageGids(app.info.packageName);
3012
3013                    if (Environment.isExternalStorageEmulated()) {
3014                        if (pm.checkPermission(
3015                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3016                                app.info.packageName) == PERMISSION_GRANTED) {
3017                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3018                        } else {
3019                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3020                        }
3021                    }
3022                } catch (PackageManager.NameNotFoundException e) {
3023                    Slog.w(TAG, "Unable to retrieve gids", e);
3024                }
3025
3026                /*
3027                 * Add shared application and profile GIDs so applications can share some
3028                 * resources like shared libraries and access user-wide resources
3029                 */
3030                if (permGids == null) {
3031                    gids = new int[2];
3032                } else {
3033                    gids = new int[permGids.length + 2];
3034                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3035                }
3036                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3037                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3038            }
3039            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3040                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3041                        && mTopComponent != null
3042                        && app.processName.equals(mTopComponent.getPackageName())) {
3043                    uid = 0;
3044                }
3045                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3046                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3047                    uid = 0;
3048                }
3049            }
3050            int debugFlags = 0;
3051            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3052                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3053                // Also turn on CheckJNI for debuggable apps. It's quite
3054                // awkward to turn on otherwise.
3055                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3056            }
3057            // Run the app in safe mode if its manifest requests so or the
3058            // system is booted in safe mode.
3059            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3060                mSafeMode == true) {
3061                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3062            }
3063            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3064                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3065            }
3066            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3067                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3068            }
3069            if ("1".equals(SystemProperties.get("debug.assert"))) {
3070                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3071            }
3072
3073            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3074            if (requiredAbi == null) {
3075                requiredAbi = Build.SUPPORTED_ABIS[0];
3076            }
3077
3078            // Start the process.  It will either succeed and return a result containing
3079            // the PID of the new process, or else throw a RuntimeException.
3080            boolean isActivityProcess = (entryPoint == null);
3081            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3082            Process.ProcessStartResult startResult = Process.start(entryPoint,
3083                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3084                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
3085
3086            if (app.isolated) {
3087                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3088            }
3089            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3090
3091            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3092                    UserHandle.getUserId(uid), startResult.pid, uid,
3093                    app.processName, hostingType,
3094                    hostingNameStr != null ? hostingNameStr : "");
3095
3096            if (app.persistent) {
3097                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3098            }
3099
3100            StringBuilder buf = mStringBuilder;
3101            buf.setLength(0);
3102            buf.append("Start proc ");
3103            buf.append(app.processName);
3104            if (!isActivityProcess) {
3105                buf.append(" [");
3106                buf.append(entryPoint);
3107                buf.append("]");
3108            }
3109            buf.append(" for ");
3110            buf.append(hostingType);
3111            if (hostingNameStr != null) {
3112                buf.append(" ");
3113                buf.append(hostingNameStr);
3114            }
3115            buf.append(": pid=");
3116            buf.append(startResult.pid);
3117            buf.append(" uid=");
3118            buf.append(uid);
3119            buf.append(" gids={");
3120            if (gids != null) {
3121                for (int gi=0; gi<gids.length; gi++) {
3122                    if (gi != 0) buf.append(", ");
3123                    buf.append(gids[gi]);
3124
3125                }
3126            }
3127            buf.append("}");
3128            if (requiredAbi != null) {
3129                buf.append(" abi=");
3130                buf.append(requiredAbi);
3131            }
3132            Slog.i(TAG, buf.toString());
3133            app.setPid(startResult.pid);
3134            app.usingWrapper = startResult.usingWrapper;
3135            app.removed = false;
3136            app.killedByAm = false;
3137            synchronized (mPidsSelfLocked) {
3138                this.mPidsSelfLocked.put(startResult.pid, app);
3139                if (isActivityProcess) {
3140                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3141                    msg.obj = app;
3142                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3143                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3144                }
3145            }
3146        } catch (RuntimeException e) {
3147            // XXX do better error recovery.
3148            app.setPid(0);
3149            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3150            if (app.isolated) {
3151                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3152            }
3153            Slog.e(TAG, "Failure starting process " + app.processName, e);
3154        }
3155    }
3156
3157    void updateUsageStats(ActivityRecord component, boolean resumed) {
3158        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3159        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3160        if (resumed) {
3161            if (mUsageStatsService != null) {
3162                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3163                        System.currentTimeMillis(),
3164                        UsageStats.Event.MOVE_TO_FOREGROUND);
3165            }
3166            synchronized (stats) {
3167                stats.noteActivityResumedLocked(component.app.uid);
3168            }
3169        } else {
3170            if (mUsageStatsService != null) {
3171                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3172                        System.currentTimeMillis(),
3173                        UsageStats.Event.MOVE_TO_BACKGROUND);
3174            }
3175            synchronized (stats) {
3176                stats.noteActivityPausedLocked(component.app.uid);
3177            }
3178        }
3179    }
3180
3181    Intent getHomeIntent() {
3182        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3183        intent.setComponent(mTopComponent);
3184        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3185            intent.addCategory(Intent.CATEGORY_HOME);
3186        }
3187        return intent;
3188    }
3189
3190    boolean startHomeActivityLocked(int userId) {
3191        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3192                && mTopAction == null) {
3193            // We are running in factory test mode, but unable to find
3194            // the factory test app, so just sit around displaying the
3195            // error message and don't try to start anything.
3196            return false;
3197        }
3198        Intent intent = getHomeIntent();
3199        ActivityInfo aInfo =
3200            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3201        if (aInfo != null) {
3202            intent.setComponent(new ComponentName(
3203                    aInfo.applicationInfo.packageName, aInfo.name));
3204            // Don't do this if the home app is currently being
3205            // instrumented.
3206            aInfo = new ActivityInfo(aInfo);
3207            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3208            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3209                    aInfo.applicationInfo.uid, true);
3210            if (app == null || app.instrumentationClass == null) {
3211                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3212                mStackSupervisor.startHomeActivity(intent, aInfo);
3213            }
3214        }
3215
3216        return true;
3217    }
3218
3219    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3220        ActivityInfo ai = null;
3221        ComponentName comp = intent.getComponent();
3222        try {
3223            if (comp != null) {
3224                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3225            } else {
3226                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3227                        intent,
3228                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3229                            flags, userId);
3230
3231                if (info != null) {
3232                    ai = info.activityInfo;
3233                }
3234            }
3235        } catch (RemoteException e) {
3236            // ignore
3237        }
3238
3239        return ai;
3240    }
3241
3242    /**
3243     * Starts the "new version setup screen" if appropriate.
3244     */
3245    void startSetupActivityLocked() {
3246        // Only do this once per boot.
3247        if (mCheckedForSetup) {
3248            return;
3249        }
3250
3251        // We will show this screen if the current one is a different
3252        // version than the last one shown, and we are not running in
3253        // low-level factory test mode.
3254        final ContentResolver resolver = mContext.getContentResolver();
3255        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3256                Settings.Global.getInt(resolver,
3257                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3258            mCheckedForSetup = true;
3259
3260            // See if we should be showing the platform update setup UI.
3261            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3262            List<ResolveInfo> ris = mContext.getPackageManager()
3263                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3264
3265            // We don't allow third party apps to replace this.
3266            ResolveInfo ri = null;
3267            for (int i=0; ris != null && i<ris.size(); i++) {
3268                if ((ris.get(i).activityInfo.applicationInfo.flags
3269                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3270                    ri = ris.get(i);
3271                    break;
3272                }
3273            }
3274
3275            if (ri != null) {
3276                String vers = ri.activityInfo.metaData != null
3277                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3278                        : null;
3279                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3280                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3281                            Intent.METADATA_SETUP_VERSION);
3282                }
3283                String lastVers = Settings.Secure.getString(
3284                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3285                if (vers != null && !vers.equals(lastVers)) {
3286                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3287                    intent.setComponent(new ComponentName(
3288                            ri.activityInfo.packageName, ri.activityInfo.name));
3289                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3290                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3291                }
3292            }
3293        }
3294    }
3295
3296    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3297        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3298    }
3299
3300    void enforceNotIsolatedCaller(String caller) {
3301        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3302            throw new SecurityException("Isolated process not allowed to call " + caller);
3303        }
3304    }
3305
3306    @Override
3307    public int getFrontActivityScreenCompatMode() {
3308        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3309        synchronized (this) {
3310            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3311        }
3312    }
3313
3314    @Override
3315    public void setFrontActivityScreenCompatMode(int mode) {
3316        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3317                "setFrontActivityScreenCompatMode");
3318        synchronized (this) {
3319            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3320        }
3321    }
3322
3323    @Override
3324    public int getPackageScreenCompatMode(String packageName) {
3325        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3326        synchronized (this) {
3327            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3328        }
3329    }
3330
3331    @Override
3332    public void setPackageScreenCompatMode(String packageName, int mode) {
3333        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3334                "setPackageScreenCompatMode");
3335        synchronized (this) {
3336            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3337        }
3338    }
3339
3340    @Override
3341    public boolean getPackageAskScreenCompat(String packageName) {
3342        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3343        synchronized (this) {
3344            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3345        }
3346    }
3347
3348    @Override
3349    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3350        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3351                "setPackageAskScreenCompat");
3352        synchronized (this) {
3353            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3354        }
3355    }
3356
3357    private void dispatchProcessesChanged() {
3358        int N;
3359        synchronized (this) {
3360            N = mPendingProcessChanges.size();
3361            if (mActiveProcessChanges.length < N) {
3362                mActiveProcessChanges = new ProcessChangeItem[N];
3363            }
3364            mPendingProcessChanges.toArray(mActiveProcessChanges);
3365            mAvailProcessChanges.addAll(mPendingProcessChanges);
3366            mPendingProcessChanges.clear();
3367            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3368        }
3369
3370        int i = mProcessObservers.beginBroadcast();
3371        while (i > 0) {
3372            i--;
3373            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3374            if (observer != null) {
3375                try {
3376                    for (int j=0; j<N; j++) {
3377                        ProcessChangeItem item = mActiveProcessChanges[j];
3378                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3379                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3380                                    + item.pid + " uid=" + item.uid + ": "
3381                                    + item.foregroundActivities);
3382                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3383                                    item.foregroundActivities);
3384                        }
3385                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3386                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3387                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3388                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3389                        }
3390                    }
3391                } catch (RemoteException e) {
3392                }
3393            }
3394        }
3395        mProcessObservers.finishBroadcast();
3396    }
3397
3398    private void dispatchProcessDied(int pid, int uid) {
3399        int i = mProcessObservers.beginBroadcast();
3400        while (i > 0) {
3401            i--;
3402            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3403            if (observer != null) {
3404                try {
3405                    observer.onProcessDied(pid, uid);
3406                } catch (RemoteException e) {
3407                }
3408            }
3409        }
3410        mProcessObservers.finishBroadcast();
3411    }
3412
3413    @Override
3414    public final int startActivity(IApplicationThread caller, String callingPackage,
3415            Intent intent, String resolvedType, IBinder resultTo,
3416            String resultWho, int requestCode, int startFlags,
3417            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3418        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3419                resultWho, requestCode,
3420                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3421    }
3422
3423    @Override
3424    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3425            Intent intent, String resolvedType, IBinder resultTo,
3426            String resultWho, int requestCode, int startFlags,
3427            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3428        enforceNotIsolatedCaller("startActivity");
3429        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3430                false, ALLOW_FULL_ONLY, "startActivity", null);
3431        // TODO: Switch to user app stacks here.
3432        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3433                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3434                null, null, options, userId, null);
3435    }
3436
3437    @Override
3438    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3439            Intent intent, String resolvedType, IBinder resultTo,
3440            String resultWho, int requestCode, int startFlags, String profileFile,
3441            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3442        enforceNotIsolatedCaller("startActivityAndWait");
3443        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3444                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3445        WaitResult res = new WaitResult();
3446        // TODO: Switch to user app stacks here.
3447        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3448                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3449                res, null, options, userId, null);
3450        return res;
3451    }
3452
3453    @Override
3454    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3455            Intent intent, String resolvedType, IBinder resultTo,
3456            String resultWho, int requestCode, int startFlags, Configuration config,
3457            Bundle options, int userId) {
3458        enforceNotIsolatedCaller("startActivityWithConfig");
3459        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3460                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3461        // TODO: Switch to user app stacks here.
3462        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3463                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3464                null, null, null, config, options, userId, null);
3465        return ret;
3466    }
3467
3468    @Override
3469    public int startActivityIntentSender(IApplicationThread caller,
3470            IntentSender intent, Intent fillInIntent, String resolvedType,
3471            IBinder resultTo, String resultWho, int requestCode,
3472            int flagsMask, int flagsValues, Bundle options) {
3473        enforceNotIsolatedCaller("startActivityIntentSender");
3474        // Refuse possible leaked file descriptors
3475        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3476            throw new IllegalArgumentException("File descriptors passed in Intent");
3477        }
3478
3479        IIntentSender sender = intent.getTarget();
3480        if (!(sender instanceof PendingIntentRecord)) {
3481            throw new IllegalArgumentException("Bad PendingIntent object");
3482        }
3483
3484        PendingIntentRecord pir = (PendingIntentRecord)sender;
3485
3486        synchronized (this) {
3487            // If this is coming from the currently resumed activity, it is
3488            // effectively saying that app switches are allowed at this point.
3489            final ActivityStack stack = getFocusedStack();
3490            if (stack.mResumedActivity != null &&
3491                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3492                mAppSwitchesAllowedTime = 0;
3493            }
3494        }
3495        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3496                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3497        return ret;
3498    }
3499
3500    @Override
3501    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3502            Intent intent, String resolvedType, IVoiceInteractionSession session,
3503            IVoiceInteractor interactor, int startFlags, String profileFile,
3504            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3505        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3506                != PackageManager.PERMISSION_GRANTED) {
3507            String msg = "Permission Denial: startVoiceActivity() from pid="
3508                    + Binder.getCallingPid()
3509                    + ", uid=" + Binder.getCallingUid()
3510                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3511            Slog.w(TAG, msg);
3512            throw new SecurityException(msg);
3513        }
3514        if (session == null || interactor == null) {
3515            throw new NullPointerException("null session or interactor");
3516        }
3517        userId = handleIncomingUser(callingPid, callingUid, userId,
3518                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3519        // TODO: Switch to user app stacks here.
3520        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3521                resolvedType, session, interactor, null, null, 0, startFlags,
3522                profileFile, profileFd, null, null, options, userId, null);
3523    }
3524
3525    @Override
3526    public boolean startNextMatchingActivity(IBinder callingActivity,
3527            Intent intent, Bundle options) {
3528        // Refuse possible leaked file descriptors
3529        if (intent != null && intent.hasFileDescriptors() == true) {
3530            throw new IllegalArgumentException("File descriptors passed in Intent");
3531        }
3532
3533        synchronized (this) {
3534            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3535            if (r == null) {
3536                ActivityOptions.abort(options);
3537                return false;
3538            }
3539            if (r.app == null || r.app.thread == null) {
3540                // The caller is not running...  d'oh!
3541                ActivityOptions.abort(options);
3542                return false;
3543            }
3544            intent = new Intent(intent);
3545            // The caller is not allowed to change the data.
3546            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3547            // And we are resetting to find the next component...
3548            intent.setComponent(null);
3549
3550            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3551
3552            ActivityInfo aInfo = null;
3553            try {
3554                List<ResolveInfo> resolves =
3555                    AppGlobals.getPackageManager().queryIntentActivities(
3556                            intent, r.resolvedType,
3557                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3558                            UserHandle.getCallingUserId());
3559
3560                // Look for the original activity in the list...
3561                final int N = resolves != null ? resolves.size() : 0;
3562                for (int i=0; i<N; i++) {
3563                    ResolveInfo rInfo = resolves.get(i);
3564                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3565                            && rInfo.activityInfo.name.equals(r.info.name)) {
3566                        // We found the current one...  the next matching is
3567                        // after it.
3568                        i++;
3569                        if (i<N) {
3570                            aInfo = resolves.get(i).activityInfo;
3571                        }
3572                        if (debug) {
3573                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3574                                    + "/" + r.info.name);
3575                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3576                                    + "/" + aInfo.name);
3577                        }
3578                        break;
3579                    }
3580                }
3581            } catch (RemoteException e) {
3582            }
3583
3584            if (aInfo == null) {
3585                // Nobody who is next!
3586                ActivityOptions.abort(options);
3587                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3588                return false;
3589            }
3590
3591            intent.setComponent(new ComponentName(
3592                    aInfo.applicationInfo.packageName, aInfo.name));
3593            intent.setFlags(intent.getFlags()&~(
3594                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3595                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3596                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3597                    Intent.FLAG_ACTIVITY_NEW_TASK));
3598
3599            // Okay now we need to start the new activity, replacing the
3600            // currently running activity.  This is a little tricky because
3601            // we want to start the new one as if the current one is finished,
3602            // but not finish the current one first so that there is no flicker.
3603            // And thus...
3604            final boolean wasFinishing = r.finishing;
3605            r.finishing = true;
3606
3607            // Propagate reply information over to the new activity.
3608            final ActivityRecord resultTo = r.resultTo;
3609            final String resultWho = r.resultWho;
3610            final int requestCode = r.requestCode;
3611            r.resultTo = null;
3612            if (resultTo != null) {
3613                resultTo.removeResultsLocked(r, resultWho, requestCode);
3614            }
3615
3616            final long origId = Binder.clearCallingIdentity();
3617            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3618                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3619                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3620                    options, false, null, null);
3621            Binder.restoreCallingIdentity(origId);
3622
3623            r.finishing = wasFinishing;
3624            if (res != ActivityManager.START_SUCCESS) {
3625                return false;
3626            }
3627            return true;
3628        }
3629    }
3630
3631    @Override
3632    public final int startActivityFromRecents(int taskId, Bundle options) {
3633        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3634            String msg = "Permission Denial: startActivityFromRecents called without " +
3635                    START_TASKS_FROM_RECENTS;
3636            Slog.w(TAG, msg);
3637            throw new SecurityException(msg);
3638        }
3639        final int callingUid;
3640        final String callingPackage;
3641        final Intent intent;
3642        final int userId;
3643        synchronized (this) {
3644            final TaskRecord task = recentTaskForIdLocked(taskId);
3645            if (task == null) {
3646                throw new ActivityNotFoundException("Task " + taskId + " not found.");
3647            }
3648            callingUid = task.mCallingUid;
3649            callingPackage = task.mCallingPackage;
3650            intent = task.intent;
3651            userId = task.userId;
3652        }
3653        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3654                options, userId, null);
3655    }
3656
3657    final int startActivityInPackage(int uid, String callingPackage,
3658            Intent intent, String resolvedType, IBinder resultTo,
3659            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3660                    IActivityContainer container) {
3661
3662        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3663                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3664
3665        // TODO: Switch to user app stacks here.
3666        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3667                null, null, resultTo, resultWho, requestCode, startFlags,
3668                null, null, null, null, options, userId, container);
3669        return ret;
3670    }
3671
3672    @Override
3673    public final int startActivities(IApplicationThread caller, String callingPackage,
3674            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3675            int userId) {
3676        enforceNotIsolatedCaller("startActivities");
3677        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3678                false, ALLOW_FULL_ONLY, "startActivity", null);
3679        // TODO: Switch to user app stacks here.
3680        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3681                resolvedTypes, resultTo, options, userId);
3682        return ret;
3683    }
3684
3685    final int startActivitiesInPackage(int uid, String callingPackage,
3686            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3687            Bundle options, int userId) {
3688
3689        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3690                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3691        // TODO: Switch to user app stacks here.
3692        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3693                resultTo, options, userId);
3694        return ret;
3695    }
3696
3697    //explicitly remove thd old information in mRecentTasks when removing existing user.
3698    private void removeRecentTasksForUser(int userId) {
3699        if(userId <= 0) {
3700            Slog.i(TAG, "Can't remove recent task on user " + userId);
3701            return;
3702        }
3703
3704        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3705            TaskRecord tr = mRecentTasks.get(i);
3706            if (tr.userId == userId) {
3707                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3708                        + " when finishing user" + userId);
3709                tr.disposeThumbnail();
3710                mRecentTasks.remove(i);
3711            }
3712        }
3713
3714        // Remove tasks from persistent storage.
3715        mTaskPersister.wakeup(null, true);
3716    }
3717
3718    final void addRecentTaskLocked(TaskRecord task) {
3719        int N = mRecentTasks.size();
3720        // Quick case: check if the top-most recent task is the same.
3721        if (N > 0 && mRecentTasks.get(0) == task) {
3722            return;
3723        }
3724        // Another quick case: never add voice sessions.
3725        if (task.voiceSession != null) {
3726            return;
3727        }
3728        // Remove any existing entries that are the same kind of task.
3729        final Intent intent = task.intent;
3730        final boolean document = intent != null && intent.isDocument();
3731        final ComponentName comp = intent.getComponent();
3732
3733        int maxRecents = task.maxRecents - 1;
3734        for (int i=0; i<N; i++) {
3735            final TaskRecord tr = mRecentTasks.get(i);
3736            if (task != tr) {
3737                if (task.userId != tr.userId) {
3738                    continue;
3739                }
3740                if (i > MAX_RECENT_BITMAPS) {
3741                    tr.freeLastThumbnail();
3742                }
3743                final Intent trIntent = tr.intent;
3744                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3745                    (intent == null || !intent.filterEquals(trIntent))) {
3746                    continue;
3747                }
3748                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3749                if (document && trIsDocument) {
3750                    // These are the same document activity (not necessarily the same doc).
3751                    if (maxRecents > 0) {
3752                        --maxRecents;
3753                        continue;
3754                    }
3755                    // Hit the maximum number of documents for this task. Fall through
3756                    // and remove this document from recents.
3757                } else if (document || trIsDocument) {
3758                    // Only one of these is a document. Not the droid we're looking for.
3759                    continue;
3760                }
3761            }
3762
3763            // Either task and tr are the same or, their affinities match or their intents match
3764            // and neither of them is a document, or they are documents using the same activity
3765            // and their maxRecents has been reached.
3766            tr.disposeThumbnail();
3767            mRecentTasks.remove(i);
3768            if (task != tr) {
3769                tr.closeRecentsChain();
3770            }
3771            i--;
3772            N--;
3773            if (task.intent == null) {
3774                // If the new recent task we are adding is not fully
3775                // specified, then replace it with the existing recent task.
3776                task = tr;
3777            }
3778            notifyTaskPersisterLocked(tr, false);
3779        }
3780        if (N >= MAX_RECENT_TASKS) {
3781            final TaskRecord tr = mRecentTasks.remove(N - 1);
3782            tr.disposeThumbnail();
3783            tr.closeRecentsChain();
3784        }
3785        mRecentTasks.add(0, task);
3786    }
3787
3788    @Override
3789    public void reportActivityFullyDrawn(IBinder token) {
3790        synchronized (this) {
3791            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3792            if (r == null) {
3793                return;
3794            }
3795            r.reportFullyDrawnLocked();
3796        }
3797    }
3798
3799    @Override
3800    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3801        synchronized (this) {
3802            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3803            if (r == null) {
3804                return;
3805            }
3806            final long origId = Binder.clearCallingIdentity();
3807            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3808            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3809                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3810            if (config != null) {
3811                r.frozenBeforeDestroy = true;
3812                if (!updateConfigurationLocked(config, r, false, false)) {
3813                    mStackSupervisor.resumeTopActivitiesLocked();
3814                }
3815            }
3816            Binder.restoreCallingIdentity(origId);
3817        }
3818    }
3819
3820    @Override
3821    public int getRequestedOrientation(IBinder token) {
3822        synchronized (this) {
3823            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3824            if (r == null) {
3825                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3826            }
3827            return mWindowManager.getAppOrientation(r.appToken);
3828        }
3829    }
3830
3831    /**
3832     * This is the internal entry point for handling Activity.finish().
3833     *
3834     * @param token The Binder token referencing the Activity we want to finish.
3835     * @param resultCode Result code, if any, from this Activity.
3836     * @param resultData Result data (Intent), if any, from this Activity.
3837     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3838     *            the root Activity in the task.
3839     *
3840     * @return Returns true if the activity successfully finished, or false if it is still running.
3841     */
3842    @Override
3843    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3844            boolean finishTask) {
3845        // Refuse possible leaked file descriptors
3846        if (resultData != null && resultData.hasFileDescriptors() == true) {
3847            throw new IllegalArgumentException("File descriptors passed in Intent");
3848        }
3849
3850        synchronized(this) {
3851            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3852            if (r == null) {
3853                return true;
3854            }
3855            // Keep track of the root activity of the task before we finish it
3856            TaskRecord tr = r.task;
3857            ActivityRecord rootR = tr.getRootActivity();
3858            // Do not allow task to finish in Lock Task mode.
3859            if (tr == mStackSupervisor.mLockTaskModeTask) {
3860                if (rootR == r) {
3861                    mStackSupervisor.showLockTaskToast();
3862                    return false;
3863                }
3864            }
3865            if (mController != null) {
3866                // Find the first activity that is not finishing.
3867                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3868                if (next != null) {
3869                    // ask watcher if this is allowed
3870                    boolean resumeOK = true;
3871                    try {
3872                        resumeOK = mController.activityResuming(next.packageName);
3873                    } catch (RemoteException e) {
3874                        mController = null;
3875                        Watchdog.getInstance().setActivityController(null);
3876                    }
3877
3878                    if (!resumeOK) {
3879                        return false;
3880                    }
3881                }
3882            }
3883            final long origId = Binder.clearCallingIdentity();
3884            try {
3885                boolean res;
3886                if (finishTask && r == rootR) {
3887                    // If requested, remove the task that is associated to this activity only if it
3888                    // was the root activity in the task.  The result code and data is ignored because
3889                    // we don't support returning them across task boundaries.
3890                    res = removeTaskByIdLocked(tr.taskId, 0);
3891                } else {
3892                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3893                            resultData, "app-request", true);
3894                }
3895                return res;
3896            } finally {
3897                Binder.restoreCallingIdentity(origId);
3898            }
3899        }
3900    }
3901
3902    @Override
3903    public final void finishHeavyWeightApp() {
3904        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3905                != PackageManager.PERMISSION_GRANTED) {
3906            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3907                    + Binder.getCallingPid()
3908                    + ", uid=" + Binder.getCallingUid()
3909                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3910            Slog.w(TAG, msg);
3911            throw new SecurityException(msg);
3912        }
3913
3914        synchronized(this) {
3915            if (mHeavyWeightProcess == null) {
3916                return;
3917            }
3918
3919            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3920                    mHeavyWeightProcess.activities);
3921            for (int i=0; i<activities.size(); i++) {
3922                ActivityRecord r = activities.get(i);
3923                if (!r.finishing) {
3924                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3925                            null, "finish-heavy", true);
3926                }
3927            }
3928
3929            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3930                    mHeavyWeightProcess.userId, 0));
3931            mHeavyWeightProcess = null;
3932        }
3933    }
3934
3935    @Override
3936    public void crashApplication(int uid, int initialPid, String packageName,
3937            String message) {
3938        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3939                != PackageManager.PERMISSION_GRANTED) {
3940            String msg = "Permission Denial: crashApplication() from pid="
3941                    + Binder.getCallingPid()
3942                    + ", uid=" + Binder.getCallingUid()
3943                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3944            Slog.w(TAG, msg);
3945            throw new SecurityException(msg);
3946        }
3947
3948        synchronized(this) {
3949            ProcessRecord proc = null;
3950
3951            // Figure out which process to kill.  We don't trust that initialPid
3952            // still has any relation to current pids, so must scan through the
3953            // list.
3954            synchronized (mPidsSelfLocked) {
3955                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3956                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3957                    if (p.uid != uid) {
3958                        continue;
3959                    }
3960                    if (p.pid == initialPid) {
3961                        proc = p;
3962                        break;
3963                    }
3964                    if (p.pkgList.containsKey(packageName)) {
3965                        proc = p;
3966                    }
3967                }
3968            }
3969
3970            if (proc == null) {
3971                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3972                        + " initialPid=" + initialPid
3973                        + " packageName=" + packageName);
3974                return;
3975            }
3976
3977            if (proc.thread != null) {
3978                if (proc.pid == Process.myPid()) {
3979                    Log.w(TAG, "crashApplication: trying to crash self!");
3980                    return;
3981                }
3982                long ident = Binder.clearCallingIdentity();
3983                try {
3984                    proc.thread.scheduleCrash(message);
3985                } catch (RemoteException e) {
3986                }
3987                Binder.restoreCallingIdentity(ident);
3988            }
3989        }
3990    }
3991
3992    @Override
3993    public final void finishSubActivity(IBinder token, String resultWho,
3994            int requestCode) {
3995        synchronized(this) {
3996            final long origId = Binder.clearCallingIdentity();
3997            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3998            if (r != null) {
3999                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4000            }
4001            Binder.restoreCallingIdentity(origId);
4002        }
4003    }
4004
4005    @Override
4006    public boolean finishActivityAffinity(IBinder token) {
4007        synchronized(this) {
4008            final long origId = Binder.clearCallingIdentity();
4009            try {
4010                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4011
4012                ActivityRecord rootR = r.task.getRootActivity();
4013                // Do not allow task to finish in Lock Task mode.
4014                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4015                    if (rootR == r) {
4016                        mStackSupervisor.showLockTaskToast();
4017                        return false;
4018                    }
4019                }
4020                boolean res = false;
4021                if (r != null) {
4022                    res = r.task.stack.finishActivityAffinityLocked(r);
4023                }
4024                return res;
4025            } finally {
4026                Binder.restoreCallingIdentity(origId);
4027            }
4028        }
4029    }
4030
4031    @Override
4032    public void finishVoiceTask(IVoiceInteractionSession session) {
4033        synchronized(this) {
4034            final long origId = Binder.clearCallingIdentity();
4035            try {
4036                mStackSupervisor.finishVoiceTask(session);
4037            } finally {
4038                Binder.restoreCallingIdentity(origId);
4039            }
4040        }
4041
4042    }
4043
4044    @Override
4045    public boolean willActivityBeVisible(IBinder token) {
4046        synchronized(this) {
4047            ActivityStack stack = ActivityRecord.getStackLocked(token);
4048            if (stack != null) {
4049                return stack.willActivityBeVisibleLocked(token);
4050            }
4051            return false;
4052        }
4053    }
4054
4055    @Override
4056    public void overridePendingTransition(IBinder token, String packageName,
4057            int enterAnim, int exitAnim) {
4058        synchronized(this) {
4059            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4060            if (self == null) {
4061                return;
4062            }
4063
4064            final long origId = Binder.clearCallingIdentity();
4065
4066            if (self.state == ActivityState.RESUMED
4067                    || self.state == ActivityState.PAUSING) {
4068                mWindowManager.overridePendingAppTransition(packageName,
4069                        enterAnim, exitAnim, null);
4070            }
4071
4072            Binder.restoreCallingIdentity(origId);
4073        }
4074    }
4075
4076    /**
4077     * Main function for removing an existing process from the activity manager
4078     * as a result of that process going away.  Clears out all connections
4079     * to the process.
4080     */
4081    private final void handleAppDiedLocked(ProcessRecord app,
4082            boolean restarting, boolean allowRestart) {
4083        int pid = app.pid;
4084        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4085        if (!restarting) {
4086            removeLruProcessLocked(app);
4087            if (pid > 0) {
4088                ProcessList.remove(pid);
4089            }
4090        }
4091
4092        if (mProfileProc == app) {
4093            clearProfilerLocked();
4094        }
4095
4096        // Remove this application's activities from active lists.
4097        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4098
4099        app.activities.clear();
4100
4101        if (app.instrumentationClass != null) {
4102            Slog.w(TAG, "Crash of app " + app.processName
4103                  + " running instrumentation " + app.instrumentationClass);
4104            Bundle info = new Bundle();
4105            info.putString("shortMsg", "Process crashed.");
4106            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4107        }
4108
4109        if (!restarting) {
4110            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4111                // If there was nothing to resume, and we are not already
4112                // restarting this process, but there is a visible activity that
4113                // is hosted by the process...  then make sure all visible
4114                // activities are running, taking care of restarting this
4115                // process.
4116                if (hasVisibleActivities) {
4117                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4118                }
4119            }
4120        }
4121    }
4122
4123    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4124        IBinder threadBinder = thread.asBinder();
4125        // Find the application record.
4126        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4127            ProcessRecord rec = mLruProcesses.get(i);
4128            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4129                return i;
4130            }
4131        }
4132        return -1;
4133    }
4134
4135    final ProcessRecord getRecordForAppLocked(
4136            IApplicationThread thread) {
4137        if (thread == null) {
4138            return null;
4139        }
4140
4141        int appIndex = getLRURecordIndexForAppLocked(thread);
4142        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4143    }
4144
4145    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4146        // If there are no longer any background processes running,
4147        // and the app that died was not running instrumentation,
4148        // then tell everyone we are now low on memory.
4149        boolean haveBg = false;
4150        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4151            ProcessRecord rec = mLruProcesses.get(i);
4152            if (rec.thread != null
4153                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4154                haveBg = true;
4155                break;
4156            }
4157        }
4158
4159        if (!haveBg) {
4160            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4161            if (doReport) {
4162                long now = SystemClock.uptimeMillis();
4163                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4164                    doReport = false;
4165                } else {
4166                    mLastMemUsageReportTime = now;
4167                }
4168            }
4169            final ArrayList<ProcessMemInfo> memInfos
4170                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4171            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4172            long now = SystemClock.uptimeMillis();
4173            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4174                ProcessRecord rec = mLruProcesses.get(i);
4175                if (rec == dyingProc || rec.thread == null) {
4176                    continue;
4177                }
4178                if (doReport) {
4179                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4180                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4181                }
4182                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4183                    // The low memory report is overriding any current
4184                    // state for a GC request.  Make sure to do
4185                    // heavy/important/visible/foreground processes first.
4186                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4187                        rec.lastRequestedGc = 0;
4188                    } else {
4189                        rec.lastRequestedGc = rec.lastLowMemory;
4190                    }
4191                    rec.reportLowMemory = true;
4192                    rec.lastLowMemory = now;
4193                    mProcessesToGc.remove(rec);
4194                    addProcessToGcListLocked(rec);
4195                }
4196            }
4197            if (doReport) {
4198                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4199                mHandler.sendMessage(msg);
4200            }
4201            scheduleAppGcsLocked();
4202        }
4203    }
4204
4205    final void appDiedLocked(ProcessRecord app, int pid,
4206            IApplicationThread thread) {
4207
4208        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4209        synchronized (stats) {
4210            stats.noteProcessDiedLocked(app.info.uid, pid);
4211        }
4212
4213        Process.killProcessGroup(app.info.uid, pid);
4214
4215        // Clean up already done if the process has been re-started.
4216        if (app.pid == pid && app.thread != null &&
4217                app.thread.asBinder() == thread.asBinder()) {
4218            boolean doLowMem = app.instrumentationClass == null;
4219            boolean doOomAdj = doLowMem;
4220            if (!app.killedByAm) {
4221                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4222                        + ") has died.");
4223                mAllowLowerMemLevel = true;
4224            } else {
4225                // Note that we always want to do oom adj to update our state with the
4226                // new number of procs.
4227                mAllowLowerMemLevel = false;
4228                doLowMem = false;
4229            }
4230            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4231            if (DEBUG_CLEANUP) Slog.v(
4232                TAG, "Dying app: " + app + ", pid: " + pid
4233                + ", thread: " + thread.asBinder());
4234            handleAppDiedLocked(app, false, true);
4235
4236            if (doOomAdj) {
4237                updateOomAdjLocked();
4238            }
4239            if (doLowMem) {
4240                doLowMemReportIfNeededLocked(app);
4241            }
4242        } else if (app.pid != pid) {
4243            // A new process has already been started.
4244            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4245                    + ") has died and restarted (pid " + app.pid + ").");
4246            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4247        } else if (DEBUG_PROCESSES) {
4248            Slog.d(TAG, "Received spurious death notification for thread "
4249                    + thread.asBinder());
4250        }
4251    }
4252
4253    /**
4254     * If a stack trace dump file is configured, dump process stack traces.
4255     * @param clearTraces causes the dump file to be erased prior to the new
4256     *    traces being written, if true; when false, the new traces will be
4257     *    appended to any existing file content.
4258     * @param firstPids of dalvik VM processes to dump stack traces for first
4259     * @param lastPids of dalvik VM processes to dump stack traces for last
4260     * @param nativeProcs optional list of native process names to dump stack crawls
4261     * @return file containing stack traces, or null if no dump file is configured
4262     */
4263    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4264            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4265        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4266        if (tracesPath == null || tracesPath.length() == 0) {
4267            return null;
4268        }
4269
4270        File tracesFile = new File(tracesPath);
4271        try {
4272            File tracesDir = tracesFile.getParentFile();
4273            if (!tracesDir.exists()) {
4274                tracesFile.mkdirs();
4275                if (!SELinux.restorecon(tracesDir)) {
4276                    return null;
4277                }
4278            }
4279            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4280
4281            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4282            tracesFile.createNewFile();
4283            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4284        } catch (IOException e) {
4285            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4286            return null;
4287        }
4288
4289        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4290        return tracesFile;
4291    }
4292
4293    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4294            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4295        // Use a FileObserver to detect when traces finish writing.
4296        // The order of traces is considered important to maintain for legibility.
4297        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4298            @Override
4299            public synchronized void onEvent(int event, String path) { notify(); }
4300        };
4301
4302        try {
4303            observer.startWatching();
4304
4305            // First collect all of the stacks of the most important pids.
4306            if (firstPids != null) {
4307                try {
4308                    int num = firstPids.size();
4309                    for (int i = 0; i < num; i++) {
4310                        synchronized (observer) {
4311                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4312                            observer.wait(200);  // Wait for write-close, give up after 200msec
4313                        }
4314                    }
4315                } catch (InterruptedException e) {
4316                    Log.wtf(TAG, e);
4317                }
4318            }
4319
4320            // Next collect the stacks of the native pids
4321            if (nativeProcs != null) {
4322                int[] pids = Process.getPidsForCommands(nativeProcs);
4323                if (pids != null) {
4324                    for (int pid : pids) {
4325                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4326                    }
4327                }
4328            }
4329
4330            // Lastly, measure CPU usage.
4331            if (processCpuTracker != null) {
4332                processCpuTracker.init();
4333                System.gc();
4334                processCpuTracker.update();
4335                try {
4336                    synchronized (processCpuTracker) {
4337                        processCpuTracker.wait(500); // measure over 1/2 second.
4338                    }
4339                } catch (InterruptedException e) {
4340                }
4341                processCpuTracker.update();
4342
4343                // We'll take the stack crawls of just the top apps using CPU.
4344                final int N = processCpuTracker.countWorkingStats();
4345                int numProcs = 0;
4346                for (int i=0; i<N && numProcs<5; i++) {
4347                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4348                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4349                        numProcs++;
4350                        try {
4351                            synchronized (observer) {
4352                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4353                                observer.wait(200);  // Wait for write-close, give up after 200msec
4354                            }
4355                        } catch (InterruptedException e) {
4356                            Log.wtf(TAG, e);
4357                        }
4358
4359                    }
4360                }
4361            }
4362        } finally {
4363            observer.stopWatching();
4364        }
4365    }
4366
4367    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4368        if (true || IS_USER_BUILD) {
4369            return;
4370        }
4371        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4372        if (tracesPath == null || tracesPath.length() == 0) {
4373            return;
4374        }
4375
4376        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4377        StrictMode.allowThreadDiskWrites();
4378        try {
4379            final File tracesFile = new File(tracesPath);
4380            final File tracesDir = tracesFile.getParentFile();
4381            final File tracesTmp = new File(tracesDir, "__tmp__");
4382            try {
4383                if (!tracesDir.exists()) {
4384                    tracesFile.mkdirs();
4385                    if (!SELinux.restorecon(tracesDir.getPath())) {
4386                        return;
4387                    }
4388                }
4389                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4390
4391                if (tracesFile.exists()) {
4392                    tracesTmp.delete();
4393                    tracesFile.renameTo(tracesTmp);
4394                }
4395                StringBuilder sb = new StringBuilder();
4396                Time tobj = new Time();
4397                tobj.set(System.currentTimeMillis());
4398                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4399                sb.append(": ");
4400                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4401                sb.append(" since ");
4402                sb.append(msg);
4403                FileOutputStream fos = new FileOutputStream(tracesFile);
4404                fos.write(sb.toString().getBytes());
4405                if (app == null) {
4406                    fos.write("\n*** No application process!".getBytes());
4407                }
4408                fos.close();
4409                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4410            } catch (IOException e) {
4411                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4412                return;
4413            }
4414
4415            if (app != null) {
4416                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4417                firstPids.add(app.pid);
4418                dumpStackTraces(tracesPath, firstPids, null, null, null);
4419            }
4420
4421            File lastTracesFile = null;
4422            File curTracesFile = null;
4423            for (int i=9; i>=0; i--) {
4424                String name = String.format(Locale.US, "slow%02d.txt", i);
4425                curTracesFile = new File(tracesDir, name);
4426                if (curTracesFile.exists()) {
4427                    if (lastTracesFile != null) {
4428                        curTracesFile.renameTo(lastTracesFile);
4429                    } else {
4430                        curTracesFile.delete();
4431                    }
4432                }
4433                lastTracesFile = curTracesFile;
4434            }
4435            tracesFile.renameTo(curTracesFile);
4436            if (tracesTmp.exists()) {
4437                tracesTmp.renameTo(tracesFile);
4438            }
4439        } finally {
4440            StrictMode.setThreadPolicy(oldPolicy);
4441        }
4442    }
4443
4444    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4445            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4446        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4447        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4448
4449        if (mController != null) {
4450            try {
4451                // 0 == continue, -1 = kill process immediately
4452                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4453                if (res < 0 && app.pid != MY_PID) {
4454                    Process.killProcess(app.pid);
4455                    Process.killProcessGroup(app.info.uid, app.pid);
4456                }
4457            } catch (RemoteException e) {
4458                mController = null;
4459                Watchdog.getInstance().setActivityController(null);
4460            }
4461        }
4462
4463        long anrTime = SystemClock.uptimeMillis();
4464        if (MONITOR_CPU_USAGE) {
4465            updateCpuStatsNow();
4466        }
4467
4468        synchronized (this) {
4469            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4470            if (mShuttingDown) {
4471                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4472                return;
4473            } else if (app.notResponding) {
4474                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4475                return;
4476            } else if (app.crashing) {
4477                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4478                return;
4479            }
4480
4481            // In case we come through here for the same app before completing
4482            // this one, mark as anring now so we will bail out.
4483            app.notResponding = true;
4484
4485            // Log the ANR to the event log.
4486            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4487                    app.processName, app.info.flags, annotation);
4488
4489            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4490            firstPids.add(app.pid);
4491
4492            int parentPid = app.pid;
4493            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4494            if (parentPid != app.pid) firstPids.add(parentPid);
4495
4496            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4497
4498            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4499                ProcessRecord r = mLruProcesses.get(i);
4500                if (r != null && r.thread != null) {
4501                    int pid = r.pid;
4502                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4503                        if (r.persistent) {
4504                            firstPids.add(pid);
4505                        } else {
4506                            lastPids.put(pid, Boolean.TRUE);
4507                        }
4508                    }
4509                }
4510            }
4511        }
4512
4513        // Log the ANR to the main log.
4514        StringBuilder info = new StringBuilder();
4515        info.setLength(0);
4516        info.append("ANR in ").append(app.processName);
4517        if (activity != null && activity.shortComponentName != null) {
4518            info.append(" (").append(activity.shortComponentName).append(")");
4519        }
4520        info.append("\n");
4521        info.append("PID: ").append(app.pid).append("\n");
4522        if (annotation != null) {
4523            info.append("Reason: ").append(annotation).append("\n");
4524        }
4525        if (parent != null && parent != activity) {
4526            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4527        }
4528
4529        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4530
4531        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4532                NATIVE_STACKS_OF_INTEREST);
4533
4534        String cpuInfo = null;
4535        if (MONITOR_CPU_USAGE) {
4536            updateCpuStatsNow();
4537            synchronized (mProcessCpuThread) {
4538                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4539            }
4540            info.append(processCpuTracker.printCurrentLoad());
4541            info.append(cpuInfo);
4542        }
4543
4544        info.append(processCpuTracker.printCurrentState(anrTime));
4545
4546        Slog.e(TAG, info.toString());
4547        if (tracesFile == null) {
4548            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4549            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4550        }
4551
4552        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4553                cpuInfo, tracesFile, null);
4554
4555        if (mController != null) {
4556            try {
4557                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4558                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4559                if (res != 0) {
4560                    if (res < 0 && app.pid != MY_PID) {
4561                        Process.killProcess(app.pid);
4562                        Process.killProcessGroup(app.info.uid, app.pid);
4563                    } else {
4564                        synchronized (this) {
4565                            mServices.scheduleServiceTimeoutLocked(app);
4566                        }
4567                    }
4568                    return;
4569                }
4570            } catch (RemoteException e) {
4571                mController = null;
4572                Watchdog.getInstance().setActivityController(null);
4573            }
4574        }
4575
4576        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4577        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4578                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4579
4580        synchronized (this) {
4581            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4582                killUnneededProcessLocked(app, "background ANR");
4583                return;
4584            }
4585
4586            // Set the app's notResponding state, and look up the errorReportReceiver
4587            makeAppNotRespondingLocked(app,
4588                    activity != null ? activity.shortComponentName : null,
4589                    annotation != null ? "ANR " + annotation : "ANR",
4590                    info.toString());
4591
4592            // Bring up the infamous App Not Responding dialog
4593            Message msg = Message.obtain();
4594            HashMap<String, Object> map = new HashMap<String, Object>();
4595            msg.what = SHOW_NOT_RESPONDING_MSG;
4596            msg.obj = map;
4597            msg.arg1 = aboveSystem ? 1 : 0;
4598            map.put("app", app);
4599            if (activity != null) {
4600                map.put("activity", activity);
4601            }
4602
4603            mHandler.sendMessage(msg);
4604        }
4605    }
4606
4607    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4608        if (!mLaunchWarningShown) {
4609            mLaunchWarningShown = true;
4610            mHandler.post(new Runnable() {
4611                @Override
4612                public void run() {
4613                    synchronized (ActivityManagerService.this) {
4614                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4615                        d.show();
4616                        mHandler.postDelayed(new Runnable() {
4617                            @Override
4618                            public void run() {
4619                                synchronized (ActivityManagerService.this) {
4620                                    d.dismiss();
4621                                    mLaunchWarningShown = false;
4622                                }
4623                            }
4624                        }, 4000);
4625                    }
4626                }
4627            });
4628        }
4629    }
4630
4631    @Override
4632    public boolean clearApplicationUserData(final String packageName,
4633            final IPackageDataObserver observer, int userId) {
4634        enforceNotIsolatedCaller("clearApplicationUserData");
4635        int uid = Binder.getCallingUid();
4636        int pid = Binder.getCallingPid();
4637        userId = handleIncomingUser(pid, uid,
4638                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4639        long callingId = Binder.clearCallingIdentity();
4640        try {
4641            IPackageManager pm = AppGlobals.getPackageManager();
4642            int pkgUid = -1;
4643            synchronized(this) {
4644                try {
4645                    pkgUid = pm.getPackageUid(packageName, userId);
4646                } catch (RemoteException e) {
4647                }
4648                if (pkgUid == -1) {
4649                    Slog.w(TAG, "Invalid packageName: " + packageName);
4650                    if (observer != null) {
4651                        try {
4652                            observer.onRemoveCompleted(packageName, false);
4653                        } catch (RemoteException e) {
4654                            Slog.i(TAG, "Observer no longer exists.");
4655                        }
4656                    }
4657                    return false;
4658                }
4659                if (uid == pkgUid || checkComponentPermission(
4660                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4661                        pid, uid, -1, true)
4662                        == PackageManager.PERMISSION_GRANTED) {
4663                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4664                } else {
4665                    throw new SecurityException("PID " + pid + " does not have permission "
4666                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4667                                    + " of package " + packageName);
4668                }
4669            }
4670
4671            try {
4672                // Clear application user data
4673                pm.clearApplicationUserData(packageName, observer, userId);
4674
4675                // Remove all permissions granted from/to this package
4676                removeUriPermissionsForPackageLocked(packageName, userId, true);
4677
4678                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4679                        Uri.fromParts("package", packageName, null));
4680                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4681                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4682                        null, null, 0, null, null, null, false, false, userId);
4683            } catch (RemoteException e) {
4684            }
4685        } finally {
4686            Binder.restoreCallingIdentity(callingId);
4687        }
4688        return true;
4689    }
4690
4691    @Override
4692    public void killBackgroundProcesses(final String packageName, int userId) {
4693        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4694                != PackageManager.PERMISSION_GRANTED &&
4695                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4696                        != PackageManager.PERMISSION_GRANTED) {
4697            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4698                    + Binder.getCallingPid()
4699                    + ", uid=" + Binder.getCallingUid()
4700                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4701            Slog.w(TAG, msg);
4702            throw new SecurityException(msg);
4703        }
4704
4705        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4706                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4707        long callingId = Binder.clearCallingIdentity();
4708        try {
4709            IPackageManager pm = AppGlobals.getPackageManager();
4710            synchronized(this) {
4711                int appId = -1;
4712                try {
4713                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4714                } catch (RemoteException e) {
4715                }
4716                if (appId == -1) {
4717                    Slog.w(TAG, "Invalid packageName: " + packageName);
4718                    return;
4719                }
4720                killPackageProcessesLocked(packageName, appId, userId,
4721                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4722            }
4723        } finally {
4724            Binder.restoreCallingIdentity(callingId);
4725        }
4726    }
4727
4728    @Override
4729    public void killAllBackgroundProcesses() {
4730        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4731                != PackageManager.PERMISSION_GRANTED) {
4732            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4733                    + Binder.getCallingPid()
4734                    + ", uid=" + Binder.getCallingUid()
4735                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4736            Slog.w(TAG, msg);
4737            throw new SecurityException(msg);
4738        }
4739
4740        long callingId = Binder.clearCallingIdentity();
4741        try {
4742            synchronized(this) {
4743                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4744                final int NP = mProcessNames.getMap().size();
4745                for (int ip=0; ip<NP; ip++) {
4746                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4747                    final int NA = apps.size();
4748                    for (int ia=0; ia<NA; ia++) {
4749                        ProcessRecord app = apps.valueAt(ia);
4750                        if (app.persistent) {
4751                            // we don't kill persistent processes
4752                            continue;
4753                        }
4754                        if (app.removed) {
4755                            procs.add(app);
4756                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4757                            app.removed = true;
4758                            procs.add(app);
4759                        }
4760                    }
4761                }
4762
4763                int N = procs.size();
4764                for (int i=0; i<N; i++) {
4765                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4766                }
4767                mAllowLowerMemLevel = true;
4768                updateOomAdjLocked();
4769                doLowMemReportIfNeededLocked(null);
4770            }
4771        } finally {
4772            Binder.restoreCallingIdentity(callingId);
4773        }
4774    }
4775
4776    @Override
4777    public void forceStopPackage(final String packageName, int userId) {
4778        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4779                != PackageManager.PERMISSION_GRANTED) {
4780            String msg = "Permission Denial: forceStopPackage() from pid="
4781                    + Binder.getCallingPid()
4782                    + ", uid=" + Binder.getCallingUid()
4783                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4784            Slog.w(TAG, msg);
4785            throw new SecurityException(msg);
4786        }
4787        final int callingPid = Binder.getCallingPid();
4788        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4789                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4790        long callingId = Binder.clearCallingIdentity();
4791        try {
4792            IPackageManager pm = AppGlobals.getPackageManager();
4793            synchronized(this) {
4794                int[] users = userId == UserHandle.USER_ALL
4795                        ? getUsersLocked() : new int[] { userId };
4796                for (int user : users) {
4797                    int pkgUid = -1;
4798                    try {
4799                        pkgUid = pm.getPackageUid(packageName, user);
4800                    } catch (RemoteException e) {
4801                    }
4802                    if (pkgUid == -1) {
4803                        Slog.w(TAG, "Invalid packageName: " + packageName);
4804                        continue;
4805                    }
4806                    try {
4807                        pm.setPackageStoppedState(packageName, true, user);
4808                    } catch (RemoteException e) {
4809                    } catch (IllegalArgumentException e) {
4810                        Slog.w(TAG, "Failed trying to unstop package "
4811                                + packageName + ": " + e);
4812                    }
4813                    if (isUserRunningLocked(user, false)) {
4814                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4815                    }
4816                }
4817            }
4818        } finally {
4819            Binder.restoreCallingIdentity(callingId);
4820        }
4821    }
4822
4823    @Override
4824    public void addPackageDependency(String packageName) {
4825        synchronized (this) {
4826            int callingPid = Binder.getCallingPid();
4827            if (callingPid == Process.myPid()) {
4828                //  Yeah, um, no.
4829                Slog.w(TAG, "Can't addPackageDependency on system process");
4830                return;
4831            }
4832            ProcessRecord proc;
4833            synchronized (mPidsSelfLocked) {
4834                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4835            }
4836            if (proc != null) {
4837                if (proc.pkgDeps == null) {
4838                    proc.pkgDeps = new ArraySet<String>(1);
4839                }
4840                proc.pkgDeps.add(packageName);
4841            }
4842        }
4843    }
4844
4845    /*
4846     * The pkg name and app id have to be specified.
4847     */
4848    @Override
4849    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4850        if (pkg == null) {
4851            return;
4852        }
4853        // Make sure the uid is valid.
4854        if (appid < 0) {
4855            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4856            return;
4857        }
4858        int callerUid = Binder.getCallingUid();
4859        // Only the system server can kill an application
4860        if (callerUid == Process.SYSTEM_UID) {
4861            // Post an aysnc message to kill the application
4862            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4863            msg.arg1 = appid;
4864            msg.arg2 = 0;
4865            Bundle bundle = new Bundle();
4866            bundle.putString("pkg", pkg);
4867            bundle.putString("reason", reason);
4868            msg.obj = bundle;
4869            mHandler.sendMessage(msg);
4870        } else {
4871            throw new SecurityException(callerUid + " cannot kill pkg: " +
4872                    pkg);
4873        }
4874    }
4875
4876    @Override
4877    public void closeSystemDialogs(String reason) {
4878        enforceNotIsolatedCaller("closeSystemDialogs");
4879
4880        final int pid = Binder.getCallingPid();
4881        final int uid = Binder.getCallingUid();
4882        final long origId = Binder.clearCallingIdentity();
4883        try {
4884            synchronized (this) {
4885                // Only allow this from foreground processes, so that background
4886                // applications can't abuse it to prevent system UI from being shown.
4887                if (uid >= Process.FIRST_APPLICATION_UID) {
4888                    ProcessRecord proc;
4889                    synchronized (mPidsSelfLocked) {
4890                        proc = mPidsSelfLocked.get(pid);
4891                    }
4892                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4893                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4894                                + " from background process " + proc);
4895                        return;
4896                    }
4897                }
4898                closeSystemDialogsLocked(reason);
4899            }
4900        } finally {
4901            Binder.restoreCallingIdentity(origId);
4902        }
4903    }
4904
4905    void closeSystemDialogsLocked(String reason) {
4906        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4907        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4908                | Intent.FLAG_RECEIVER_FOREGROUND);
4909        if (reason != null) {
4910            intent.putExtra("reason", reason);
4911        }
4912        mWindowManager.closeSystemDialogs(reason);
4913
4914        mStackSupervisor.closeSystemDialogsLocked();
4915
4916        broadcastIntentLocked(null, null, intent, null,
4917                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4918                Process.SYSTEM_UID, UserHandle.USER_ALL);
4919    }
4920
4921    @Override
4922    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4923        enforceNotIsolatedCaller("getProcessMemoryInfo");
4924        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4925        for (int i=pids.length-1; i>=0; i--) {
4926            ProcessRecord proc;
4927            int oomAdj;
4928            synchronized (this) {
4929                synchronized (mPidsSelfLocked) {
4930                    proc = mPidsSelfLocked.get(pids[i]);
4931                    oomAdj = proc != null ? proc.setAdj : 0;
4932                }
4933            }
4934            infos[i] = new Debug.MemoryInfo();
4935            Debug.getMemoryInfo(pids[i], infos[i]);
4936            if (proc != null) {
4937                synchronized (this) {
4938                    if (proc.thread != null && proc.setAdj == oomAdj) {
4939                        // Record this for posterity if the process has been stable.
4940                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4941                                infos[i].getTotalUss(), false, proc.pkgList);
4942                    }
4943                }
4944            }
4945        }
4946        return infos;
4947    }
4948
4949    @Override
4950    public long[] getProcessPss(int[] pids) {
4951        enforceNotIsolatedCaller("getProcessPss");
4952        long[] pss = new long[pids.length];
4953        for (int i=pids.length-1; i>=0; i--) {
4954            ProcessRecord proc;
4955            int oomAdj;
4956            synchronized (this) {
4957                synchronized (mPidsSelfLocked) {
4958                    proc = mPidsSelfLocked.get(pids[i]);
4959                    oomAdj = proc != null ? proc.setAdj : 0;
4960                }
4961            }
4962            long[] tmpUss = new long[1];
4963            pss[i] = Debug.getPss(pids[i], tmpUss);
4964            if (proc != null) {
4965                synchronized (this) {
4966                    if (proc.thread != null && proc.setAdj == oomAdj) {
4967                        // Record this for posterity if the process has been stable.
4968                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4969                    }
4970                }
4971            }
4972        }
4973        return pss;
4974    }
4975
4976    @Override
4977    public void killApplicationProcess(String processName, int uid) {
4978        if (processName == null) {
4979            return;
4980        }
4981
4982        int callerUid = Binder.getCallingUid();
4983        // Only the system server can kill an application
4984        if (callerUid == Process.SYSTEM_UID) {
4985            synchronized (this) {
4986                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4987                if (app != null && app.thread != null) {
4988                    try {
4989                        app.thread.scheduleSuicide();
4990                    } catch (RemoteException e) {
4991                        // If the other end already died, then our work here is done.
4992                    }
4993                } else {
4994                    Slog.w(TAG, "Process/uid not found attempting kill of "
4995                            + processName + " / " + uid);
4996                }
4997            }
4998        } else {
4999            throw new SecurityException(callerUid + " cannot kill app process: " +
5000                    processName);
5001        }
5002    }
5003
5004    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5005        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5006                false, true, false, false, UserHandle.getUserId(uid), reason);
5007        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5008                Uri.fromParts("package", packageName, null));
5009        if (!mProcessesReady) {
5010            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5011                    | Intent.FLAG_RECEIVER_FOREGROUND);
5012        }
5013        intent.putExtra(Intent.EXTRA_UID, uid);
5014        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5015        broadcastIntentLocked(null, null, intent,
5016                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5017                false, false,
5018                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5019    }
5020
5021    private void forceStopUserLocked(int userId, String reason) {
5022        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5023        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5024        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5025                | Intent.FLAG_RECEIVER_FOREGROUND);
5026        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5027        broadcastIntentLocked(null, null, intent,
5028                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5029                false, false,
5030                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5031    }
5032
5033    private final boolean killPackageProcessesLocked(String packageName, int appId,
5034            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5035            boolean doit, boolean evenPersistent, String reason) {
5036        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5037
5038        // Remove all processes this package may have touched: all with the
5039        // same UID (except for the system or root user), and all whose name
5040        // matches the package name.
5041        final int NP = mProcessNames.getMap().size();
5042        for (int ip=0; ip<NP; ip++) {
5043            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5044            final int NA = apps.size();
5045            for (int ia=0; ia<NA; ia++) {
5046                ProcessRecord app = apps.valueAt(ia);
5047                if (app.persistent && !evenPersistent) {
5048                    // we don't kill persistent processes
5049                    continue;
5050                }
5051                if (app.removed) {
5052                    if (doit) {
5053                        procs.add(app);
5054                    }
5055                    continue;
5056                }
5057
5058                // Skip process if it doesn't meet our oom adj requirement.
5059                if (app.setAdj < minOomAdj) {
5060                    continue;
5061                }
5062
5063                // If no package is specified, we call all processes under the
5064                // give user id.
5065                if (packageName == null) {
5066                    if (app.userId != userId) {
5067                        continue;
5068                    }
5069                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5070                        continue;
5071                    }
5072                // Package has been specified, we want to hit all processes
5073                // that match it.  We need to qualify this by the processes
5074                // that are running under the specified app and user ID.
5075                } else {
5076                    final boolean isDep = app.pkgDeps != null
5077                            && app.pkgDeps.contains(packageName);
5078                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5079                        continue;
5080                    }
5081                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5082                        continue;
5083                    }
5084                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5085                        continue;
5086                    }
5087                }
5088
5089                // Process has passed all conditions, kill it!
5090                if (!doit) {
5091                    return true;
5092                }
5093                app.removed = true;
5094                procs.add(app);
5095            }
5096        }
5097
5098        int N = procs.size();
5099        for (int i=0; i<N; i++) {
5100            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5101        }
5102        updateOomAdjLocked();
5103        return N > 0;
5104    }
5105
5106    private final boolean forceStopPackageLocked(String name, int appId,
5107            boolean callerWillRestart, boolean purgeCache, boolean doit,
5108            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5109        int i;
5110        int N;
5111
5112        if (userId == UserHandle.USER_ALL && name == null) {
5113            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5114        }
5115
5116        if (appId < 0 && name != null) {
5117            try {
5118                appId = UserHandle.getAppId(
5119                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5120            } catch (RemoteException e) {
5121            }
5122        }
5123
5124        if (doit) {
5125            if (name != null) {
5126                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5127                        + " user=" + userId + ": " + reason);
5128            } else {
5129                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5130            }
5131
5132            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5133            for (int ip=pmap.size()-1; ip>=0; ip--) {
5134                SparseArray<Long> ba = pmap.valueAt(ip);
5135                for (i=ba.size()-1; i>=0; i--) {
5136                    boolean remove = false;
5137                    final int entUid = ba.keyAt(i);
5138                    if (name != null) {
5139                        if (userId == UserHandle.USER_ALL) {
5140                            if (UserHandle.getAppId(entUid) == appId) {
5141                                remove = true;
5142                            }
5143                        } else {
5144                            if (entUid == UserHandle.getUid(userId, appId)) {
5145                                remove = true;
5146                            }
5147                        }
5148                    } else if (UserHandle.getUserId(entUid) == userId) {
5149                        remove = true;
5150                    }
5151                    if (remove) {
5152                        ba.removeAt(i);
5153                    }
5154                }
5155                if (ba.size() == 0) {
5156                    pmap.removeAt(ip);
5157                }
5158            }
5159        }
5160
5161        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5162                -100, callerWillRestart, true, doit, evenPersistent,
5163                name == null ? ("stop user " + userId) : ("stop " + name));
5164
5165        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5166            if (!doit) {
5167                return true;
5168            }
5169            didSomething = true;
5170        }
5171
5172        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5173            if (!doit) {
5174                return true;
5175            }
5176            didSomething = true;
5177        }
5178
5179        if (name == null) {
5180            // Remove all sticky broadcasts from this user.
5181            mStickyBroadcasts.remove(userId);
5182        }
5183
5184        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5185        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5186                userId, providers)) {
5187            if (!doit) {
5188                return true;
5189            }
5190            didSomething = true;
5191        }
5192        N = providers.size();
5193        for (i=0; i<N; i++) {
5194            removeDyingProviderLocked(null, providers.get(i), true);
5195        }
5196
5197        // Remove transient permissions granted from/to this package/user
5198        removeUriPermissionsForPackageLocked(name, userId, false);
5199
5200        if (name == null || uninstalling) {
5201            // Remove pending intents.  For now we only do this when force
5202            // stopping users, because we have some problems when doing this
5203            // for packages -- app widgets are not currently cleaned up for
5204            // such packages, so they can be left with bad pending intents.
5205            if (mIntentSenderRecords.size() > 0) {
5206                Iterator<WeakReference<PendingIntentRecord>> it
5207                        = mIntentSenderRecords.values().iterator();
5208                while (it.hasNext()) {
5209                    WeakReference<PendingIntentRecord> wpir = it.next();
5210                    if (wpir == null) {
5211                        it.remove();
5212                        continue;
5213                    }
5214                    PendingIntentRecord pir = wpir.get();
5215                    if (pir == null) {
5216                        it.remove();
5217                        continue;
5218                    }
5219                    if (name == null) {
5220                        // Stopping user, remove all objects for the user.
5221                        if (pir.key.userId != userId) {
5222                            // Not the same user, skip it.
5223                            continue;
5224                        }
5225                    } else {
5226                        if (UserHandle.getAppId(pir.uid) != appId) {
5227                            // Different app id, skip it.
5228                            continue;
5229                        }
5230                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5231                            // Different user, skip it.
5232                            continue;
5233                        }
5234                        if (!pir.key.packageName.equals(name)) {
5235                            // Different package, skip it.
5236                            continue;
5237                        }
5238                    }
5239                    if (!doit) {
5240                        return true;
5241                    }
5242                    didSomething = true;
5243                    it.remove();
5244                    pir.canceled = true;
5245                    if (pir.key.activity != null) {
5246                        pir.key.activity.pendingResults.remove(pir.ref);
5247                    }
5248                }
5249            }
5250        }
5251
5252        if (doit) {
5253            if (purgeCache && name != null) {
5254                AttributeCache ac = AttributeCache.instance();
5255                if (ac != null) {
5256                    ac.removePackage(name);
5257                }
5258            }
5259            if (mBooted) {
5260                mStackSupervisor.resumeTopActivitiesLocked();
5261                mStackSupervisor.scheduleIdleLocked();
5262            }
5263        }
5264
5265        return didSomething;
5266    }
5267
5268    private final boolean removeProcessLocked(ProcessRecord app,
5269            boolean callerWillRestart, boolean allowRestart, String reason) {
5270        final String name = app.processName;
5271        final int uid = app.uid;
5272        if (DEBUG_PROCESSES) Slog.d(
5273            TAG, "Force removing proc " + app.toShortString() + " (" + name
5274            + "/" + uid + ")");
5275
5276        mProcessNames.remove(name, uid);
5277        mIsolatedProcesses.remove(app.uid);
5278        if (mHeavyWeightProcess == app) {
5279            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5280                    mHeavyWeightProcess.userId, 0));
5281            mHeavyWeightProcess = null;
5282        }
5283        boolean needRestart = false;
5284        if (app.pid > 0 && app.pid != MY_PID) {
5285            int pid = app.pid;
5286            synchronized (mPidsSelfLocked) {
5287                mPidsSelfLocked.remove(pid);
5288                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5289            }
5290            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5291            if (app.isolated) {
5292                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5293            }
5294            killUnneededProcessLocked(app, reason);
5295            Process.killProcessGroup(app.info.uid, app.pid);
5296            handleAppDiedLocked(app, true, allowRestart);
5297            removeLruProcessLocked(app);
5298
5299            if (app.persistent && !app.isolated) {
5300                if (!callerWillRestart) {
5301                    addAppLocked(app.info, false, null /* ABI override */);
5302                } else {
5303                    needRestart = true;
5304                }
5305            }
5306        } else {
5307            mRemovedProcesses.add(app);
5308        }
5309
5310        return needRestart;
5311    }
5312
5313    private final void processStartTimedOutLocked(ProcessRecord app) {
5314        final int pid = app.pid;
5315        boolean gone = false;
5316        synchronized (mPidsSelfLocked) {
5317            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5318            if (knownApp != null && knownApp.thread == null) {
5319                mPidsSelfLocked.remove(pid);
5320                gone = true;
5321            }
5322        }
5323
5324        if (gone) {
5325            Slog.w(TAG, "Process " + app + " failed to attach");
5326            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5327                    pid, app.uid, app.processName);
5328            mProcessNames.remove(app.processName, app.uid);
5329            mIsolatedProcesses.remove(app.uid);
5330            if (mHeavyWeightProcess == app) {
5331                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5332                        mHeavyWeightProcess.userId, 0));
5333                mHeavyWeightProcess = null;
5334            }
5335            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5336            if (app.isolated) {
5337                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5338            }
5339            // Take care of any launching providers waiting for this process.
5340            checkAppInLaunchingProvidersLocked(app, true);
5341            // Take care of any services that are waiting for the process.
5342            mServices.processStartTimedOutLocked(app);
5343            killUnneededProcessLocked(app, "start timeout");
5344            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5345                Slog.w(TAG, "Unattached app died before backup, skipping");
5346                try {
5347                    IBackupManager bm = IBackupManager.Stub.asInterface(
5348                            ServiceManager.getService(Context.BACKUP_SERVICE));
5349                    bm.agentDisconnected(app.info.packageName);
5350                } catch (RemoteException e) {
5351                    // Can't happen; the backup manager is local
5352                }
5353            }
5354            if (isPendingBroadcastProcessLocked(pid)) {
5355                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5356                skipPendingBroadcastLocked(pid);
5357            }
5358        } else {
5359            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5360        }
5361    }
5362
5363    private final boolean attachApplicationLocked(IApplicationThread thread,
5364            int pid) {
5365
5366        // Find the application record that is being attached...  either via
5367        // the pid if we are running in multiple processes, or just pull the
5368        // next app record if we are emulating process with anonymous threads.
5369        ProcessRecord app;
5370        if (pid != MY_PID && pid >= 0) {
5371            synchronized (mPidsSelfLocked) {
5372                app = mPidsSelfLocked.get(pid);
5373            }
5374        } else {
5375            app = null;
5376        }
5377
5378        if (app == null) {
5379            Slog.w(TAG, "No pending application record for pid " + pid
5380                    + " (IApplicationThread " + thread + "); dropping process");
5381            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5382            if (pid > 0 && pid != MY_PID) {
5383                Process.killProcessQuiet(pid);
5384                //TODO: Process.killProcessGroup(app.info.uid, pid);
5385            } else {
5386                try {
5387                    thread.scheduleExit();
5388                } catch (Exception e) {
5389                    // Ignore exceptions.
5390                }
5391            }
5392            return false;
5393        }
5394
5395        // If this application record is still attached to a previous
5396        // process, clean it up now.
5397        if (app.thread != null) {
5398            handleAppDiedLocked(app, true, true);
5399        }
5400
5401        // Tell the process all about itself.
5402
5403        if (localLOGV) Slog.v(
5404                TAG, "Binding process pid " + pid + " to record " + app);
5405
5406        final String processName = app.processName;
5407        try {
5408            AppDeathRecipient adr = new AppDeathRecipient(
5409                    app, pid, thread);
5410            thread.asBinder().linkToDeath(adr, 0);
5411            app.deathRecipient = adr;
5412        } catch (RemoteException e) {
5413            app.resetPackageList(mProcessStats);
5414            startProcessLocked(app, "link fail", processName);
5415            return false;
5416        }
5417
5418        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5419
5420        app.makeActive(thread, mProcessStats);
5421        app.curAdj = app.setAdj = -100;
5422        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5423        app.forcingToForeground = null;
5424        updateProcessForegroundLocked(app, false, false);
5425        app.hasShownUi = false;
5426        app.debugging = false;
5427        app.cached = false;
5428
5429        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5430
5431        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5432        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5433
5434        if (!normalMode) {
5435            Slog.i(TAG, "Launching preboot mode app: " + app);
5436        }
5437
5438        if (localLOGV) Slog.v(
5439            TAG, "New app record " + app
5440            + " thread=" + thread.asBinder() + " pid=" + pid);
5441        try {
5442            int testMode = IApplicationThread.DEBUG_OFF;
5443            if (mDebugApp != null && mDebugApp.equals(processName)) {
5444                testMode = mWaitForDebugger
5445                    ? IApplicationThread.DEBUG_WAIT
5446                    : IApplicationThread.DEBUG_ON;
5447                app.debugging = true;
5448                if (mDebugTransient) {
5449                    mDebugApp = mOrigDebugApp;
5450                    mWaitForDebugger = mOrigWaitForDebugger;
5451                }
5452            }
5453            String profileFile = app.instrumentationProfileFile;
5454            ParcelFileDescriptor profileFd = null;
5455            boolean profileAutoStop = false;
5456            if (mProfileApp != null && mProfileApp.equals(processName)) {
5457                mProfileProc = app;
5458                profileFile = mProfileFile;
5459                profileFd = mProfileFd;
5460                profileAutoStop = mAutoStopProfiler;
5461            }
5462            boolean enableOpenGlTrace = false;
5463            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5464                enableOpenGlTrace = true;
5465                mOpenGlTraceApp = null;
5466            }
5467
5468            // If the app is being launched for restore or full backup, set it up specially
5469            boolean isRestrictedBackupMode = false;
5470            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5471                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5472                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5473                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5474            }
5475
5476            ensurePackageDexOpt(app.instrumentationInfo != null
5477                    ? app.instrumentationInfo.packageName
5478                    : app.info.packageName);
5479            if (app.instrumentationClass != null) {
5480                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5481            }
5482            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5483                    + processName + " with config " + mConfiguration);
5484            ApplicationInfo appInfo = app.instrumentationInfo != null
5485                    ? app.instrumentationInfo : app.info;
5486            app.compat = compatibilityInfoForPackageLocked(appInfo);
5487            if (profileFd != null) {
5488                profileFd = profileFd.dup();
5489            }
5490            thread.bindApplication(processName, appInfo, providers,
5491                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5492                    app.instrumentationArguments, app.instrumentationWatcher,
5493                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5494                    isRestrictedBackupMode || !normalMode, app.persistent,
5495                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5496                    mCoreSettingsObserver.getCoreSettingsLocked());
5497            updateLruProcessLocked(app, false, null);
5498            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5499        } catch (Exception e) {
5500            // todo: Yikes!  What should we do?  For now we will try to
5501            // start another process, but that could easily get us in
5502            // an infinite loop of restarting processes...
5503            Slog.w(TAG, "Exception thrown during bind!", e);
5504
5505            app.resetPackageList(mProcessStats);
5506            app.unlinkDeathRecipient();
5507            startProcessLocked(app, "bind fail", processName);
5508            return false;
5509        }
5510
5511        // Remove this record from the list of starting applications.
5512        mPersistentStartingProcesses.remove(app);
5513        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5514                "Attach application locked removing on hold: " + app);
5515        mProcessesOnHold.remove(app);
5516
5517        boolean badApp = false;
5518        boolean didSomething = false;
5519
5520        // See if the top visible activity is waiting to run in this process...
5521        if (normalMode) {
5522            try {
5523                if (mStackSupervisor.attachApplicationLocked(app)) {
5524                    didSomething = true;
5525                }
5526            } catch (Exception e) {
5527                badApp = true;
5528            }
5529        }
5530
5531        // Find any services that should be running in this process...
5532        if (!badApp) {
5533            try {
5534                didSomething |= mServices.attachApplicationLocked(app, processName);
5535            } catch (Exception e) {
5536                badApp = true;
5537            }
5538        }
5539
5540        // Check if a next-broadcast receiver is in this process...
5541        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5542            try {
5543                didSomething |= sendPendingBroadcastsLocked(app);
5544            } catch (Exception e) {
5545                // If the app died trying to launch the receiver we declare it 'bad'
5546                badApp = true;
5547            }
5548        }
5549
5550        // Check whether the next backup agent is in this process...
5551        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5552            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5553            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5554            try {
5555                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5556                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5557                        mBackupTarget.backupMode);
5558            } catch (Exception e) {
5559                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5560                e.printStackTrace();
5561            }
5562        }
5563
5564        if (badApp) {
5565            // todo: Also need to kill application to deal with all
5566            // kinds of exceptions.
5567            handleAppDiedLocked(app, false, true);
5568            return false;
5569        }
5570
5571        if (!didSomething) {
5572            updateOomAdjLocked();
5573        }
5574
5575        return true;
5576    }
5577
5578    @Override
5579    public final void attachApplication(IApplicationThread thread) {
5580        synchronized (this) {
5581            int callingPid = Binder.getCallingPid();
5582            final long origId = Binder.clearCallingIdentity();
5583            attachApplicationLocked(thread, callingPid);
5584            Binder.restoreCallingIdentity(origId);
5585        }
5586    }
5587
5588    @Override
5589    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5590        final long origId = Binder.clearCallingIdentity();
5591        synchronized (this) {
5592            ActivityStack stack = ActivityRecord.getStackLocked(token);
5593            if (stack != null) {
5594                ActivityRecord r =
5595                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5596                if (stopProfiling) {
5597                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5598                        try {
5599                            mProfileFd.close();
5600                        } catch (IOException e) {
5601                        }
5602                        clearProfilerLocked();
5603                    }
5604                }
5605            }
5606        }
5607        Binder.restoreCallingIdentity(origId);
5608    }
5609
5610    void postEnableScreenAfterBootLocked() {
5611        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
5612    }
5613
5614    void enableScreenAfterBoot() {
5615        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5616                SystemClock.uptimeMillis());
5617        mWindowManager.enableScreenAfterBoot();
5618
5619        synchronized (this) {
5620            updateEventDispatchingLocked();
5621        }
5622    }
5623
5624    @Override
5625    public void showBootMessage(final CharSequence msg, final boolean always) {
5626        enforceNotIsolatedCaller("showBootMessage");
5627        mWindowManager.showBootMessage(msg, always);
5628    }
5629
5630    @Override
5631    public void dismissKeyguardOnNextActivity() {
5632        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5633        final long token = Binder.clearCallingIdentity();
5634        try {
5635            synchronized (this) {
5636                if (DEBUG_LOCKSCREEN) logLockScreen("");
5637                if (mLockScreenShown) {
5638                    mLockScreenShown = false;
5639                    comeOutOfSleepIfNeededLocked();
5640                }
5641                mStackSupervisor.setDismissKeyguard(true);
5642            }
5643        } finally {
5644            Binder.restoreCallingIdentity(token);
5645        }
5646    }
5647
5648    final void finishBooting() {
5649        // Register receivers to handle package update events
5650        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5651
5652        synchronized (this) {
5653            // Ensure that any processes we had put on hold are now started
5654            // up.
5655            final int NP = mProcessesOnHold.size();
5656            if (NP > 0) {
5657                ArrayList<ProcessRecord> procs =
5658                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5659                for (int ip=0; ip<NP; ip++) {
5660                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5661                            + procs.get(ip));
5662                    startProcessLocked(procs.get(ip), "on-hold", null);
5663                }
5664            }
5665
5666            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5667                // Start looking for apps that are abusing wake locks.
5668                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5669                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5670                // Tell anyone interested that we are done booting!
5671                SystemProperties.set("sys.boot_completed", "1");
5672                SystemProperties.set("dev.bootcomplete", "1");
5673                for (int i=0; i<mStartedUsers.size(); i++) {
5674                    UserStartedState uss = mStartedUsers.valueAt(i);
5675                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5676                        uss.mState = UserStartedState.STATE_RUNNING;
5677                        final int userId = mStartedUsers.keyAt(i);
5678                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5679                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5680                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5681                        broadcastIntentLocked(null, null, intent, null,
5682                                new IIntentReceiver.Stub() {
5683                                    @Override
5684                                    public void performReceive(Intent intent, int resultCode,
5685                                            String data, Bundle extras, boolean ordered,
5686                                            boolean sticky, int sendingUser) {
5687                                        synchronized (ActivityManagerService.this) {
5688                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5689                                                    true, false);
5690                                        }
5691                                    }
5692                                },
5693                                0, null, null,
5694                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5695                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5696                                userId);
5697                    }
5698                }
5699                scheduleStartProfilesLocked();
5700            }
5701        }
5702    }
5703
5704    final void ensureBootCompleted() {
5705        boolean booting;
5706        boolean enableScreen;
5707        synchronized (this) {
5708            booting = mBooting;
5709            mBooting = false;
5710            enableScreen = !mBooted;
5711            mBooted = true;
5712        }
5713
5714        if (booting) {
5715            finishBooting();
5716        }
5717
5718        if (enableScreen) {
5719            enableScreenAfterBoot();
5720        }
5721    }
5722
5723    @Override
5724    public final void activityResumed(IBinder token) {
5725        final long origId = Binder.clearCallingIdentity();
5726        synchronized(this) {
5727            ActivityStack stack = ActivityRecord.getStackLocked(token);
5728            if (stack != null) {
5729                ActivityRecord.activityResumedLocked(token);
5730            }
5731        }
5732        Binder.restoreCallingIdentity(origId);
5733    }
5734
5735    @Override
5736    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5737        final long origId = Binder.clearCallingIdentity();
5738        synchronized(this) {
5739            ActivityStack stack = ActivityRecord.getStackLocked(token);
5740            if (stack != null) {
5741                stack.activityPausedLocked(token, false, persistentState);
5742            }
5743        }
5744        Binder.restoreCallingIdentity(origId);
5745    }
5746
5747    @Override
5748    public final void activityStopped(IBinder token, Bundle icicle,
5749            PersistableBundle persistentState, CharSequence description) {
5750        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5751
5752        // Refuse possible leaked file descriptors
5753        if (icicle != null && icicle.hasFileDescriptors()) {
5754            throw new IllegalArgumentException("File descriptors passed in Bundle");
5755        }
5756
5757        final long origId = Binder.clearCallingIdentity();
5758
5759        synchronized (this) {
5760            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5761            if (r != null) {
5762                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5763            }
5764        }
5765
5766        trimApplications();
5767
5768        Binder.restoreCallingIdentity(origId);
5769    }
5770
5771    @Override
5772    public final void activityDestroyed(IBinder token) {
5773        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5774        synchronized (this) {
5775            ActivityStack stack = ActivityRecord.getStackLocked(token);
5776            if (stack != null) {
5777                stack.activityDestroyedLocked(token);
5778            }
5779        }
5780    }
5781
5782    @Override
5783    public final void mediaResourcesReleased(IBinder token) {
5784        final long origId = Binder.clearCallingIdentity();
5785        try {
5786            synchronized (this) {
5787                ActivityStack stack = ActivityRecord.getStackLocked(token);
5788                if (stack != null) {
5789                    stack.mediaResourcesReleased(token);
5790                }
5791            }
5792        } finally {
5793            Binder.restoreCallingIdentity(origId);
5794        }
5795    }
5796
5797    @Override
5798    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5799        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5800    }
5801
5802    @Override
5803    public final void notifyEnterAnimationComplete(IBinder token) {
5804        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5805    }
5806
5807    @Override
5808    public String getCallingPackage(IBinder token) {
5809        synchronized (this) {
5810            ActivityRecord r = getCallingRecordLocked(token);
5811            return r != null ? r.info.packageName : null;
5812        }
5813    }
5814
5815    @Override
5816    public ComponentName getCallingActivity(IBinder token) {
5817        synchronized (this) {
5818            ActivityRecord r = getCallingRecordLocked(token);
5819            return r != null ? r.intent.getComponent() : null;
5820        }
5821    }
5822
5823    private ActivityRecord getCallingRecordLocked(IBinder token) {
5824        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5825        if (r == null) {
5826            return null;
5827        }
5828        return r.resultTo;
5829    }
5830
5831    @Override
5832    public ComponentName getActivityClassForToken(IBinder token) {
5833        synchronized(this) {
5834            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5835            if (r == null) {
5836                return null;
5837            }
5838            return r.intent.getComponent();
5839        }
5840    }
5841
5842    @Override
5843    public String getPackageForToken(IBinder token) {
5844        synchronized(this) {
5845            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5846            if (r == null) {
5847                return null;
5848            }
5849            return r.packageName;
5850        }
5851    }
5852
5853    @Override
5854    public IIntentSender getIntentSender(int type,
5855            String packageName, IBinder token, String resultWho,
5856            int requestCode, Intent[] intents, String[] resolvedTypes,
5857            int flags, Bundle options, int userId) {
5858        enforceNotIsolatedCaller("getIntentSender");
5859        // Refuse possible leaked file descriptors
5860        if (intents != null) {
5861            if (intents.length < 1) {
5862                throw new IllegalArgumentException("Intents array length must be >= 1");
5863            }
5864            for (int i=0; i<intents.length; i++) {
5865                Intent intent = intents[i];
5866                if (intent != null) {
5867                    if (intent.hasFileDescriptors()) {
5868                        throw new IllegalArgumentException("File descriptors passed in Intent");
5869                    }
5870                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5871                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5872                        throw new IllegalArgumentException(
5873                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5874                    }
5875                    intents[i] = new Intent(intent);
5876                }
5877            }
5878            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5879                throw new IllegalArgumentException(
5880                        "Intent array length does not match resolvedTypes length");
5881            }
5882        }
5883        if (options != null) {
5884            if (options.hasFileDescriptors()) {
5885                throw new IllegalArgumentException("File descriptors passed in options");
5886            }
5887        }
5888
5889        synchronized(this) {
5890            int callingUid = Binder.getCallingUid();
5891            int origUserId = userId;
5892            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5893                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5894                    ALLOW_NON_FULL, "getIntentSender", null);
5895            if (origUserId == UserHandle.USER_CURRENT) {
5896                // We don't want to evaluate this until the pending intent is
5897                // actually executed.  However, we do want to always do the
5898                // security checking for it above.
5899                userId = UserHandle.USER_CURRENT;
5900            }
5901            try {
5902                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5903                    int uid = AppGlobals.getPackageManager()
5904                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5905                    if (!UserHandle.isSameApp(callingUid, uid)) {
5906                        String msg = "Permission Denial: getIntentSender() from pid="
5907                            + Binder.getCallingPid()
5908                            + ", uid=" + Binder.getCallingUid()
5909                            + ", (need uid=" + uid + ")"
5910                            + " is not allowed to send as package " + packageName;
5911                        Slog.w(TAG, msg);
5912                        throw new SecurityException(msg);
5913                    }
5914                }
5915
5916                return getIntentSenderLocked(type, packageName, callingUid, userId,
5917                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5918
5919            } catch (RemoteException e) {
5920                throw new SecurityException(e);
5921            }
5922        }
5923    }
5924
5925    IIntentSender getIntentSenderLocked(int type, String packageName,
5926            int callingUid, int userId, IBinder token, String resultWho,
5927            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5928            Bundle options) {
5929        if (DEBUG_MU)
5930            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5931        ActivityRecord activity = null;
5932        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5933            activity = ActivityRecord.isInStackLocked(token);
5934            if (activity == null) {
5935                return null;
5936            }
5937            if (activity.finishing) {
5938                return null;
5939            }
5940        }
5941
5942        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5943        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5944        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5945        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5946                |PendingIntent.FLAG_UPDATE_CURRENT);
5947
5948        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5949                type, packageName, activity, resultWho,
5950                requestCode, intents, resolvedTypes, flags, options, userId);
5951        WeakReference<PendingIntentRecord> ref;
5952        ref = mIntentSenderRecords.get(key);
5953        PendingIntentRecord rec = ref != null ? ref.get() : null;
5954        if (rec != null) {
5955            if (!cancelCurrent) {
5956                if (updateCurrent) {
5957                    if (rec.key.requestIntent != null) {
5958                        rec.key.requestIntent.replaceExtras(intents != null ?
5959                                intents[intents.length - 1] : null);
5960                    }
5961                    if (intents != null) {
5962                        intents[intents.length-1] = rec.key.requestIntent;
5963                        rec.key.allIntents = intents;
5964                        rec.key.allResolvedTypes = resolvedTypes;
5965                    } else {
5966                        rec.key.allIntents = null;
5967                        rec.key.allResolvedTypes = null;
5968                    }
5969                }
5970                return rec;
5971            }
5972            rec.canceled = true;
5973            mIntentSenderRecords.remove(key);
5974        }
5975        if (noCreate) {
5976            return rec;
5977        }
5978        rec = new PendingIntentRecord(this, key, callingUid);
5979        mIntentSenderRecords.put(key, rec.ref);
5980        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5981            if (activity.pendingResults == null) {
5982                activity.pendingResults
5983                        = new HashSet<WeakReference<PendingIntentRecord>>();
5984            }
5985            activity.pendingResults.add(rec.ref);
5986        }
5987        return rec;
5988    }
5989
5990    @Override
5991    public void cancelIntentSender(IIntentSender sender) {
5992        if (!(sender instanceof PendingIntentRecord)) {
5993            return;
5994        }
5995        synchronized(this) {
5996            PendingIntentRecord rec = (PendingIntentRecord)sender;
5997            try {
5998                int uid = AppGlobals.getPackageManager()
5999                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6000                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6001                    String msg = "Permission Denial: cancelIntentSender() from pid="
6002                        + Binder.getCallingPid()
6003                        + ", uid=" + Binder.getCallingUid()
6004                        + " is not allowed to cancel packges "
6005                        + rec.key.packageName;
6006                    Slog.w(TAG, msg);
6007                    throw new SecurityException(msg);
6008                }
6009            } catch (RemoteException e) {
6010                throw new SecurityException(e);
6011            }
6012            cancelIntentSenderLocked(rec, true);
6013        }
6014    }
6015
6016    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6017        rec.canceled = true;
6018        mIntentSenderRecords.remove(rec.key);
6019        if (cleanActivity && rec.key.activity != null) {
6020            rec.key.activity.pendingResults.remove(rec.ref);
6021        }
6022    }
6023
6024    @Override
6025    public String getPackageForIntentSender(IIntentSender pendingResult) {
6026        if (!(pendingResult instanceof PendingIntentRecord)) {
6027            return null;
6028        }
6029        try {
6030            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6031            return res.key.packageName;
6032        } catch (ClassCastException e) {
6033        }
6034        return null;
6035    }
6036
6037    @Override
6038    public int getUidForIntentSender(IIntentSender sender) {
6039        if (sender instanceof PendingIntentRecord) {
6040            try {
6041                PendingIntentRecord res = (PendingIntentRecord)sender;
6042                return res.uid;
6043            } catch (ClassCastException e) {
6044            }
6045        }
6046        return -1;
6047    }
6048
6049    @Override
6050    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6051        if (!(pendingResult instanceof PendingIntentRecord)) {
6052            return false;
6053        }
6054        try {
6055            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6056            if (res.key.allIntents == null) {
6057                return false;
6058            }
6059            for (int i=0; i<res.key.allIntents.length; i++) {
6060                Intent intent = res.key.allIntents[i];
6061                if (intent.getPackage() != null && intent.getComponent() != null) {
6062                    return false;
6063                }
6064            }
6065            return true;
6066        } catch (ClassCastException e) {
6067        }
6068        return false;
6069    }
6070
6071    @Override
6072    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6073        if (!(pendingResult instanceof PendingIntentRecord)) {
6074            return false;
6075        }
6076        try {
6077            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6078            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6079                return true;
6080            }
6081            return false;
6082        } catch (ClassCastException e) {
6083        }
6084        return false;
6085    }
6086
6087    @Override
6088    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6089        if (!(pendingResult instanceof PendingIntentRecord)) {
6090            return null;
6091        }
6092        try {
6093            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6094            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6095        } catch (ClassCastException e) {
6096        }
6097        return null;
6098    }
6099
6100    @Override
6101    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6102        if (!(pendingResult instanceof PendingIntentRecord)) {
6103            return null;
6104        }
6105        try {
6106            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6107            Intent intent = res.key.requestIntent;
6108            if (intent != null) {
6109                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6110                        || res.lastTagPrefix.equals(prefix))) {
6111                    return res.lastTag;
6112                }
6113                res.lastTagPrefix = prefix;
6114                StringBuilder sb = new StringBuilder(128);
6115                if (prefix != null) {
6116                    sb.append(prefix);
6117                }
6118                if (intent.getAction() != null) {
6119                    sb.append(intent.getAction());
6120                } else if (intent.getComponent() != null) {
6121                    intent.getComponent().appendShortString(sb);
6122                } else {
6123                    sb.append("?");
6124                }
6125                return res.lastTag = sb.toString();
6126            }
6127        } catch (ClassCastException e) {
6128        }
6129        return null;
6130    }
6131
6132    @Override
6133    public void setProcessLimit(int max) {
6134        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6135                "setProcessLimit()");
6136        synchronized (this) {
6137            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6138            mProcessLimitOverride = max;
6139        }
6140        trimApplications();
6141    }
6142
6143    @Override
6144    public int getProcessLimit() {
6145        synchronized (this) {
6146            return mProcessLimitOverride;
6147        }
6148    }
6149
6150    void foregroundTokenDied(ForegroundToken token) {
6151        synchronized (ActivityManagerService.this) {
6152            synchronized (mPidsSelfLocked) {
6153                ForegroundToken cur
6154                    = mForegroundProcesses.get(token.pid);
6155                if (cur != token) {
6156                    return;
6157                }
6158                mForegroundProcesses.remove(token.pid);
6159                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6160                if (pr == null) {
6161                    return;
6162                }
6163                pr.forcingToForeground = null;
6164                updateProcessForegroundLocked(pr, false, false);
6165            }
6166            updateOomAdjLocked();
6167        }
6168    }
6169
6170    @Override
6171    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6172        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6173                "setProcessForeground()");
6174        synchronized(this) {
6175            boolean changed = false;
6176
6177            synchronized (mPidsSelfLocked) {
6178                ProcessRecord pr = mPidsSelfLocked.get(pid);
6179                if (pr == null && isForeground) {
6180                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6181                    return;
6182                }
6183                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6184                if (oldToken != null) {
6185                    oldToken.token.unlinkToDeath(oldToken, 0);
6186                    mForegroundProcesses.remove(pid);
6187                    if (pr != null) {
6188                        pr.forcingToForeground = null;
6189                    }
6190                    changed = true;
6191                }
6192                if (isForeground && token != null) {
6193                    ForegroundToken newToken = new ForegroundToken() {
6194                        @Override
6195                        public void binderDied() {
6196                            foregroundTokenDied(this);
6197                        }
6198                    };
6199                    newToken.pid = pid;
6200                    newToken.token = token;
6201                    try {
6202                        token.linkToDeath(newToken, 0);
6203                        mForegroundProcesses.put(pid, newToken);
6204                        pr.forcingToForeground = token;
6205                        changed = true;
6206                    } catch (RemoteException e) {
6207                        // If the process died while doing this, we will later
6208                        // do the cleanup with the process death link.
6209                    }
6210                }
6211            }
6212
6213            if (changed) {
6214                updateOomAdjLocked();
6215            }
6216        }
6217    }
6218
6219    // =========================================================
6220    // PERMISSIONS
6221    // =========================================================
6222
6223    static class PermissionController extends IPermissionController.Stub {
6224        ActivityManagerService mActivityManagerService;
6225        PermissionController(ActivityManagerService activityManagerService) {
6226            mActivityManagerService = activityManagerService;
6227        }
6228
6229        @Override
6230        public boolean checkPermission(String permission, int pid, int uid) {
6231            return mActivityManagerService.checkPermission(permission, pid,
6232                    uid) == PackageManager.PERMISSION_GRANTED;
6233        }
6234    }
6235
6236    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6237        @Override
6238        public int checkComponentPermission(String permission, int pid, int uid,
6239                int owningUid, boolean exported) {
6240            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6241                    owningUid, exported);
6242        }
6243
6244        @Override
6245        public Object getAMSLock() {
6246            return ActivityManagerService.this;
6247        }
6248    }
6249
6250    /**
6251     * This can be called with or without the global lock held.
6252     */
6253    int checkComponentPermission(String permission, int pid, int uid,
6254            int owningUid, boolean exported) {
6255        // We might be performing an operation on behalf of an indirect binder
6256        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6257        // client identity accordingly before proceeding.
6258        Identity tlsIdentity = sCallerIdentity.get();
6259        if (tlsIdentity != null) {
6260            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6261                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6262            uid = tlsIdentity.uid;
6263            pid = tlsIdentity.pid;
6264        }
6265
6266        if (pid == MY_PID) {
6267            return PackageManager.PERMISSION_GRANTED;
6268        }
6269
6270        return ActivityManager.checkComponentPermission(permission, uid,
6271                owningUid, exported);
6272    }
6273
6274    /**
6275     * As the only public entry point for permissions checking, this method
6276     * can enforce the semantic that requesting a check on a null global
6277     * permission is automatically denied.  (Internally a null permission
6278     * string is used when calling {@link #checkComponentPermission} in cases
6279     * when only uid-based security is needed.)
6280     *
6281     * This can be called with or without the global lock held.
6282     */
6283    @Override
6284    public int checkPermission(String permission, int pid, int uid) {
6285        if (permission == null) {
6286            return PackageManager.PERMISSION_DENIED;
6287        }
6288        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6289    }
6290
6291    /**
6292     * Binder IPC calls go through the public entry point.
6293     * This can be called with or without the global lock held.
6294     */
6295    int checkCallingPermission(String permission) {
6296        return checkPermission(permission,
6297                Binder.getCallingPid(),
6298                UserHandle.getAppId(Binder.getCallingUid()));
6299    }
6300
6301    /**
6302     * This can be called with or without the global lock held.
6303     */
6304    void enforceCallingPermission(String permission, String func) {
6305        if (checkCallingPermission(permission)
6306                == PackageManager.PERMISSION_GRANTED) {
6307            return;
6308        }
6309
6310        String msg = "Permission Denial: " + func + " from pid="
6311                + Binder.getCallingPid()
6312                + ", uid=" + Binder.getCallingUid()
6313                + " requires " + permission;
6314        Slog.w(TAG, msg);
6315        throw new SecurityException(msg);
6316    }
6317
6318    /**
6319     * Determine if UID is holding permissions required to access {@link Uri} in
6320     * the given {@link ProviderInfo}. Final permission checking is always done
6321     * in {@link ContentProvider}.
6322     */
6323    private final boolean checkHoldingPermissionsLocked(
6324            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6325        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6326                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6327        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6328            return false;
6329        }
6330        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6331    }
6332
6333    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6334            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6335        if (pi.applicationInfo.uid == uid) {
6336            return true;
6337        } else if (!pi.exported) {
6338            return false;
6339        }
6340
6341        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6342        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6343        try {
6344            // check if target holds top-level <provider> permissions
6345            if (!readMet && pi.readPermission != null && considerUidPermissions
6346                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6347                readMet = true;
6348            }
6349            if (!writeMet && pi.writePermission != null && considerUidPermissions
6350                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6351                writeMet = true;
6352            }
6353
6354            // track if unprotected read/write is allowed; any denied
6355            // <path-permission> below removes this ability
6356            boolean allowDefaultRead = pi.readPermission == null;
6357            boolean allowDefaultWrite = pi.writePermission == null;
6358
6359            // check if target holds any <path-permission> that match uri
6360            final PathPermission[] pps = pi.pathPermissions;
6361            if (pps != null) {
6362                final String path = grantUri.uri.getPath();
6363                int i = pps.length;
6364                while (i > 0 && (!readMet || !writeMet)) {
6365                    i--;
6366                    PathPermission pp = pps[i];
6367                    if (pp.match(path)) {
6368                        if (!readMet) {
6369                            final String pprperm = pp.getReadPermission();
6370                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6371                                    + pprperm + " for " + pp.getPath()
6372                                    + ": match=" + pp.match(path)
6373                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6374                            if (pprperm != null) {
6375                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6376                                        == PERMISSION_GRANTED) {
6377                                    readMet = true;
6378                                } else {
6379                                    allowDefaultRead = false;
6380                                }
6381                            }
6382                        }
6383                        if (!writeMet) {
6384                            final String ppwperm = pp.getWritePermission();
6385                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6386                                    + ppwperm + " for " + pp.getPath()
6387                                    + ": match=" + pp.match(path)
6388                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6389                            if (ppwperm != null) {
6390                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6391                                        == PERMISSION_GRANTED) {
6392                                    writeMet = true;
6393                                } else {
6394                                    allowDefaultWrite = false;
6395                                }
6396                            }
6397                        }
6398                    }
6399                }
6400            }
6401
6402            // grant unprotected <provider> read/write, if not blocked by
6403            // <path-permission> above
6404            if (allowDefaultRead) readMet = true;
6405            if (allowDefaultWrite) writeMet = true;
6406
6407        } catch (RemoteException e) {
6408            return false;
6409        }
6410
6411        return readMet && writeMet;
6412    }
6413
6414    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6415        ProviderInfo pi = null;
6416        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6417        if (cpr != null) {
6418            pi = cpr.info;
6419        } else {
6420            try {
6421                pi = AppGlobals.getPackageManager().resolveContentProvider(
6422                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6423            } catch (RemoteException ex) {
6424            }
6425        }
6426        return pi;
6427    }
6428
6429    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6430        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6431        if (targetUris != null) {
6432            return targetUris.get(grantUri);
6433        }
6434        return null;
6435    }
6436
6437    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6438            String targetPkg, int targetUid, GrantUri grantUri) {
6439        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6440        if (targetUris == null) {
6441            targetUris = Maps.newArrayMap();
6442            mGrantedUriPermissions.put(targetUid, targetUris);
6443        }
6444
6445        UriPermission perm = targetUris.get(grantUri);
6446        if (perm == null) {
6447            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6448            targetUris.put(grantUri, perm);
6449        }
6450
6451        return perm;
6452    }
6453
6454    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6455            final int modeFlags) {
6456        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6457        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6458                : UriPermission.STRENGTH_OWNED;
6459
6460        // Root gets to do everything.
6461        if (uid == 0) {
6462            return true;
6463        }
6464
6465        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6466        if (perms == null) return false;
6467
6468        // First look for exact match
6469        final UriPermission exactPerm = perms.get(grantUri);
6470        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6471            return true;
6472        }
6473
6474        // No exact match, look for prefixes
6475        final int N = perms.size();
6476        for (int i = 0; i < N; i++) {
6477            final UriPermission perm = perms.valueAt(i);
6478            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6479                    && perm.getStrength(modeFlags) >= minStrength) {
6480                return true;
6481            }
6482        }
6483
6484        return false;
6485    }
6486
6487    @Override
6488    public int checkUriPermission(Uri uri, int pid, int uid,
6489            final int modeFlags, int userId) {
6490        enforceNotIsolatedCaller("checkUriPermission");
6491
6492        // Another redirected-binder-call permissions check as in
6493        // {@link checkComponentPermission}.
6494        Identity tlsIdentity = sCallerIdentity.get();
6495        if (tlsIdentity != null) {
6496            uid = tlsIdentity.uid;
6497            pid = tlsIdentity.pid;
6498        }
6499
6500        // Our own process gets to do everything.
6501        if (pid == MY_PID) {
6502            return PackageManager.PERMISSION_GRANTED;
6503        }
6504        synchronized (this) {
6505            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6506                    ? PackageManager.PERMISSION_GRANTED
6507                    : PackageManager.PERMISSION_DENIED;
6508        }
6509    }
6510
6511    /**
6512     * Check if the targetPkg can be granted permission to access uri by
6513     * the callingUid using the given modeFlags.  Throws a security exception
6514     * if callingUid is not allowed to do this.  Returns the uid of the target
6515     * if the URI permission grant should be performed; returns -1 if it is not
6516     * needed (for example targetPkg already has permission to access the URI).
6517     * If you already know the uid of the target, you can supply it in
6518     * lastTargetUid else set that to -1.
6519     */
6520    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6521            final int modeFlags, int lastTargetUid) {
6522        if (!Intent.isAccessUriMode(modeFlags)) {
6523            return -1;
6524        }
6525
6526        if (targetPkg != null) {
6527            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6528                    "Checking grant " + targetPkg + " permission to " + grantUri);
6529        }
6530
6531        final IPackageManager pm = AppGlobals.getPackageManager();
6532
6533        // If this is not a content: uri, we can't do anything with it.
6534        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6535            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6536                    "Can't grant URI permission for non-content URI: " + grantUri);
6537            return -1;
6538        }
6539
6540        final String authority = grantUri.uri.getAuthority();
6541        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6542        if (pi == null) {
6543            Slog.w(TAG, "No content provider found for permission check: " +
6544                    grantUri.uri.toSafeString());
6545            return -1;
6546        }
6547
6548        int targetUid = lastTargetUid;
6549        if (targetUid < 0 && targetPkg != null) {
6550            try {
6551                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6552                if (targetUid < 0) {
6553                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6554                            "Can't grant URI permission no uid for: " + targetPkg);
6555                    return -1;
6556                }
6557            } catch (RemoteException ex) {
6558                return -1;
6559            }
6560        }
6561
6562        if (targetUid >= 0) {
6563            // First...  does the target actually need this permission?
6564            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6565                // No need to grant the target this permission.
6566                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6567                        "Target " + targetPkg + " already has full permission to " + grantUri);
6568                return -1;
6569            }
6570        } else {
6571            // First...  there is no target package, so can anyone access it?
6572            boolean allowed = pi.exported;
6573            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6574                if (pi.readPermission != null) {
6575                    allowed = false;
6576                }
6577            }
6578            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6579                if (pi.writePermission != null) {
6580                    allowed = false;
6581                }
6582            }
6583            if (allowed) {
6584                return -1;
6585            }
6586        }
6587
6588        /* There is a special cross user grant if:
6589         * - The target is on another user.
6590         * - Apps on the current user can access the uri without any uid permissions.
6591         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6592         * grant uri permissions.
6593         */
6594        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6595                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6596                modeFlags, false /*without considering the uid permissions*/);
6597
6598        // Second...  is the provider allowing granting of URI permissions?
6599        if (!specialCrossUserGrant) {
6600            if (!pi.grantUriPermissions) {
6601                throw new SecurityException("Provider " + pi.packageName
6602                        + "/" + pi.name
6603                        + " does not allow granting of Uri permissions (uri "
6604                        + grantUri + ")");
6605            }
6606            if (pi.uriPermissionPatterns != null) {
6607                final int N = pi.uriPermissionPatterns.length;
6608                boolean allowed = false;
6609                for (int i=0; i<N; i++) {
6610                    if (pi.uriPermissionPatterns[i] != null
6611                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6612                        allowed = true;
6613                        break;
6614                    }
6615                }
6616                if (!allowed) {
6617                    throw new SecurityException("Provider " + pi.packageName
6618                            + "/" + pi.name
6619                            + " does not allow granting of permission to path of Uri "
6620                            + grantUri);
6621                }
6622            }
6623        }
6624
6625        // Third...  does the caller itself have permission to access
6626        // this uri?
6627        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6628            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6629                // Require they hold a strong enough Uri permission
6630                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6631                    throw new SecurityException("Uid " + callingUid
6632                            + " does not have permission to uri " + grantUri);
6633                }
6634            }
6635        }
6636        return targetUid;
6637    }
6638
6639    @Override
6640    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6641            final int modeFlags, int userId) {
6642        enforceNotIsolatedCaller("checkGrantUriPermission");
6643        synchronized(this) {
6644            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6645                    new GrantUri(userId, uri, false), modeFlags, -1);
6646        }
6647    }
6648
6649    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6650            final int modeFlags, UriPermissionOwner owner) {
6651        if (!Intent.isAccessUriMode(modeFlags)) {
6652            return;
6653        }
6654
6655        // So here we are: the caller has the assumed permission
6656        // to the uri, and the target doesn't.  Let's now give this to
6657        // the target.
6658
6659        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6660                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6661
6662        final String authority = grantUri.uri.getAuthority();
6663        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6664        if (pi == null) {
6665            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6666            return;
6667        }
6668
6669        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6670            grantUri.prefix = true;
6671        }
6672        final UriPermission perm = findOrCreateUriPermissionLocked(
6673                pi.packageName, targetPkg, targetUid, grantUri);
6674        perm.grantModes(modeFlags, owner);
6675    }
6676
6677    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6678            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6679        if (targetPkg == null) {
6680            throw new NullPointerException("targetPkg");
6681        }
6682        int targetUid;
6683        final IPackageManager pm = AppGlobals.getPackageManager();
6684        try {
6685            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6686        } catch (RemoteException ex) {
6687            return;
6688        }
6689
6690        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6691                targetUid);
6692        if (targetUid < 0) {
6693            return;
6694        }
6695
6696        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6697                owner);
6698    }
6699
6700    static class NeededUriGrants extends ArrayList<GrantUri> {
6701        final String targetPkg;
6702        final int targetUid;
6703        final int flags;
6704
6705        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6706            this.targetPkg = targetPkg;
6707            this.targetUid = targetUid;
6708            this.flags = flags;
6709        }
6710    }
6711
6712    /**
6713     * Like checkGrantUriPermissionLocked, but takes an Intent.
6714     */
6715    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6716            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6717        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6718                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6719                + " clip=" + (intent != null ? intent.getClipData() : null)
6720                + " from " + intent + "; flags=0x"
6721                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6722
6723        if (targetPkg == null) {
6724            throw new NullPointerException("targetPkg");
6725        }
6726
6727        if (intent == null) {
6728            return null;
6729        }
6730        Uri data = intent.getData();
6731        ClipData clip = intent.getClipData();
6732        if (data == null && clip == null) {
6733            return null;
6734        }
6735        // Default userId for uris in the intent (if they don't specify it themselves)
6736        int contentUserHint = intent.getContentUserHint();
6737        if (contentUserHint == UserHandle.USER_CURRENT) {
6738            contentUserHint = UserHandle.getUserId(callingUid);
6739        }
6740        final IPackageManager pm = AppGlobals.getPackageManager();
6741        int targetUid;
6742        if (needed != null) {
6743            targetUid = needed.targetUid;
6744        } else {
6745            try {
6746                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6747            } catch (RemoteException ex) {
6748                return null;
6749            }
6750            if (targetUid < 0) {
6751                if (DEBUG_URI_PERMISSION) {
6752                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6753                            + " on user " + targetUserId);
6754                }
6755                return null;
6756            }
6757        }
6758        if (data != null) {
6759            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6760            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6761                    targetUid);
6762            if (targetUid > 0) {
6763                if (needed == null) {
6764                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6765                }
6766                needed.add(grantUri);
6767            }
6768        }
6769        if (clip != null) {
6770            for (int i=0; i<clip.getItemCount(); i++) {
6771                Uri uri = clip.getItemAt(i).getUri();
6772                if (uri != null) {
6773                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6774                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6775                            targetUid);
6776                    if (targetUid > 0) {
6777                        if (needed == null) {
6778                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6779                        }
6780                        needed.add(grantUri);
6781                    }
6782                } else {
6783                    Intent clipIntent = clip.getItemAt(i).getIntent();
6784                    if (clipIntent != null) {
6785                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6786                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6787                        if (newNeeded != null) {
6788                            needed = newNeeded;
6789                        }
6790                    }
6791                }
6792            }
6793        }
6794
6795        return needed;
6796    }
6797
6798    /**
6799     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6800     */
6801    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6802            UriPermissionOwner owner) {
6803        if (needed != null) {
6804            for (int i=0; i<needed.size(); i++) {
6805                GrantUri grantUri = needed.get(i);
6806                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6807                        grantUri, needed.flags, owner);
6808            }
6809        }
6810    }
6811
6812    void grantUriPermissionFromIntentLocked(int callingUid,
6813            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6814        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6815                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6816        if (needed == null) {
6817            return;
6818        }
6819
6820        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6821    }
6822
6823    @Override
6824    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6825            final int modeFlags, int userId) {
6826        enforceNotIsolatedCaller("grantUriPermission");
6827        GrantUri grantUri = new GrantUri(userId, uri, false);
6828        synchronized(this) {
6829            final ProcessRecord r = getRecordForAppLocked(caller);
6830            if (r == null) {
6831                throw new SecurityException("Unable to find app for caller "
6832                        + caller
6833                        + " when granting permission to uri " + grantUri);
6834            }
6835            if (targetPkg == null) {
6836                throw new IllegalArgumentException("null target");
6837            }
6838            if (grantUri == null) {
6839                throw new IllegalArgumentException("null uri");
6840            }
6841
6842            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6843                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6844                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6845                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6846
6847            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6848                    UserHandle.getUserId(r.uid));
6849        }
6850    }
6851
6852    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6853        if (perm.modeFlags == 0) {
6854            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6855                    perm.targetUid);
6856            if (perms != null) {
6857                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6858                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6859
6860                perms.remove(perm.uri);
6861                if (perms.isEmpty()) {
6862                    mGrantedUriPermissions.remove(perm.targetUid);
6863                }
6864            }
6865        }
6866    }
6867
6868    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6869        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6870
6871        final IPackageManager pm = AppGlobals.getPackageManager();
6872        final String authority = grantUri.uri.getAuthority();
6873        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6874        if (pi == null) {
6875            Slog.w(TAG, "No content provider found for permission revoke: "
6876                    + grantUri.toSafeString());
6877            return;
6878        }
6879
6880        // Does the caller have this permission on the URI?
6881        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6882            // Right now, if you are not the original owner of the permission,
6883            // you are not allowed to revoke it.
6884            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6885                throw new SecurityException("Uid " + callingUid
6886                        + " does not have permission to uri " + grantUri);
6887            //}
6888        }
6889
6890        boolean persistChanged = false;
6891
6892        // Go through all of the permissions and remove any that match.
6893        int N = mGrantedUriPermissions.size();
6894        for (int i = 0; i < N; i++) {
6895            final int targetUid = mGrantedUriPermissions.keyAt(i);
6896            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6897
6898            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6899                final UriPermission perm = it.next();
6900                if (perm.uri.sourceUserId == grantUri.sourceUserId
6901                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6902                    if (DEBUG_URI_PERMISSION)
6903                        Slog.v(TAG,
6904                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6905                    persistChanged |= perm.revokeModes(
6906                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6907                    if (perm.modeFlags == 0) {
6908                        it.remove();
6909                    }
6910                }
6911            }
6912
6913            if (perms.isEmpty()) {
6914                mGrantedUriPermissions.remove(targetUid);
6915                N--;
6916                i--;
6917            }
6918        }
6919
6920        if (persistChanged) {
6921            schedulePersistUriGrants();
6922        }
6923    }
6924
6925    @Override
6926    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6927            int userId) {
6928        enforceNotIsolatedCaller("revokeUriPermission");
6929        synchronized(this) {
6930            final ProcessRecord r = getRecordForAppLocked(caller);
6931            if (r == null) {
6932                throw new SecurityException("Unable to find app for caller "
6933                        + caller
6934                        + " when revoking permission to uri " + uri);
6935            }
6936            if (uri == null) {
6937                Slog.w(TAG, "revokeUriPermission: null uri");
6938                return;
6939            }
6940
6941            if (!Intent.isAccessUriMode(modeFlags)) {
6942                return;
6943            }
6944
6945            final IPackageManager pm = AppGlobals.getPackageManager();
6946            final String authority = uri.getAuthority();
6947            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6948            if (pi == null) {
6949                Slog.w(TAG, "No content provider found for permission revoke: "
6950                        + uri.toSafeString());
6951                return;
6952            }
6953
6954            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6955        }
6956    }
6957
6958    /**
6959     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6960     * given package.
6961     *
6962     * @param packageName Package name to match, or {@code null} to apply to all
6963     *            packages.
6964     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6965     *            to all users.
6966     * @param persistable If persistable grants should be removed.
6967     */
6968    private void removeUriPermissionsForPackageLocked(
6969            String packageName, int userHandle, boolean persistable) {
6970        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6971            throw new IllegalArgumentException("Must narrow by either package or user");
6972        }
6973
6974        boolean persistChanged = false;
6975
6976        int N = mGrantedUriPermissions.size();
6977        for (int i = 0; i < N; i++) {
6978            final int targetUid = mGrantedUriPermissions.keyAt(i);
6979            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6980
6981            // Only inspect grants matching user
6982            if (userHandle == UserHandle.USER_ALL
6983                    || userHandle == UserHandle.getUserId(targetUid)) {
6984                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6985                    final UriPermission perm = it.next();
6986
6987                    // Only inspect grants matching package
6988                    if (packageName == null || perm.sourcePkg.equals(packageName)
6989                            || perm.targetPkg.equals(packageName)) {
6990                        persistChanged |= perm.revokeModes(
6991                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6992
6993                        // Only remove when no modes remain; any persisted grants
6994                        // will keep this alive.
6995                        if (perm.modeFlags == 0) {
6996                            it.remove();
6997                        }
6998                    }
6999                }
7000
7001                if (perms.isEmpty()) {
7002                    mGrantedUriPermissions.remove(targetUid);
7003                    N--;
7004                    i--;
7005                }
7006            }
7007        }
7008
7009        if (persistChanged) {
7010            schedulePersistUriGrants();
7011        }
7012    }
7013
7014    @Override
7015    public IBinder newUriPermissionOwner(String name) {
7016        enforceNotIsolatedCaller("newUriPermissionOwner");
7017        synchronized(this) {
7018            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7019            return owner.getExternalTokenLocked();
7020        }
7021    }
7022
7023    @Override
7024    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7025            final int modeFlags, int sourceUserId, int targetUserId) {
7026        synchronized(this) {
7027            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7028            if (owner == null) {
7029                throw new IllegalArgumentException("Unknown owner: " + token);
7030            }
7031            if (fromUid != Binder.getCallingUid()) {
7032                if (Binder.getCallingUid() != Process.myUid()) {
7033                    // Only system code can grant URI permissions on behalf
7034                    // of other users.
7035                    throw new SecurityException("nice try");
7036                }
7037            }
7038            if (targetPkg == null) {
7039                throw new IllegalArgumentException("null target");
7040            }
7041            if (uri == null) {
7042                throw new IllegalArgumentException("null uri");
7043            }
7044
7045            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7046                    modeFlags, owner, targetUserId);
7047        }
7048    }
7049
7050    @Override
7051    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7052        synchronized(this) {
7053            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7054            if (owner == null) {
7055                throw new IllegalArgumentException("Unknown owner: " + token);
7056            }
7057
7058            if (uri == null) {
7059                owner.removeUriPermissionsLocked(mode);
7060            } else {
7061                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7062            }
7063        }
7064    }
7065
7066    private void schedulePersistUriGrants() {
7067        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7068            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7069                    10 * DateUtils.SECOND_IN_MILLIS);
7070        }
7071    }
7072
7073    private void writeGrantedUriPermissions() {
7074        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7075
7076        // Snapshot permissions so we can persist without lock
7077        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7078        synchronized (this) {
7079            final int size = mGrantedUriPermissions.size();
7080            for (int i = 0; i < size; i++) {
7081                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7082                for (UriPermission perm : perms.values()) {
7083                    if (perm.persistedModeFlags != 0) {
7084                        persist.add(perm.snapshot());
7085                    }
7086                }
7087            }
7088        }
7089
7090        FileOutputStream fos = null;
7091        try {
7092            fos = mGrantFile.startWrite();
7093
7094            XmlSerializer out = new FastXmlSerializer();
7095            out.setOutput(fos, "utf-8");
7096            out.startDocument(null, true);
7097            out.startTag(null, TAG_URI_GRANTS);
7098            for (UriPermission.Snapshot perm : persist) {
7099                out.startTag(null, TAG_URI_GRANT);
7100                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7101                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7102                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7103                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7104                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7105                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7106                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7107                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7108                out.endTag(null, TAG_URI_GRANT);
7109            }
7110            out.endTag(null, TAG_URI_GRANTS);
7111            out.endDocument();
7112
7113            mGrantFile.finishWrite(fos);
7114        } catch (IOException e) {
7115            if (fos != null) {
7116                mGrantFile.failWrite(fos);
7117            }
7118        }
7119    }
7120
7121    private void readGrantedUriPermissionsLocked() {
7122        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7123
7124        final long now = System.currentTimeMillis();
7125
7126        FileInputStream fis = null;
7127        try {
7128            fis = mGrantFile.openRead();
7129            final XmlPullParser in = Xml.newPullParser();
7130            in.setInput(fis, null);
7131
7132            int type;
7133            while ((type = in.next()) != END_DOCUMENT) {
7134                final String tag = in.getName();
7135                if (type == START_TAG) {
7136                    if (TAG_URI_GRANT.equals(tag)) {
7137                        final int sourceUserId;
7138                        final int targetUserId;
7139                        final int userHandle = readIntAttribute(in,
7140                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7141                        if (userHandle != UserHandle.USER_NULL) {
7142                            // For backwards compatibility.
7143                            sourceUserId = userHandle;
7144                            targetUserId = userHandle;
7145                        } else {
7146                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7147                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7148                        }
7149                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7150                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7151                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7152                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7153                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7154                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7155
7156                        // Sanity check that provider still belongs to source package
7157                        final ProviderInfo pi = getProviderInfoLocked(
7158                                uri.getAuthority(), sourceUserId);
7159                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7160                            int targetUid = -1;
7161                            try {
7162                                targetUid = AppGlobals.getPackageManager()
7163                                        .getPackageUid(targetPkg, targetUserId);
7164                            } catch (RemoteException e) {
7165                            }
7166                            if (targetUid != -1) {
7167                                final UriPermission perm = findOrCreateUriPermissionLocked(
7168                                        sourcePkg, targetPkg, targetUid,
7169                                        new GrantUri(sourceUserId, uri, prefix));
7170                                perm.initPersistedModes(modeFlags, createdTime);
7171                            }
7172                        } else {
7173                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7174                                    + " but instead found " + pi);
7175                        }
7176                    }
7177                }
7178            }
7179        } catch (FileNotFoundException e) {
7180            // Missing grants is okay
7181        } catch (IOException e) {
7182            Log.wtf(TAG, "Failed reading Uri grants", e);
7183        } catch (XmlPullParserException e) {
7184            Log.wtf(TAG, "Failed reading Uri grants", e);
7185        } finally {
7186            IoUtils.closeQuietly(fis);
7187        }
7188    }
7189
7190    @Override
7191    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7192        enforceNotIsolatedCaller("takePersistableUriPermission");
7193
7194        Preconditions.checkFlagsArgument(modeFlags,
7195                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7196
7197        synchronized (this) {
7198            final int callingUid = Binder.getCallingUid();
7199            boolean persistChanged = false;
7200            GrantUri grantUri = new GrantUri(userId, uri, false);
7201
7202            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7203                    new GrantUri(userId, uri, false));
7204            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7205                    new GrantUri(userId, uri, true));
7206
7207            final boolean exactValid = (exactPerm != null)
7208                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7209            final boolean prefixValid = (prefixPerm != null)
7210                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7211
7212            if (!(exactValid || prefixValid)) {
7213                throw new SecurityException("No persistable permission grants found for UID "
7214                        + callingUid + " and Uri " + grantUri.toSafeString());
7215            }
7216
7217            if (exactValid) {
7218                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7219            }
7220            if (prefixValid) {
7221                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7222            }
7223
7224            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7225
7226            if (persistChanged) {
7227                schedulePersistUriGrants();
7228            }
7229        }
7230    }
7231
7232    @Override
7233    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7234        enforceNotIsolatedCaller("releasePersistableUriPermission");
7235
7236        Preconditions.checkFlagsArgument(modeFlags,
7237                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7238
7239        synchronized (this) {
7240            final int callingUid = Binder.getCallingUid();
7241            boolean persistChanged = false;
7242
7243            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7244                    new GrantUri(userId, uri, false));
7245            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7246                    new GrantUri(userId, uri, true));
7247            if (exactPerm == null && prefixPerm == null) {
7248                throw new SecurityException("No permission grants found for UID " + callingUid
7249                        + " and Uri " + uri.toSafeString());
7250            }
7251
7252            if (exactPerm != null) {
7253                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7254                removeUriPermissionIfNeededLocked(exactPerm);
7255            }
7256            if (prefixPerm != null) {
7257                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7258                removeUriPermissionIfNeededLocked(prefixPerm);
7259            }
7260
7261            if (persistChanged) {
7262                schedulePersistUriGrants();
7263            }
7264        }
7265    }
7266
7267    /**
7268     * Prune any older {@link UriPermission} for the given UID until outstanding
7269     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7270     *
7271     * @return if any mutations occured that require persisting.
7272     */
7273    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7274        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7275        if (perms == null) return false;
7276        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7277
7278        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7279        for (UriPermission perm : perms.values()) {
7280            if (perm.persistedModeFlags != 0) {
7281                persisted.add(perm);
7282            }
7283        }
7284
7285        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7286        if (trimCount <= 0) return false;
7287
7288        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7289        for (int i = 0; i < trimCount; i++) {
7290            final UriPermission perm = persisted.get(i);
7291
7292            if (DEBUG_URI_PERMISSION) {
7293                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7294            }
7295
7296            perm.releasePersistableModes(~0);
7297            removeUriPermissionIfNeededLocked(perm);
7298        }
7299
7300        return true;
7301    }
7302
7303    @Override
7304    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7305            String packageName, boolean incoming) {
7306        enforceNotIsolatedCaller("getPersistedUriPermissions");
7307        Preconditions.checkNotNull(packageName, "packageName");
7308
7309        final int callingUid = Binder.getCallingUid();
7310        final IPackageManager pm = AppGlobals.getPackageManager();
7311        try {
7312            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7313            if (packageUid != callingUid) {
7314                throw new SecurityException(
7315                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7316            }
7317        } catch (RemoteException e) {
7318            throw new SecurityException("Failed to verify package name ownership");
7319        }
7320
7321        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7322        synchronized (this) {
7323            if (incoming) {
7324                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7325                        callingUid);
7326                if (perms == null) {
7327                    Slog.w(TAG, "No permission grants found for " + packageName);
7328                } else {
7329                    for (UriPermission perm : perms.values()) {
7330                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7331                            result.add(perm.buildPersistedPublicApiObject());
7332                        }
7333                    }
7334                }
7335            } else {
7336                final int size = mGrantedUriPermissions.size();
7337                for (int i = 0; i < size; i++) {
7338                    final ArrayMap<GrantUri, UriPermission> perms =
7339                            mGrantedUriPermissions.valueAt(i);
7340                    for (UriPermission perm : perms.values()) {
7341                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7342                            result.add(perm.buildPersistedPublicApiObject());
7343                        }
7344                    }
7345                }
7346            }
7347        }
7348        return new ParceledListSlice<android.content.UriPermission>(result);
7349    }
7350
7351    @Override
7352    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7353        synchronized (this) {
7354            ProcessRecord app =
7355                who != null ? getRecordForAppLocked(who) : null;
7356            if (app == null) return;
7357
7358            Message msg = Message.obtain();
7359            msg.what = WAIT_FOR_DEBUGGER_MSG;
7360            msg.obj = app;
7361            msg.arg1 = waiting ? 1 : 0;
7362            mHandler.sendMessage(msg);
7363        }
7364    }
7365
7366    @Override
7367    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7368        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7369        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7370        outInfo.availMem = Process.getFreeMemory();
7371        outInfo.totalMem = Process.getTotalMemory();
7372        outInfo.threshold = homeAppMem;
7373        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7374        outInfo.hiddenAppThreshold = cachedAppMem;
7375        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7376                ProcessList.SERVICE_ADJ);
7377        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7378                ProcessList.VISIBLE_APP_ADJ);
7379        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7380                ProcessList.FOREGROUND_APP_ADJ);
7381    }
7382
7383    // =========================================================
7384    // TASK MANAGEMENT
7385    // =========================================================
7386
7387    @Override
7388    public List<IAppTask> getAppTasks() {
7389        final PackageManager pm = mContext.getPackageManager();
7390        int callingUid = Binder.getCallingUid();
7391        long ident = Binder.clearCallingIdentity();
7392
7393        // Compose the list of packages for this id to test against
7394        HashSet<String> packages = new HashSet<String>();
7395        String[] uidPackages = pm.getPackagesForUid(callingUid);
7396        for (int i = 0; i < uidPackages.length; i++) {
7397            packages.add(uidPackages[i]);
7398        }
7399
7400        synchronized(this) {
7401            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7402            try {
7403                if (localLOGV) Slog.v(TAG, "getAppTasks");
7404
7405                final int N = mRecentTasks.size();
7406                for (int i = 0; i < N; i++) {
7407                    TaskRecord tr = mRecentTasks.get(i);
7408                    // Skip tasks that are not created by the caller
7409                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7410                        ActivityManager.RecentTaskInfo taskInfo =
7411                                createRecentTaskInfoFromTaskRecord(tr);
7412                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7413                        list.add(taskImpl);
7414                    }
7415                }
7416            } finally {
7417                Binder.restoreCallingIdentity(ident);
7418            }
7419            return list;
7420        }
7421    }
7422
7423    @Override
7424    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7425        final int callingUid = Binder.getCallingUid();
7426        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7427
7428        synchronized(this) {
7429            if (localLOGV) Slog.v(
7430                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7431
7432            final boolean allowed = checkCallingPermission(
7433                    android.Manifest.permission.GET_TASKS)
7434                    == PackageManager.PERMISSION_GRANTED;
7435            if (!allowed) {
7436                Slog.w(TAG, "getTasks: caller " + callingUid
7437                        + " does not hold GET_TASKS; limiting output");
7438            }
7439
7440            // TODO: Improve with MRU list from all ActivityStacks.
7441            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7442        }
7443
7444        return list;
7445    }
7446
7447    TaskRecord getMostRecentTask() {
7448        return mRecentTasks.get(0);
7449    }
7450
7451    /**
7452     * Creates a new RecentTaskInfo from a TaskRecord.
7453     */
7454    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7455        // Update the task description to reflect any changes in the task stack
7456        tr.updateTaskDescription();
7457
7458        // Compose the recent task info
7459        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7460        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7461        rti.persistentId = tr.taskId;
7462        rti.baseIntent = new Intent(tr.getBaseIntent());
7463        rti.origActivity = tr.origActivity;
7464        rti.description = tr.lastDescription;
7465        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7466        rti.userId = tr.userId;
7467        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7468        rti.firstActiveTime = tr.firstActiveTime;
7469        rti.lastActiveTime = tr.lastActiveTime;
7470        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7471        return rti;
7472    }
7473
7474    @Override
7475    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7476        final int callingUid = Binder.getCallingUid();
7477        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7478                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7479
7480        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7481        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7482        synchronized (this) {
7483            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7484                    == PackageManager.PERMISSION_GRANTED;
7485            if (!allowed) {
7486                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7487                        + " does not hold GET_TASKS; limiting output");
7488            }
7489            final boolean detailed = checkCallingPermission(
7490                    android.Manifest.permission.GET_DETAILED_TASKS)
7491                    == PackageManager.PERMISSION_GRANTED;
7492
7493            IPackageManager pm = AppGlobals.getPackageManager();
7494
7495            final int N = mRecentTasks.size();
7496            ArrayList<ActivityManager.RecentTaskInfo> res
7497                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7498                            maxNum < N ? maxNum : N);
7499
7500            final Set<Integer> includedUsers;
7501            if (includeProfiles) {
7502                includedUsers = getProfileIdsLocked(userId);
7503            } else {
7504                includedUsers = new HashSet<Integer>();
7505            }
7506            includedUsers.add(Integer.valueOf(userId));
7507
7508            // Regroup affiliated tasks together.
7509            for (int i = 0; i < N; ) {
7510                TaskRecord task = mRecentTasks.remove(i);
7511                if (mTmpRecents.contains(task)) {
7512                    continue;
7513                }
7514                int affiliatedTaskId = task.mAffiliatedTaskId;
7515                while (true) {
7516                    TaskRecord next = task.mNextAffiliate;
7517                    if (next == null) {
7518                        break;
7519                    }
7520                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7521                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7522                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7523                        task.setNextAffiliate(null);
7524                        if (next.mPrevAffiliate == task) {
7525                            next.setPrevAffiliate(null);
7526                        }
7527                        break;
7528                    }
7529                    if (next.mPrevAffiliate != task) {
7530                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7531                                next.mPrevAffiliate + " task=" + task);
7532                        next.setPrevAffiliate(null);
7533                        break;
7534                    }
7535                    if (!mRecentTasks.contains(next)) {
7536                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7537                        task.setNextAffiliate(null);
7538                        if (next.mPrevAffiliate == task) {
7539                            next.setPrevAffiliate(null);
7540                        }
7541                        break;
7542                    }
7543                    task = next;
7544                }
7545                // task is now the end of the list
7546                do {
7547                    mRecentTasks.remove(task);
7548                    mRecentTasks.add(i++, task);
7549                    mTmpRecents.add(task);
7550                } while ((task = task.mPrevAffiliate) != null);
7551            }
7552            mTmpRecents.clear();
7553            // mRecentTasks is now in sorted, affiliated order.
7554
7555            for (int i=0; i<N && maxNum > 0; i++) {
7556                TaskRecord tr = mRecentTasks.get(i);
7557                // Only add calling user or related users recent tasks
7558                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7559
7560                // Return the entry if desired by the caller.  We always return
7561                // the first entry, because callers always expect this to be the
7562                // foreground app.  We may filter others if the caller has
7563                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7564                // we should exclude the entry.
7565
7566                if (i == 0
7567                        || withExcluded
7568                        || (tr.intent == null)
7569                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7570                                == 0)) {
7571                    if (!allowed) {
7572                        // If the caller doesn't have the GET_TASKS permission, then only
7573                        // allow them to see a small subset of tasks -- their own and home.
7574                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7575                            continue;
7576                        }
7577                    }
7578                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7579                        // Don't include auto remove tasks that are finished or finishing.
7580                        continue;
7581                    }
7582
7583                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7584                    if (!detailed) {
7585                        rti.baseIntent.replaceExtras((Bundle)null);
7586                    }
7587
7588                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7589                        // Check whether this activity is currently available.
7590                        try {
7591                            if (rti.origActivity != null) {
7592                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7593                                        == null) {
7594                                    continue;
7595                                }
7596                            } else if (rti.baseIntent != null) {
7597                                if (pm.queryIntentActivities(rti.baseIntent,
7598                                        null, 0, userId) == null) {
7599                                    continue;
7600                                }
7601                            }
7602                        } catch (RemoteException e) {
7603                            // Will never happen.
7604                        }
7605                    }
7606
7607                    res.add(rti);
7608                    maxNum--;
7609                }
7610            }
7611            return res;
7612        }
7613    }
7614
7615    private TaskRecord recentTaskForIdLocked(int id) {
7616        final int N = mRecentTasks.size();
7617            for (int i=0; i<N; i++) {
7618                TaskRecord tr = mRecentTasks.get(i);
7619                if (tr.taskId == id) {
7620                    return tr;
7621                }
7622            }
7623            return null;
7624    }
7625
7626    @Override
7627    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7628        synchronized (this) {
7629            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7630                    "getTaskThumbnail()");
7631            TaskRecord tr = recentTaskForIdLocked(id);
7632            if (tr != null) {
7633                return tr.getTaskThumbnailLocked();
7634            }
7635        }
7636        return null;
7637    }
7638
7639    @Override
7640    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7641        synchronized (this) {
7642            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7643            if (r != null) {
7644                r.taskDescription = td;
7645                r.task.updateTaskDescription();
7646            }
7647        }
7648    }
7649
7650    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7651        if (!pr.killedByAm) {
7652            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7653            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7654                    pr.processName, pr.setAdj, reason);
7655            pr.killedByAm = true;
7656            Process.killProcessQuiet(pr.pid);
7657            Process.killProcessGroup(pr.info.uid, pr.pid);
7658        }
7659    }
7660
7661    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7662        tr.disposeThumbnail();
7663        mRecentTasks.remove(tr);
7664        tr.closeRecentsChain();
7665        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7666        Intent baseIntent = new Intent(
7667                tr.intent != null ? tr.intent : tr.affinityIntent);
7668        ComponentName component = baseIntent.getComponent();
7669        if (component == null) {
7670            Slog.w(TAG, "Now component for base intent of task: " + tr);
7671            return;
7672        }
7673
7674        // Find any running services associated with this app.
7675        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7676
7677        if (killProcesses) {
7678            // Find any running processes associated with this app.
7679            final String pkg = component.getPackageName();
7680            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7681            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7682            for (int i=0; i<pmap.size(); i++) {
7683                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7684                for (int j=0; j<uids.size(); j++) {
7685                    ProcessRecord proc = uids.valueAt(j);
7686                    if (proc.userId != tr.userId) {
7687                        continue;
7688                    }
7689                    if (!proc.pkgList.containsKey(pkg)) {
7690                        continue;
7691                    }
7692                    procs.add(proc);
7693                }
7694            }
7695
7696            // Kill the running processes.
7697            for (int i=0; i<procs.size(); i++) {
7698                ProcessRecord pr = procs.get(i);
7699                if (pr == mHomeProcess) {
7700                    // Don't kill the home process along with tasks from the same package.
7701                    continue;
7702                }
7703                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7704                    killUnneededProcessLocked(pr, "remove task");
7705                } else {
7706                    pr.waitingToKill = "remove task";
7707                }
7708            }
7709        }
7710    }
7711
7712    /**
7713     * Removes the task with the specified task id.
7714     *
7715     * @param taskId Identifier of the task to be removed.
7716     * @param flags Additional operational flags.  May be 0 or
7717     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7718     * @return Returns true if the given task was found and removed.
7719     */
7720    private boolean removeTaskByIdLocked(int taskId, int flags) {
7721        TaskRecord tr = recentTaskForIdLocked(taskId);
7722        if (tr != null) {
7723            tr.removeTaskActivitiesLocked();
7724            cleanUpRemovedTaskLocked(tr, flags);
7725            if (tr.isPersistable) {
7726                notifyTaskPersisterLocked(null, true);
7727            }
7728            return true;
7729        }
7730        return false;
7731    }
7732
7733    @Override
7734    public boolean removeTask(int taskId, int flags) {
7735        synchronized (this) {
7736            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7737                    "removeTask()");
7738            long ident = Binder.clearCallingIdentity();
7739            try {
7740                return removeTaskByIdLocked(taskId, flags);
7741            } finally {
7742                Binder.restoreCallingIdentity(ident);
7743            }
7744        }
7745    }
7746
7747    /**
7748     * TODO: Add mController hook
7749     */
7750    @Override
7751    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7752        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7753                "moveTaskToFront()");
7754
7755        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7756        synchronized(this) {
7757            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7758                    Binder.getCallingUid(), "Task to front")) {
7759                ActivityOptions.abort(options);
7760                return;
7761            }
7762            final long origId = Binder.clearCallingIdentity();
7763            try {
7764                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7765                if (task == null) {
7766                    return;
7767                }
7768                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7769                    mStackSupervisor.showLockTaskToast();
7770                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7771                    return;
7772                }
7773                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7774                if (prev != null && prev.isRecentsActivity()) {
7775                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7776                }
7777                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7778            } finally {
7779                Binder.restoreCallingIdentity(origId);
7780            }
7781            ActivityOptions.abort(options);
7782        }
7783    }
7784
7785    @Override
7786    public void moveTaskToBack(int taskId) {
7787        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7788                "moveTaskToBack()");
7789
7790        synchronized(this) {
7791            TaskRecord tr = recentTaskForIdLocked(taskId);
7792            if (tr != null) {
7793                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7794                ActivityStack stack = tr.stack;
7795                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7796                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7797                            Binder.getCallingUid(), "Task to back")) {
7798                        return;
7799                    }
7800                }
7801                final long origId = Binder.clearCallingIdentity();
7802                try {
7803                    stack.moveTaskToBackLocked(taskId, null);
7804                } finally {
7805                    Binder.restoreCallingIdentity(origId);
7806                }
7807            }
7808        }
7809    }
7810
7811    /**
7812     * Moves an activity, and all of the other activities within the same task, to the bottom
7813     * of the history stack.  The activity's order within the task is unchanged.
7814     *
7815     * @param token A reference to the activity we wish to move
7816     * @param nonRoot If false then this only works if the activity is the root
7817     *                of a task; if true it will work for any activity in a task.
7818     * @return Returns true if the move completed, false if not.
7819     */
7820    @Override
7821    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7822        enforceNotIsolatedCaller("moveActivityTaskToBack");
7823        synchronized(this) {
7824            final long origId = Binder.clearCallingIdentity();
7825            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7826            if (taskId >= 0) {
7827                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7828            }
7829            Binder.restoreCallingIdentity(origId);
7830        }
7831        return false;
7832    }
7833
7834    @Override
7835    public void moveTaskBackwards(int task) {
7836        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7837                "moveTaskBackwards()");
7838
7839        synchronized(this) {
7840            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7841                    Binder.getCallingUid(), "Task backwards")) {
7842                return;
7843            }
7844            final long origId = Binder.clearCallingIdentity();
7845            moveTaskBackwardsLocked(task);
7846            Binder.restoreCallingIdentity(origId);
7847        }
7848    }
7849
7850    private final void moveTaskBackwardsLocked(int task) {
7851        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7852    }
7853
7854    @Override
7855    public IBinder getHomeActivityToken() throws RemoteException {
7856        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7857                "getHomeActivityToken()");
7858        synchronized (this) {
7859            return mStackSupervisor.getHomeActivityToken();
7860        }
7861    }
7862
7863    @Override
7864    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7865            IActivityContainerCallback callback) throws RemoteException {
7866        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7867                "createActivityContainer()");
7868        synchronized (this) {
7869            if (parentActivityToken == null) {
7870                throw new IllegalArgumentException("parent token must not be null");
7871            }
7872            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7873            if (r == null) {
7874                return null;
7875            }
7876            if (callback == null) {
7877                throw new IllegalArgumentException("callback must not be null");
7878            }
7879            return mStackSupervisor.createActivityContainer(r, callback);
7880        }
7881    }
7882
7883    @Override
7884    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7885        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7886                "deleteActivityContainer()");
7887        synchronized (this) {
7888            mStackSupervisor.deleteActivityContainer(container);
7889        }
7890    }
7891
7892    @Override
7893    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7894            throws RemoteException {
7895        synchronized (this) {
7896            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7897            if (stack != null) {
7898                return stack.mActivityContainer;
7899            }
7900            return null;
7901        }
7902    }
7903
7904    @Override
7905    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7906        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7907                "moveTaskToStack()");
7908        if (stackId == HOME_STACK_ID) {
7909            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7910                    new RuntimeException("here").fillInStackTrace());
7911        }
7912        synchronized (this) {
7913            long ident = Binder.clearCallingIdentity();
7914            try {
7915                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7916                        + stackId + " toTop=" + toTop);
7917                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7918            } finally {
7919                Binder.restoreCallingIdentity(ident);
7920            }
7921        }
7922    }
7923
7924    @Override
7925    public void resizeStack(int stackBoxId, Rect bounds) {
7926        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7927                "resizeStackBox()");
7928        long ident = Binder.clearCallingIdentity();
7929        try {
7930            mWindowManager.resizeStack(stackBoxId, bounds);
7931        } finally {
7932            Binder.restoreCallingIdentity(ident);
7933        }
7934    }
7935
7936    @Override
7937    public List<StackInfo> getAllStackInfos() {
7938        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7939                "getAllStackInfos()");
7940        long ident = Binder.clearCallingIdentity();
7941        try {
7942            synchronized (this) {
7943                return mStackSupervisor.getAllStackInfosLocked();
7944            }
7945        } finally {
7946            Binder.restoreCallingIdentity(ident);
7947        }
7948    }
7949
7950    @Override
7951    public StackInfo getStackInfo(int stackId) {
7952        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7953                "getStackInfo()");
7954        long ident = Binder.clearCallingIdentity();
7955        try {
7956            synchronized (this) {
7957                return mStackSupervisor.getStackInfoLocked(stackId);
7958            }
7959        } finally {
7960            Binder.restoreCallingIdentity(ident);
7961        }
7962    }
7963
7964    @Override
7965    public boolean isInHomeStack(int taskId) {
7966        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7967                "getStackInfo()");
7968        long ident = Binder.clearCallingIdentity();
7969        try {
7970            synchronized (this) {
7971                TaskRecord tr = recentTaskForIdLocked(taskId);
7972                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7973            }
7974        } finally {
7975            Binder.restoreCallingIdentity(ident);
7976        }
7977    }
7978
7979    @Override
7980    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7981        synchronized(this) {
7982            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7983        }
7984    }
7985
7986    private boolean isLockTaskAuthorized(String pkg) {
7987        final DevicePolicyManager dpm = (DevicePolicyManager)
7988                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7989        try {
7990            int uid = mContext.getPackageManager().getPackageUid(pkg,
7991                    Binder.getCallingUserHandle().getIdentifier());
7992            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7993        } catch (NameNotFoundException e) {
7994            return false;
7995        }
7996    }
7997
7998    void startLockTaskMode(TaskRecord task) {
7999        final String pkg;
8000        synchronized (this) {
8001            pkg = task.intent.getComponent().getPackageName();
8002        }
8003        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8004        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8005            final TaskRecord taskRecord = task;
8006            mHandler.post(new Runnable() {
8007                @Override
8008                public void run() {
8009                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8010                }
8011            });
8012            return;
8013        }
8014        long ident = Binder.clearCallingIdentity();
8015        try {
8016            synchronized (this) {
8017                // Since we lost lock on task, make sure it is still there.
8018                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8019                if (task != null) {
8020                    if (!isSystemInitiated
8021                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8022                        throw new IllegalArgumentException("Invalid task, not in foreground");
8023                    }
8024                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8025                }
8026            }
8027        } finally {
8028            Binder.restoreCallingIdentity(ident);
8029        }
8030    }
8031
8032    @Override
8033    public void startLockTaskMode(int taskId) {
8034        final TaskRecord task;
8035        long ident = Binder.clearCallingIdentity();
8036        try {
8037            synchronized (this) {
8038                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8039            }
8040        } finally {
8041            Binder.restoreCallingIdentity(ident);
8042        }
8043        if (task != null) {
8044            startLockTaskMode(task);
8045        }
8046    }
8047
8048    @Override
8049    public void startLockTaskMode(IBinder token) {
8050        final TaskRecord task;
8051        long ident = Binder.clearCallingIdentity();
8052        try {
8053            synchronized (this) {
8054                final ActivityRecord r = ActivityRecord.forToken(token);
8055                if (r == null) {
8056                    return;
8057                }
8058                task = r.task;
8059            }
8060        } finally {
8061            Binder.restoreCallingIdentity(ident);
8062        }
8063        if (task != null) {
8064            startLockTaskMode(task);
8065        }
8066    }
8067
8068    @Override
8069    public void startLockTaskModeOnCurrent() throws RemoteException {
8070        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8071        ActivityRecord r = null;
8072        synchronized (this) {
8073            r = mStackSupervisor.topRunningActivityLocked();
8074        }
8075        startLockTaskMode(r.task);
8076    }
8077
8078    @Override
8079    public void stopLockTaskMode() {
8080        // Verify that the user matches the package of the intent for the TaskRecord
8081        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8082        // and stopLockTaskMode.
8083        final int callingUid = Binder.getCallingUid();
8084        if (callingUid != Process.SYSTEM_UID) {
8085            try {
8086                String pkg =
8087                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8088                int uid = mContext.getPackageManager().getPackageUid(pkg,
8089                        Binder.getCallingUserHandle().getIdentifier());
8090                if (uid != callingUid) {
8091                    throw new SecurityException("Invalid uid, expected " + uid);
8092                }
8093            } catch (NameNotFoundException e) {
8094                Log.d(TAG, "stopLockTaskMode " + e);
8095                return;
8096            }
8097        }
8098        long ident = Binder.clearCallingIdentity();
8099        try {
8100            Log.d(TAG, "stopLockTaskMode");
8101            // Stop lock task
8102            synchronized (this) {
8103                mStackSupervisor.setLockTaskModeLocked(null, false);
8104            }
8105        } finally {
8106            Binder.restoreCallingIdentity(ident);
8107        }
8108    }
8109
8110    @Override
8111    public void stopLockTaskModeOnCurrent() throws RemoteException {
8112        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8113        long ident = Binder.clearCallingIdentity();
8114        try {
8115            stopLockTaskMode();
8116        } finally {
8117            Binder.restoreCallingIdentity(ident);
8118        }
8119    }
8120
8121    @Override
8122    public boolean isInLockTaskMode() {
8123        synchronized (this) {
8124            return mStackSupervisor.isInLockTaskMode();
8125        }
8126    }
8127
8128    // =========================================================
8129    // CONTENT PROVIDERS
8130    // =========================================================
8131
8132    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8133        List<ProviderInfo> providers = null;
8134        try {
8135            providers = AppGlobals.getPackageManager().
8136                queryContentProviders(app.processName, app.uid,
8137                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8138        } catch (RemoteException ex) {
8139        }
8140        if (DEBUG_MU)
8141            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8142        int userId = app.userId;
8143        if (providers != null) {
8144            int N = providers.size();
8145            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8146            for (int i=0; i<N; i++) {
8147                ProviderInfo cpi =
8148                    (ProviderInfo)providers.get(i);
8149                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8150                        cpi.name, cpi.flags);
8151                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8152                    // This is a singleton provider, but a user besides the
8153                    // default user is asking to initialize a process it runs
8154                    // in...  well, no, it doesn't actually run in this process,
8155                    // it runs in the process of the default user.  Get rid of it.
8156                    providers.remove(i);
8157                    N--;
8158                    i--;
8159                    continue;
8160                }
8161
8162                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8163                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8164                if (cpr == null) {
8165                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8166                    mProviderMap.putProviderByClass(comp, cpr);
8167                }
8168                if (DEBUG_MU)
8169                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8170                app.pubProviders.put(cpi.name, cpr);
8171                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8172                    // Don't add this if it is a platform component that is marked
8173                    // to run in multiple processes, because this is actually
8174                    // part of the framework so doesn't make sense to track as a
8175                    // separate apk in the process.
8176                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8177                            mProcessStats);
8178                }
8179                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8180            }
8181        }
8182        return providers;
8183    }
8184
8185    /**
8186     * Check if {@link ProcessRecord} has a possible chance at accessing the
8187     * given {@link ProviderInfo}. Final permission checking is always done
8188     * in {@link ContentProvider}.
8189     */
8190    private final String checkContentProviderPermissionLocked(
8191            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8192        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8193        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8194        boolean checkedGrants = false;
8195        if (checkUser) {
8196            // Looking for cross-user grants before enforcing the typical cross-users permissions
8197            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8198            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8199                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8200                    return null;
8201                }
8202                checkedGrants = true;
8203            }
8204            userId = handleIncomingUser(callingPid, callingUid, userId,
8205                    false, ALLOW_NON_FULL,
8206                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8207            if (userId != tmpTargetUserId) {
8208                // When we actually went to determine the final targer user ID, this ended
8209                // up different than our initial check for the authority.  This is because
8210                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8211                // SELF.  So we need to re-check the grants again.
8212                checkedGrants = false;
8213            }
8214        }
8215        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8216                cpi.applicationInfo.uid, cpi.exported)
8217                == PackageManager.PERMISSION_GRANTED) {
8218            return null;
8219        }
8220        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8221                cpi.applicationInfo.uid, cpi.exported)
8222                == PackageManager.PERMISSION_GRANTED) {
8223            return null;
8224        }
8225
8226        PathPermission[] pps = cpi.pathPermissions;
8227        if (pps != null) {
8228            int i = pps.length;
8229            while (i > 0) {
8230                i--;
8231                PathPermission pp = pps[i];
8232                String pprperm = pp.getReadPermission();
8233                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8234                        cpi.applicationInfo.uid, cpi.exported)
8235                        == PackageManager.PERMISSION_GRANTED) {
8236                    return null;
8237                }
8238                String ppwperm = pp.getWritePermission();
8239                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8240                        cpi.applicationInfo.uid, cpi.exported)
8241                        == PackageManager.PERMISSION_GRANTED) {
8242                    return null;
8243                }
8244            }
8245        }
8246        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8247            return null;
8248        }
8249
8250        String msg;
8251        if (!cpi.exported) {
8252            msg = "Permission Denial: opening provider " + cpi.name
8253                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8254                    + ", uid=" + callingUid + ") that is not exported from uid "
8255                    + cpi.applicationInfo.uid;
8256        } else {
8257            msg = "Permission Denial: opening provider " + cpi.name
8258                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8259                    + ", uid=" + callingUid + ") requires "
8260                    + cpi.readPermission + " or " + cpi.writePermission;
8261        }
8262        Slog.w(TAG, msg);
8263        return msg;
8264    }
8265
8266    /**
8267     * Returns if the ContentProvider has granted a uri to callingUid
8268     */
8269    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8270        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8271        if (perms != null) {
8272            for (int i=perms.size()-1; i>=0; i--) {
8273                GrantUri grantUri = perms.keyAt(i);
8274                if (grantUri.sourceUserId == userId || !checkUser) {
8275                    if (matchesProvider(grantUri.uri, cpi)) {
8276                        return true;
8277                    }
8278                }
8279            }
8280        }
8281        return false;
8282    }
8283
8284    /**
8285     * Returns true if the uri authority is one of the authorities specified in the provider.
8286     */
8287    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8288        String uriAuth = uri.getAuthority();
8289        String cpiAuth = cpi.authority;
8290        if (cpiAuth.indexOf(';') == -1) {
8291            return cpiAuth.equals(uriAuth);
8292        }
8293        String[] cpiAuths = cpiAuth.split(";");
8294        int length = cpiAuths.length;
8295        for (int i = 0; i < length; i++) {
8296            if (cpiAuths[i].equals(uriAuth)) return true;
8297        }
8298        return false;
8299    }
8300
8301    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8302            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8303        if (r != null) {
8304            for (int i=0; i<r.conProviders.size(); i++) {
8305                ContentProviderConnection conn = r.conProviders.get(i);
8306                if (conn.provider == cpr) {
8307                    if (DEBUG_PROVIDER) Slog.v(TAG,
8308                            "Adding provider requested by "
8309                            + r.processName + " from process "
8310                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8311                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8312                    if (stable) {
8313                        conn.stableCount++;
8314                        conn.numStableIncs++;
8315                    } else {
8316                        conn.unstableCount++;
8317                        conn.numUnstableIncs++;
8318                    }
8319                    return conn;
8320                }
8321            }
8322            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8323            if (stable) {
8324                conn.stableCount = 1;
8325                conn.numStableIncs = 1;
8326            } else {
8327                conn.unstableCount = 1;
8328                conn.numUnstableIncs = 1;
8329            }
8330            cpr.connections.add(conn);
8331            r.conProviders.add(conn);
8332            return conn;
8333        }
8334        cpr.addExternalProcessHandleLocked(externalProcessToken);
8335        return null;
8336    }
8337
8338    boolean decProviderCountLocked(ContentProviderConnection conn,
8339            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8340        if (conn != null) {
8341            cpr = conn.provider;
8342            if (DEBUG_PROVIDER) Slog.v(TAG,
8343                    "Removing provider requested by "
8344                    + conn.client.processName + " from process "
8345                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8346                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8347            if (stable) {
8348                conn.stableCount--;
8349            } else {
8350                conn.unstableCount--;
8351            }
8352            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8353                cpr.connections.remove(conn);
8354                conn.client.conProviders.remove(conn);
8355                return true;
8356            }
8357            return false;
8358        }
8359        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8360        return false;
8361    }
8362
8363    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8364            String name, IBinder token, boolean stable, int userId) {
8365        ContentProviderRecord cpr;
8366        ContentProviderConnection conn = null;
8367        ProviderInfo cpi = null;
8368
8369        synchronized(this) {
8370            ProcessRecord r = null;
8371            if (caller != null) {
8372                r = getRecordForAppLocked(caller);
8373                if (r == null) {
8374                    throw new SecurityException(
8375                            "Unable to find app for caller " + caller
8376                          + " (pid=" + Binder.getCallingPid()
8377                          + ") when getting content provider " + name);
8378                }
8379            }
8380
8381            boolean checkCrossUser = true;
8382
8383            // First check if this content provider has been published...
8384            cpr = mProviderMap.getProviderByName(name, userId);
8385            // If that didn't work, check if it exists for user 0 and then
8386            // verify that it's a singleton provider before using it.
8387            if (cpr == null && userId != UserHandle.USER_OWNER) {
8388                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8389                if (cpr != null) {
8390                    cpi = cpr.info;
8391                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8392                            cpi.name, cpi.flags)
8393                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8394                        userId = UserHandle.USER_OWNER;
8395                        checkCrossUser = false;
8396                    } else {
8397                        cpr = null;
8398                        cpi = null;
8399                    }
8400                }
8401            }
8402
8403            boolean providerRunning = cpr != null;
8404            if (providerRunning) {
8405                cpi = cpr.info;
8406                String msg;
8407                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8408                        != null) {
8409                    throw new SecurityException(msg);
8410                }
8411
8412                if (r != null && cpr.canRunHere(r)) {
8413                    // This provider has been published or is in the process
8414                    // of being published...  but it is also allowed to run
8415                    // in the caller's process, so don't make a connection
8416                    // and just let the caller instantiate its own instance.
8417                    ContentProviderHolder holder = cpr.newHolder(null);
8418                    // don't give caller the provider object, it needs
8419                    // to make its own.
8420                    holder.provider = null;
8421                    return holder;
8422                }
8423
8424                final long origId = Binder.clearCallingIdentity();
8425
8426                // In this case the provider instance already exists, so we can
8427                // return it right away.
8428                conn = incProviderCountLocked(r, cpr, token, stable);
8429                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8430                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8431                        // If this is a perceptible app accessing the provider,
8432                        // make sure to count it as being accessed and thus
8433                        // back up on the LRU list.  This is good because
8434                        // content providers are often expensive to start.
8435                        updateLruProcessLocked(cpr.proc, false, null);
8436                    }
8437                }
8438
8439                if (cpr.proc != null) {
8440                    if (false) {
8441                        if (cpr.name.flattenToShortString().equals(
8442                                "com.android.providers.calendar/.CalendarProvider2")) {
8443                            Slog.v(TAG, "****************** KILLING "
8444                                + cpr.name.flattenToShortString());
8445                            Process.killProcess(cpr.proc.pid);
8446                        }
8447                    }
8448                    boolean success = updateOomAdjLocked(cpr.proc);
8449                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8450                    // NOTE: there is still a race here where a signal could be
8451                    // pending on the process even though we managed to update its
8452                    // adj level.  Not sure what to do about this, but at least
8453                    // the race is now smaller.
8454                    if (!success) {
8455                        // Uh oh...  it looks like the provider's process
8456                        // has been killed on us.  We need to wait for a new
8457                        // process to be started, and make sure its death
8458                        // doesn't kill our process.
8459                        Slog.i(TAG,
8460                                "Existing provider " + cpr.name.flattenToShortString()
8461                                + " is crashing; detaching " + r);
8462                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8463                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8464                        if (!lastRef) {
8465                            // This wasn't the last ref our process had on
8466                            // the provider...  we have now been killed, bail.
8467                            return null;
8468                        }
8469                        providerRunning = false;
8470                        conn = null;
8471                    }
8472                }
8473
8474                Binder.restoreCallingIdentity(origId);
8475            }
8476
8477            boolean singleton;
8478            if (!providerRunning) {
8479                try {
8480                    cpi = AppGlobals.getPackageManager().
8481                        resolveContentProvider(name,
8482                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8483                } catch (RemoteException ex) {
8484                }
8485                if (cpi == null) {
8486                    return null;
8487                }
8488                // If the provider is a singleton AND
8489                // (it's a call within the same user || the provider is a
8490                // privileged app)
8491                // Then allow connecting to the singleton provider
8492                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8493                        cpi.name, cpi.flags)
8494                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8495                if (singleton) {
8496                    userId = UserHandle.USER_OWNER;
8497                }
8498                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8499
8500                String msg;
8501                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8502                        != null) {
8503                    throw new SecurityException(msg);
8504                }
8505
8506                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8507                        && !cpi.processName.equals("system")) {
8508                    // If this content provider does not run in the system
8509                    // process, and the system is not yet ready to run other
8510                    // processes, then fail fast instead of hanging.
8511                    throw new IllegalArgumentException(
8512                            "Attempt to launch content provider before system ready");
8513                }
8514
8515                // Make sure that the user who owns this provider is started.  If not,
8516                // we don't want to allow it to run.
8517                if (mStartedUsers.get(userId) == null) {
8518                    Slog.w(TAG, "Unable to launch app "
8519                            + cpi.applicationInfo.packageName + "/"
8520                            + cpi.applicationInfo.uid + " for provider "
8521                            + name + ": user " + userId + " is stopped");
8522                    return null;
8523                }
8524
8525                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8526                cpr = mProviderMap.getProviderByClass(comp, userId);
8527                final boolean firstClass = cpr == null;
8528                if (firstClass) {
8529                    try {
8530                        ApplicationInfo ai =
8531                            AppGlobals.getPackageManager().
8532                                getApplicationInfo(
8533                                        cpi.applicationInfo.packageName,
8534                                        STOCK_PM_FLAGS, userId);
8535                        if (ai == null) {
8536                            Slog.w(TAG, "No package info for content provider "
8537                                    + cpi.name);
8538                            return null;
8539                        }
8540                        ai = getAppInfoForUser(ai, userId);
8541                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8542                    } catch (RemoteException ex) {
8543                        // pm is in same process, this will never happen.
8544                    }
8545                }
8546
8547                if (r != null && cpr.canRunHere(r)) {
8548                    // If this is a multiprocess provider, then just return its
8549                    // info and allow the caller to instantiate it.  Only do
8550                    // this if the provider is the same user as the caller's
8551                    // process, or can run as root (so can be in any process).
8552                    return cpr.newHolder(null);
8553                }
8554
8555                if (DEBUG_PROVIDER) {
8556                    RuntimeException e = new RuntimeException("here");
8557                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8558                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8559                }
8560
8561                // This is single process, and our app is now connecting to it.
8562                // See if we are already in the process of launching this
8563                // provider.
8564                final int N = mLaunchingProviders.size();
8565                int i;
8566                for (i=0; i<N; i++) {
8567                    if (mLaunchingProviders.get(i) == cpr) {
8568                        break;
8569                    }
8570                }
8571
8572                // If the provider is not already being launched, then get it
8573                // started.
8574                if (i >= N) {
8575                    final long origId = Binder.clearCallingIdentity();
8576
8577                    try {
8578                        // Content provider is now in use, its package can't be stopped.
8579                        try {
8580                            AppGlobals.getPackageManager().setPackageStoppedState(
8581                                    cpr.appInfo.packageName, false, userId);
8582                        } catch (RemoteException e) {
8583                        } catch (IllegalArgumentException e) {
8584                            Slog.w(TAG, "Failed trying to unstop package "
8585                                    + cpr.appInfo.packageName + ": " + e);
8586                        }
8587
8588                        // Use existing process if already started
8589                        ProcessRecord proc = getProcessRecordLocked(
8590                                cpi.processName, cpr.appInfo.uid, false);
8591                        if (proc != null && proc.thread != null) {
8592                            if (DEBUG_PROVIDER) {
8593                                Slog.d(TAG, "Installing in existing process " + proc);
8594                            }
8595                            proc.pubProviders.put(cpi.name, cpr);
8596                            try {
8597                                proc.thread.scheduleInstallProvider(cpi);
8598                            } catch (RemoteException e) {
8599                            }
8600                        } else {
8601                            proc = startProcessLocked(cpi.processName,
8602                                    cpr.appInfo, false, 0, "content provider",
8603                                    new ComponentName(cpi.applicationInfo.packageName,
8604                                            cpi.name), false, false, false);
8605                            if (proc == null) {
8606                                Slog.w(TAG, "Unable to launch app "
8607                                        + cpi.applicationInfo.packageName + "/"
8608                                        + cpi.applicationInfo.uid + " for provider "
8609                                        + name + ": process is bad");
8610                                return null;
8611                            }
8612                        }
8613                        cpr.launchingApp = proc;
8614                        mLaunchingProviders.add(cpr);
8615                    } finally {
8616                        Binder.restoreCallingIdentity(origId);
8617                    }
8618                }
8619
8620                // Make sure the provider is published (the same provider class
8621                // may be published under multiple names).
8622                if (firstClass) {
8623                    mProviderMap.putProviderByClass(comp, cpr);
8624                }
8625
8626                mProviderMap.putProviderByName(name, cpr);
8627                conn = incProviderCountLocked(r, cpr, token, stable);
8628                if (conn != null) {
8629                    conn.waiting = true;
8630                }
8631            }
8632        }
8633
8634        // Wait for the provider to be published...
8635        synchronized (cpr) {
8636            while (cpr.provider == null) {
8637                if (cpr.launchingApp == null) {
8638                    Slog.w(TAG, "Unable to launch app "
8639                            + cpi.applicationInfo.packageName + "/"
8640                            + cpi.applicationInfo.uid + " for provider "
8641                            + name + ": launching app became null");
8642                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8643                            UserHandle.getUserId(cpi.applicationInfo.uid),
8644                            cpi.applicationInfo.packageName,
8645                            cpi.applicationInfo.uid, name);
8646                    return null;
8647                }
8648                try {
8649                    if (DEBUG_MU) {
8650                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8651                                + cpr.launchingApp);
8652                    }
8653                    if (conn != null) {
8654                        conn.waiting = true;
8655                    }
8656                    cpr.wait();
8657                } catch (InterruptedException ex) {
8658                } finally {
8659                    if (conn != null) {
8660                        conn.waiting = false;
8661                    }
8662                }
8663            }
8664        }
8665        return cpr != null ? cpr.newHolder(conn) : null;
8666    }
8667
8668    @Override
8669    public final ContentProviderHolder getContentProvider(
8670            IApplicationThread caller, String name, int userId, boolean stable) {
8671        enforceNotIsolatedCaller("getContentProvider");
8672        if (caller == null) {
8673            String msg = "null IApplicationThread when getting content provider "
8674                    + name;
8675            Slog.w(TAG, msg);
8676            throw new SecurityException(msg);
8677        }
8678        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8679        // with cross-user grant.
8680        return getContentProviderImpl(caller, name, null, stable, userId);
8681    }
8682
8683    public ContentProviderHolder getContentProviderExternal(
8684            String name, int userId, IBinder token) {
8685        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8686            "Do not have permission in call getContentProviderExternal()");
8687        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8688                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8689        return getContentProviderExternalUnchecked(name, token, userId);
8690    }
8691
8692    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8693            IBinder token, int userId) {
8694        return getContentProviderImpl(null, name, token, true, userId);
8695    }
8696
8697    /**
8698     * Drop a content provider from a ProcessRecord's bookkeeping
8699     */
8700    public void removeContentProvider(IBinder connection, boolean stable) {
8701        enforceNotIsolatedCaller("removeContentProvider");
8702        long ident = Binder.clearCallingIdentity();
8703        try {
8704            synchronized (this) {
8705                ContentProviderConnection conn;
8706                try {
8707                    conn = (ContentProviderConnection)connection;
8708                } catch (ClassCastException e) {
8709                    String msg ="removeContentProvider: " + connection
8710                            + " not a ContentProviderConnection";
8711                    Slog.w(TAG, msg);
8712                    throw new IllegalArgumentException(msg);
8713                }
8714                if (conn == null) {
8715                    throw new NullPointerException("connection is null");
8716                }
8717                if (decProviderCountLocked(conn, null, null, stable)) {
8718                    updateOomAdjLocked();
8719                }
8720            }
8721        } finally {
8722            Binder.restoreCallingIdentity(ident);
8723        }
8724    }
8725
8726    public void removeContentProviderExternal(String name, IBinder token) {
8727        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8728            "Do not have permission in call removeContentProviderExternal()");
8729        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8730    }
8731
8732    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8733        synchronized (this) {
8734            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8735            if(cpr == null) {
8736                //remove from mProvidersByClass
8737                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8738                return;
8739            }
8740
8741            //update content provider record entry info
8742            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8743            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8744            if (localCpr.hasExternalProcessHandles()) {
8745                if (localCpr.removeExternalProcessHandleLocked(token)) {
8746                    updateOomAdjLocked();
8747                } else {
8748                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8749                            + " with no external reference for token: "
8750                            + token + ".");
8751                }
8752            } else {
8753                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8754                        + " with no external references.");
8755            }
8756        }
8757    }
8758
8759    public final void publishContentProviders(IApplicationThread caller,
8760            List<ContentProviderHolder> providers) {
8761        if (providers == null) {
8762            return;
8763        }
8764
8765        enforceNotIsolatedCaller("publishContentProviders");
8766        synchronized (this) {
8767            final ProcessRecord r = getRecordForAppLocked(caller);
8768            if (DEBUG_MU)
8769                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8770            if (r == null) {
8771                throw new SecurityException(
8772                        "Unable to find app for caller " + caller
8773                      + " (pid=" + Binder.getCallingPid()
8774                      + ") when publishing content providers");
8775            }
8776
8777            final long origId = Binder.clearCallingIdentity();
8778
8779            final int N = providers.size();
8780            for (int i=0; i<N; i++) {
8781                ContentProviderHolder src = providers.get(i);
8782                if (src == null || src.info == null || src.provider == null) {
8783                    continue;
8784                }
8785                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8786                if (DEBUG_MU)
8787                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8788                if (dst != null) {
8789                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8790                    mProviderMap.putProviderByClass(comp, dst);
8791                    String names[] = dst.info.authority.split(";");
8792                    for (int j = 0; j < names.length; j++) {
8793                        mProviderMap.putProviderByName(names[j], dst);
8794                    }
8795
8796                    int NL = mLaunchingProviders.size();
8797                    int j;
8798                    for (j=0; j<NL; j++) {
8799                        if (mLaunchingProviders.get(j) == dst) {
8800                            mLaunchingProviders.remove(j);
8801                            j--;
8802                            NL--;
8803                        }
8804                    }
8805                    synchronized (dst) {
8806                        dst.provider = src.provider;
8807                        dst.proc = r;
8808                        dst.notifyAll();
8809                    }
8810                    updateOomAdjLocked(r);
8811                }
8812            }
8813
8814            Binder.restoreCallingIdentity(origId);
8815        }
8816    }
8817
8818    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8819        ContentProviderConnection conn;
8820        try {
8821            conn = (ContentProviderConnection)connection;
8822        } catch (ClassCastException e) {
8823            String msg ="refContentProvider: " + connection
8824                    + " not a ContentProviderConnection";
8825            Slog.w(TAG, msg);
8826            throw new IllegalArgumentException(msg);
8827        }
8828        if (conn == null) {
8829            throw new NullPointerException("connection is null");
8830        }
8831
8832        synchronized (this) {
8833            if (stable > 0) {
8834                conn.numStableIncs += stable;
8835            }
8836            stable = conn.stableCount + stable;
8837            if (stable < 0) {
8838                throw new IllegalStateException("stableCount < 0: " + stable);
8839            }
8840
8841            if (unstable > 0) {
8842                conn.numUnstableIncs += unstable;
8843            }
8844            unstable = conn.unstableCount + unstable;
8845            if (unstable < 0) {
8846                throw new IllegalStateException("unstableCount < 0: " + unstable);
8847            }
8848
8849            if ((stable+unstable) <= 0) {
8850                throw new IllegalStateException("ref counts can't go to zero here: stable="
8851                        + stable + " unstable=" + unstable);
8852            }
8853            conn.stableCount = stable;
8854            conn.unstableCount = unstable;
8855            return !conn.dead;
8856        }
8857    }
8858
8859    public void unstableProviderDied(IBinder connection) {
8860        ContentProviderConnection conn;
8861        try {
8862            conn = (ContentProviderConnection)connection;
8863        } catch (ClassCastException e) {
8864            String msg ="refContentProvider: " + connection
8865                    + " not a ContentProviderConnection";
8866            Slog.w(TAG, msg);
8867            throw new IllegalArgumentException(msg);
8868        }
8869        if (conn == null) {
8870            throw new NullPointerException("connection is null");
8871        }
8872
8873        // Safely retrieve the content provider associated with the connection.
8874        IContentProvider provider;
8875        synchronized (this) {
8876            provider = conn.provider.provider;
8877        }
8878
8879        if (provider == null) {
8880            // Um, yeah, we're way ahead of you.
8881            return;
8882        }
8883
8884        // Make sure the caller is being honest with us.
8885        if (provider.asBinder().pingBinder()) {
8886            // Er, no, still looks good to us.
8887            synchronized (this) {
8888                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8889                        + " says " + conn + " died, but we don't agree");
8890                return;
8891            }
8892        }
8893
8894        // Well look at that!  It's dead!
8895        synchronized (this) {
8896            if (conn.provider.provider != provider) {
8897                // But something changed...  good enough.
8898                return;
8899            }
8900
8901            ProcessRecord proc = conn.provider.proc;
8902            if (proc == null || proc.thread == null) {
8903                // Seems like the process is already cleaned up.
8904                return;
8905            }
8906
8907            // As far as we're concerned, this is just like receiving a
8908            // death notification...  just a bit prematurely.
8909            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8910                    + ") early provider death");
8911            final long ident = Binder.clearCallingIdentity();
8912            try {
8913                appDiedLocked(proc, proc.pid, proc.thread);
8914            } finally {
8915                Binder.restoreCallingIdentity(ident);
8916            }
8917        }
8918    }
8919
8920    @Override
8921    public void appNotRespondingViaProvider(IBinder connection) {
8922        enforceCallingPermission(
8923                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8924
8925        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8926        if (conn == null) {
8927            Slog.w(TAG, "ContentProviderConnection is null");
8928            return;
8929        }
8930
8931        final ProcessRecord host = conn.provider.proc;
8932        if (host == null) {
8933            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8934            return;
8935        }
8936
8937        final long token = Binder.clearCallingIdentity();
8938        try {
8939            appNotResponding(host, null, null, false, "ContentProvider not responding");
8940        } finally {
8941            Binder.restoreCallingIdentity(token);
8942        }
8943    }
8944
8945    public final void installSystemProviders() {
8946        List<ProviderInfo> providers;
8947        synchronized (this) {
8948            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8949            providers = generateApplicationProvidersLocked(app);
8950            if (providers != null) {
8951                for (int i=providers.size()-1; i>=0; i--) {
8952                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8953                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8954                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8955                                + ": not system .apk");
8956                        providers.remove(i);
8957                    }
8958                }
8959            }
8960        }
8961        if (providers != null) {
8962            mSystemThread.installSystemProviders(providers);
8963        }
8964
8965        mCoreSettingsObserver = new CoreSettingsObserver(this);
8966
8967        //mUsageStatsService.monitorPackages();
8968    }
8969
8970    /**
8971     * Allows app to retrieve the MIME type of a URI without having permission
8972     * to access its content provider.
8973     *
8974     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8975     *
8976     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8977     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8978     */
8979    public String getProviderMimeType(Uri uri, int userId) {
8980        enforceNotIsolatedCaller("getProviderMimeType");
8981        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8982                userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null);
8983        final String name = uri.getAuthority();
8984        final long ident = Binder.clearCallingIdentity();
8985        ContentProviderHolder holder = null;
8986
8987        try {
8988            holder = getContentProviderExternalUnchecked(name, null, userId);
8989            if (holder != null) {
8990                return holder.provider.getType(uri);
8991            }
8992        } catch (RemoteException e) {
8993            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8994            return null;
8995        } finally {
8996            if (holder != null) {
8997                removeContentProviderExternalUnchecked(name, null, userId);
8998            }
8999            Binder.restoreCallingIdentity(ident);
9000        }
9001
9002        return null;
9003    }
9004
9005    // =========================================================
9006    // GLOBAL MANAGEMENT
9007    // =========================================================
9008
9009    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9010            boolean isolated, int isolatedUid) {
9011        String proc = customProcess != null ? customProcess : info.processName;
9012        BatteryStatsImpl.Uid.Proc ps = null;
9013        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9014        int uid = info.uid;
9015        if (isolated) {
9016            if (isolatedUid == 0) {
9017                int userId = UserHandle.getUserId(uid);
9018                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9019                while (true) {
9020                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9021                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9022                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9023                    }
9024                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9025                    mNextIsolatedProcessUid++;
9026                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9027                        // No process for this uid, use it.
9028                        break;
9029                    }
9030                    stepsLeft--;
9031                    if (stepsLeft <= 0) {
9032                        return null;
9033                    }
9034                }
9035            } else {
9036                // Special case for startIsolatedProcess (internal only), where
9037                // the uid of the isolated process is specified by the caller.
9038                uid = isolatedUid;
9039            }
9040        }
9041        return new ProcessRecord(stats, info, proc, uid);
9042    }
9043
9044    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9045            String abiOverride) {
9046        ProcessRecord app;
9047        if (!isolated) {
9048            app = getProcessRecordLocked(info.processName, info.uid, true);
9049        } else {
9050            app = null;
9051        }
9052
9053        if (app == null) {
9054            app = newProcessRecordLocked(info, null, isolated, 0);
9055            mProcessNames.put(info.processName, app.uid, app);
9056            if (isolated) {
9057                mIsolatedProcesses.put(app.uid, app);
9058            }
9059            updateLruProcessLocked(app, false, null);
9060            updateOomAdjLocked();
9061        }
9062
9063        // This package really, really can not be stopped.
9064        try {
9065            AppGlobals.getPackageManager().setPackageStoppedState(
9066                    info.packageName, false, UserHandle.getUserId(app.uid));
9067        } catch (RemoteException e) {
9068        } catch (IllegalArgumentException e) {
9069            Slog.w(TAG, "Failed trying to unstop package "
9070                    + info.packageName + ": " + e);
9071        }
9072
9073        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9074                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9075            app.persistent = true;
9076            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9077        }
9078        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9079            mPersistentStartingProcesses.add(app);
9080            startProcessLocked(app, "added application", app.processName, abiOverride,
9081                    null /* entryPoint */, null /* entryPointArgs */);
9082        }
9083
9084        return app;
9085    }
9086
9087    public void unhandledBack() {
9088        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9089                "unhandledBack()");
9090
9091        synchronized(this) {
9092            final long origId = Binder.clearCallingIdentity();
9093            try {
9094                getFocusedStack().unhandledBackLocked();
9095            } finally {
9096                Binder.restoreCallingIdentity(origId);
9097            }
9098        }
9099    }
9100
9101    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9102        enforceNotIsolatedCaller("openContentUri");
9103        final int userId = UserHandle.getCallingUserId();
9104        String name = uri.getAuthority();
9105        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9106        ParcelFileDescriptor pfd = null;
9107        if (cph != null) {
9108            // We record the binder invoker's uid in thread-local storage before
9109            // going to the content provider to open the file.  Later, in the code
9110            // that handles all permissions checks, we look for this uid and use
9111            // that rather than the Activity Manager's own uid.  The effect is that
9112            // we do the check against the caller's permissions even though it looks
9113            // to the content provider like the Activity Manager itself is making
9114            // the request.
9115            sCallerIdentity.set(new Identity(
9116                    Binder.getCallingPid(), Binder.getCallingUid()));
9117            try {
9118                pfd = cph.provider.openFile(null, uri, "r", null);
9119            } catch (FileNotFoundException e) {
9120                // do nothing; pfd will be returned null
9121            } finally {
9122                // Ensure that whatever happens, we clean up the identity state
9123                sCallerIdentity.remove();
9124            }
9125
9126            // We've got the fd now, so we're done with the provider.
9127            removeContentProviderExternalUnchecked(name, null, userId);
9128        } else {
9129            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9130        }
9131        return pfd;
9132    }
9133
9134    // Actually is sleeping or shutting down or whatever else in the future
9135    // is an inactive state.
9136    public boolean isSleepingOrShuttingDown() {
9137        return mSleeping || mShuttingDown;
9138    }
9139
9140    public boolean isSleeping() {
9141        return mSleeping;
9142    }
9143
9144    void goingToSleep() {
9145        synchronized(this) {
9146            mWentToSleep = true;
9147            updateEventDispatchingLocked();
9148            goToSleepIfNeededLocked();
9149        }
9150    }
9151
9152    void finishRunningVoiceLocked() {
9153        if (mRunningVoice) {
9154            mRunningVoice = false;
9155            goToSleepIfNeededLocked();
9156        }
9157    }
9158
9159    void goToSleepIfNeededLocked() {
9160        if (mWentToSleep && !mRunningVoice) {
9161            if (!mSleeping) {
9162                mSleeping = true;
9163                mStackSupervisor.goingToSleepLocked();
9164
9165                // Initialize the wake times of all processes.
9166                checkExcessivePowerUsageLocked(false);
9167                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9168                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9169                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9170            }
9171        }
9172    }
9173
9174    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9175        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9176            // Never persist the home stack.
9177            return;
9178        }
9179        mTaskPersister.wakeup(task, flush);
9180    }
9181
9182    @Override
9183    public boolean shutdown(int timeout) {
9184        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9185                != PackageManager.PERMISSION_GRANTED) {
9186            throw new SecurityException("Requires permission "
9187                    + android.Manifest.permission.SHUTDOWN);
9188        }
9189
9190        boolean timedout = false;
9191
9192        synchronized(this) {
9193            mShuttingDown = true;
9194            updateEventDispatchingLocked();
9195            timedout = mStackSupervisor.shutdownLocked(timeout);
9196        }
9197
9198        mAppOpsService.shutdown();
9199        if (mUsageStatsService != null) {
9200            mUsageStatsService.prepareShutdown();
9201        }
9202        mBatteryStatsService.shutdown();
9203        synchronized (this) {
9204            mProcessStats.shutdownLocked();
9205        }
9206        notifyTaskPersisterLocked(null, true);
9207
9208        return timedout;
9209    }
9210
9211    public final void activitySlept(IBinder token) {
9212        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9213
9214        final long origId = Binder.clearCallingIdentity();
9215
9216        synchronized (this) {
9217            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9218            if (r != null) {
9219                mStackSupervisor.activitySleptLocked(r);
9220            }
9221        }
9222
9223        Binder.restoreCallingIdentity(origId);
9224    }
9225
9226    void logLockScreen(String msg) {
9227        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9228                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9229                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9230                mStackSupervisor.mDismissKeyguardOnNextActivity);
9231    }
9232
9233    private void comeOutOfSleepIfNeededLocked() {
9234        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9235            if (mSleeping) {
9236                mSleeping = false;
9237                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9238            }
9239        }
9240    }
9241
9242    void wakingUp() {
9243        synchronized(this) {
9244            mWentToSleep = false;
9245            updateEventDispatchingLocked();
9246            comeOutOfSleepIfNeededLocked();
9247        }
9248    }
9249
9250    void startRunningVoiceLocked() {
9251        if (!mRunningVoice) {
9252            mRunningVoice = true;
9253            comeOutOfSleepIfNeededLocked();
9254        }
9255    }
9256
9257    private void updateEventDispatchingLocked() {
9258        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9259    }
9260
9261    public void setLockScreenShown(boolean shown) {
9262        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9263                != PackageManager.PERMISSION_GRANTED) {
9264            throw new SecurityException("Requires permission "
9265                    + android.Manifest.permission.DEVICE_POWER);
9266        }
9267
9268        synchronized(this) {
9269            long ident = Binder.clearCallingIdentity();
9270            try {
9271                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9272                mLockScreenShown = shown;
9273                comeOutOfSleepIfNeededLocked();
9274            } finally {
9275                Binder.restoreCallingIdentity(ident);
9276            }
9277        }
9278    }
9279
9280    @Override
9281    public void stopAppSwitches() {
9282        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9283                != PackageManager.PERMISSION_GRANTED) {
9284            throw new SecurityException("Requires permission "
9285                    + android.Manifest.permission.STOP_APP_SWITCHES);
9286        }
9287
9288        synchronized(this) {
9289            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9290                    + APP_SWITCH_DELAY_TIME;
9291            mDidAppSwitch = false;
9292            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9293            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9294            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9295        }
9296    }
9297
9298    public void resumeAppSwitches() {
9299        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9300                != PackageManager.PERMISSION_GRANTED) {
9301            throw new SecurityException("Requires permission "
9302                    + android.Manifest.permission.STOP_APP_SWITCHES);
9303        }
9304
9305        synchronized(this) {
9306            // Note that we don't execute any pending app switches... we will
9307            // let those wait until either the timeout, or the next start
9308            // activity request.
9309            mAppSwitchesAllowedTime = 0;
9310        }
9311    }
9312
9313    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9314            String name) {
9315        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9316            return true;
9317        }
9318
9319        final int perm = checkComponentPermission(
9320                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9321                callingUid, -1, true);
9322        if (perm == PackageManager.PERMISSION_GRANTED) {
9323            return true;
9324        }
9325
9326        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9327        return false;
9328    }
9329
9330    public void setDebugApp(String packageName, boolean waitForDebugger,
9331            boolean persistent) {
9332        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9333                "setDebugApp()");
9334
9335        long ident = Binder.clearCallingIdentity();
9336        try {
9337            // Note that this is not really thread safe if there are multiple
9338            // callers into it at the same time, but that's not a situation we
9339            // care about.
9340            if (persistent) {
9341                final ContentResolver resolver = mContext.getContentResolver();
9342                Settings.Global.putString(
9343                    resolver, Settings.Global.DEBUG_APP,
9344                    packageName);
9345                Settings.Global.putInt(
9346                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9347                    waitForDebugger ? 1 : 0);
9348            }
9349
9350            synchronized (this) {
9351                if (!persistent) {
9352                    mOrigDebugApp = mDebugApp;
9353                    mOrigWaitForDebugger = mWaitForDebugger;
9354                }
9355                mDebugApp = packageName;
9356                mWaitForDebugger = waitForDebugger;
9357                mDebugTransient = !persistent;
9358                if (packageName != null) {
9359                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9360                            false, UserHandle.USER_ALL, "set debug app");
9361                }
9362            }
9363        } finally {
9364            Binder.restoreCallingIdentity(ident);
9365        }
9366    }
9367
9368    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9369        synchronized (this) {
9370            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9371            if (!isDebuggable) {
9372                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9373                    throw new SecurityException("Process not debuggable: " + app.packageName);
9374                }
9375            }
9376
9377            mOpenGlTraceApp = processName;
9378        }
9379    }
9380
9381    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9382            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9383        synchronized (this) {
9384            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9385            if (!isDebuggable) {
9386                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9387                    throw new SecurityException("Process not debuggable: " + app.packageName);
9388                }
9389            }
9390            mProfileApp = processName;
9391            mProfileFile = profileFile;
9392            if (mProfileFd != null) {
9393                try {
9394                    mProfileFd.close();
9395                } catch (IOException e) {
9396                }
9397                mProfileFd = null;
9398            }
9399            mProfileFd = profileFd;
9400            mProfileType = 0;
9401            mAutoStopProfiler = autoStopProfiler;
9402        }
9403    }
9404
9405    @Override
9406    public void setAlwaysFinish(boolean enabled) {
9407        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9408                "setAlwaysFinish()");
9409
9410        Settings.Global.putInt(
9411                mContext.getContentResolver(),
9412                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9413
9414        synchronized (this) {
9415            mAlwaysFinishActivities = enabled;
9416        }
9417    }
9418
9419    @Override
9420    public void setActivityController(IActivityController controller) {
9421        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9422                "setActivityController()");
9423        synchronized (this) {
9424            mController = controller;
9425            Watchdog.getInstance().setActivityController(controller);
9426        }
9427    }
9428
9429    @Override
9430    public void setUserIsMonkey(boolean userIsMonkey) {
9431        synchronized (this) {
9432            synchronized (mPidsSelfLocked) {
9433                final int callingPid = Binder.getCallingPid();
9434                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9435                if (precessRecord == null) {
9436                    throw new SecurityException("Unknown process: " + callingPid);
9437                }
9438                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9439                    throw new SecurityException("Only an instrumentation process "
9440                            + "with a UiAutomation can call setUserIsMonkey");
9441                }
9442            }
9443            mUserIsMonkey = userIsMonkey;
9444        }
9445    }
9446
9447    @Override
9448    public boolean isUserAMonkey() {
9449        synchronized (this) {
9450            // If there is a controller also implies the user is a monkey.
9451            return (mUserIsMonkey || mController != null);
9452        }
9453    }
9454
9455    public void requestBugReport() {
9456        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9457        SystemProperties.set("ctl.start", "bugreport");
9458    }
9459
9460    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9461        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9462    }
9463
9464    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9465        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9466            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9467        }
9468        return KEY_DISPATCHING_TIMEOUT;
9469    }
9470
9471    @Override
9472    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9473        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9474                != PackageManager.PERMISSION_GRANTED) {
9475            throw new SecurityException("Requires permission "
9476                    + android.Manifest.permission.FILTER_EVENTS);
9477        }
9478        ProcessRecord proc;
9479        long timeout;
9480        synchronized (this) {
9481            synchronized (mPidsSelfLocked) {
9482                proc = mPidsSelfLocked.get(pid);
9483            }
9484            timeout = getInputDispatchingTimeoutLocked(proc);
9485        }
9486
9487        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9488            return -1;
9489        }
9490
9491        return timeout;
9492    }
9493
9494    /**
9495     * Handle input dispatching timeouts.
9496     * Returns whether input dispatching should be aborted or not.
9497     */
9498    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9499            final ActivityRecord activity, final ActivityRecord parent,
9500            final boolean aboveSystem, String reason) {
9501        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9502                != PackageManager.PERMISSION_GRANTED) {
9503            throw new SecurityException("Requires permission "
9504                    + android.Manifest.permission.FILTER_EVENTS);
9505        }
9506
9507        final String annotation;
9508        if (reason == null) {
9509            annotation = "Input dispatching timed out";
9510        } else {
9511            annotation = "Input dispatching timed out (" + reason + ")";
9512        }
9513
9514        if (proc != null) {
9515            synchronized (this) {
9516                if (proc.debugging) {
9517                    return false;
9518                }
9519
9520                if (mDidDexOpt) {
9521                    // Give more time since we were dexopting.
9522                    mDidDexOpt = false;
9523                    return false;
9524                }
9525
9526                if (proc.instrumentationClass != null) {
9527                    Bundle info = new Bundle();
9528                    info.putString("shortMsg", "keyDispatchingTimedOut");
9529                    info.putString("longMsg", annotation);
9530                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9531                    return true;
9532                }
9533            }
9534            mHandler.post(new Runnable() {
9535                @Override
9536                public void run() {
9537                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9538                }
9539            });
9540        }
9541
9542        return true;
9543    }
9544
9545    public Bundle getAssistContextExtras(int requestType) {
9546        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9547                "getAssistContextExtras()");
9548        PendingAssistExtras pae;
9549        Bundle extras = new Bundle();
9550        synchronized (this) {
9551            ActivityRecord activity = getFocusedStack().mResumedActivity;
9552            if (activity == null) {
9553                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9554                return null;
9555            }
9556            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9557            if (activity.app == null || activity.app.thread == null) {
9558                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9559                return extras;
9560            }
9561            if (activity.app.pid == Binder.getCallingPid()) {
9562                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9563                return extras;
9564            }
9565            pae = new PendingAssistExtras(activity);
9566            try {
9567                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9568                        requestType);
9569                mPendingAssistExtras.add(pae);
9570                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9571            } catch (RemoteException e) {
9572                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9573                return extras;
9574            }
9575        }
9576        synchronized (pae) {
9577            while (!pae.haveResult) {
9578                try {
9579                    pae.wait();
9580                } catch (InterruptedException e) {
9581                }
9582            }
9583            if (pae.result != null) {
9584                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9585            }
9586        }
9587        synchronized (this) {
9588            mPendingAssistExtras.remove(pae);
9589            mHandler.removeCallbacks(pae);
9590        }
9591        return extras;
9592    }
9593
9594    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9595        PendingAssistExtras pae = (PendingAssistExtras)token;
9596        synchronized (pae) {
9597            pae.result = extras;
9598            pae.haveResult = true;
9599            pae.notifyAll();
9600        }
9601    }
9602
9603    public void registerProcessObserver(IProcessObserver observer) {
9604        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9605                "registerProcessObserver()");
9606        synchronized (this) {
9607            mProcessObservers.register(observer);
9608        }
9609    }
9610
9611    @Override
9612    public void unregisterProcessObserver(IProcessObserver observer) {
9613        synchronized (this) {
9614            mProcessObservers.unregister(observer);
9615        }
9616    }
9617
9618    @Override
9619    public boolean convertFromTranslucent(IBinder token) {
9620        final long origId = Binder.clearCallingIdentity();
9621        try {
9622            synchronized (this) {
9623                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9624                if (r == null) {
9625                    return false;
9626                }
9627                if (r.changeWindowTranslucency(true)) {
9628                    mWindowManager.setAppFullscreen(token, true);
9629                    r.task.stack.releaseMediaResources();
9630                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9631                    return true;
9632                }
9633                return false;
9634            }
9635        } finally {
9636            Binder.restoreCallingIdentity(origId);
9637        }
9638    }
9639
9640    @Override
9641    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9642        final long origId = Binder.clearCallingIdentity();
9643        try {
9644            synchronized (this) {
9645                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9646                if (r == null) {
9647                    return false;
9648                }
9649                int index = r.task.mActivities.lastIndexOf(r);
9650                if (index > 0) {
9651                    ActivityRecord under = r.task.mActivities.get(index - 1);
9652                    under.returningOptions = options;
9653                }
9654                if (r.changeWindowTranslucency(false)) {
9655                    r.task.stack.convertToTranslucent(r);
9656                    mWindowManager.setAppFullscreen(token, false);
9657                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9658                    return true;
9659                } else {
9660                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9661                    return false;
9662                }
9663            }
9664        } finally {
9665            Binder.restoreCallingIdentity(origId);
9666        }
9667    }
9668
9669    @Override
9670    public boolean setMediaPlaying(IBinder token, boolean playing) {
9671        final long origId = Binder.clearCallingIdentity();
9672        try {
9673            synchronized (this) {
9674                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9675                if (r != null) {
9676                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9677                }
9678            }
9679            return false;
9680        } finally {
9681            Binder.restoreCallingIdentity(origId);
9682        }
9683    }
9684
9685    @Override
9686    public boolean isBackgroundMediaPlaying(IBinder token) {
9687        final long origId = Binder.clearCallingIdentity();
9688        try {
9689            synchronized (this) {
9690                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9691                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9692                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9693                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9694                return playing;
9695            }
9696        } finally {
9697            Binder.restoreCallingIdentity(origId);
9698        }
9699    }
9700
9701    @Override
9702    public ActivityOptions getActivityOptions(IBinder token) {
9703        final long origId = Binder.clearCallingIdentity();
9704        try {
9705            synchronized (this) {
9706                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9707                if (r != null) {
9708                    final ActivityOptions activityOptions = r.pendingOptions;
9709                    r.pendingOptions = null;
9710                    return activityOptions;
9711                }
9712                return null;
9713            }
9714        } finally {
9715            Binder.restoreCallingIdentity(origId);
9716        }
9717    }
9718
9719    @Override
9720    public void setImmersive(IBinder token, boolean immersive) {
9721        synchronized(this) {
9722            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9723            if (r == null) {
9724                throw new IllegalArgumentException();
9725            }
9726            r.immersive = immersive;
9727
9728            // update associated state if we're frontmost
9729            if (r == mFocusedActivity) {
9730                if (DEBUG_IMMERSIVE) {
9731                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9732                }
9733                applyUpdateLockStateLocked(r);
9734            }
9735        }
9736    }
9737
9738    @Override
9739    public boolean isImmersive(IBinder token) {
9740        synchronized (this) {
9741            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9742            if (r == null) {
9743                throw new IllegalArgumentException();
9744            }
9745            return r.immersive;
9746        }
9747    }
9748
9749    public boolean isTopActivityImmersive() {
9750        enforceNotIsolatedCaller("startActivity");
9751        synchronized (this) {
9752            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9753            return (r != null) ? r.immersive : false;
9754        }
9755    }
9756
9757    @Override
9758    public boolean isTopOfTask(IBinder token) {
9759        synchronized (this) {
9760            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9761            if (r == null) {
9762                throw new IllegalArgumentException();
9763            }
9764            return r.task.getTopActivity() == r;
9765        }
9766    }
9767
9768    public final void enterSafeMode() {
9769        synchronized(this) {
9770            // It only makes sense to do this before the system is ready
9771            // and started launching other packages.
9772            if (!mSystemReady) {
9773                try {
9774                    AppGlobals.getPackageManager().enterSafeMode();
9775                } catch (RemoteException e) {
9776                }
9777            }
9778
9779            mSafeMode = true;
9780        }
9781    }
9782
9783    public final void showSafeModeOverlay() {
9784        View v = LayoutInflater.from(mContext).inflate(
9785                com.android.internal.R.layout.safe_mode, null);
9786        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9787        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9788        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9789        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9790        lp.gravity = Gravity.BOTTOM | Gravity.START;
9791        lp.format = v.getBackground().getOpacity();
9792        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9793                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9794        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9795        ((WindowManager)mContext.getSystemService(
9796                Context.WINDOW_SERVICE)).addView(v, lp);
9797    }
9798
9799    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9800        if (!(sender instanceof PendingIntentRecord)) {
9801            return;
9802        }
9803        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9804        synchronized (stats) {
9805            if (mBatteryStatsService.isOnBattery()) {
9806                mBatteryStatsService.enforceCallingPermission();
9807                PendingIntentRecord rec = (PendingIntentRecord)sender;
9808                int MY_UID = Binder.getCallingUid();
9809                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9810                BatteryStatsImpl.Uid.Pkg pkg =
9811                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9812                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9813                pkg.incWakeupsLocked();
9814            }
9815        }
9816    }
9817
9818    public boolean killPids(int[] pids, String pReason, boolean secure) {
9819        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9820            throw new SecurityException("killPids only available to the system");
9821        }
9822        String reason = (pReason == null) ? "Unknown" : pReason;
9823        // XXX Note: don't acquire main activity lock here, because the window
9824        // manager calls in with its locks held.
9825
9826        boolean killed = false;
9827        synchronized (mPidsSelfLocked) {
9828            int[] types = new int[pids.length];
9829            int worstType = 0;
9830            for (int i=0; i<pids.length; i++) {
9831                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9832                if (proc != null) {
9833                    int type = proc.setAdj;
9834                    types[i] = type;
9835                    if (type > worstType) {
9836                        worstType = type;
9837                    }
9838                }
9839            }
9840
9841            // If the worst oom_adj is somewhere in the cached proc LRU range,
9842            // then constrain it so we will kill all cached procs.
9843            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9844                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9845                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9846            }
9847
9848            // If this is not a secure call, don't let it kill processes that
9849            // are important.
9850            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9851                worstType = ProcessList.SERVICE_ADJ;
9852            }
9853
9854            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9855            for (int i=0; i<pids.length; i++) {
9856                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9857                if (proc == null) {
9858                    continue;
9859                }
9860                int adj = proc.setAdj;
9861                if (adj >= worstType && !proc.killedByAm) {
9862                    killUnneededProcessLocked(proc, reason);
9863                    killed = true;
9864                }
9865            }
9866        }
9867        return killed;
9868    }
9869
9870    @Override
9871    public void killUid(int uid, String reason) {
9872        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9873            throw new SecurityException("killUid only available to the system");
9874        }
9875        synchronized (this) {
9876            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9877                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9878                    reason != null ? reason : "kill uid");
9879        }
9880    }
9881
9882    @Override
9883    public boolean killProcessesBelowForeground(String reason) {
9884        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9885            throw new SecurityException("killProcessesBelowForeground() only available to system");
9886        }
9887
9888        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9889    }
9890
9891    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9892        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9893            throw new SecurityException("killProcessesBelowAdj() only available to system");
9894        }
9895
9896        boolean killed = false;
9897        synchronized (mPidsSelfLocked) {
9898            final int size = mPidsSelfLocked.size();
9899            for (int i = 0; i < size; i++) {
9900                final int pid = mPidsSelfLocked.keyAt(i);
9901                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9902                if (proc == null) continue;
9903
9904                final int adj = proc.setAdj;
9905                if (adj > belowAdj && !proc.killedByAm) {
9906                    killUnneededProcessLocked(proc, reason);
9907                    killed = true;
9908                }
9909            }
9910        }
9911        return killed;
9912    }
9913
9914    @Override
9915    public void hang(final IBinder who, boolean allowRestart) {
9916        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9917                != PackageManager.PERMISSION_GRANTED) {
9918            throw new SecurityException("Requires permission "
9919                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9920        }
9921
9922        final IBinder.DeathRecipient death = new DeathRecipient() {
9923            @Override
9924            public void binderDied() {
9925                synchronized (this) {
9926                    notifyAll();
9927                }
9928            }
9929        };
9930
9931        try {
9932            who.linkToDeath(death, 0);
9933        } catch (RemoteException e) {
9934            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9935            return;
9936        }
9937
9938        synchronized (this) {
9939            Watchdog.getInstance().setAllowRestart(allowRestart);
9940            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9941            synchronized (death) {
9942                while (who.isBinderAlive()) {
9943                    try {
9944                        death.wait();
9945                    } catch (InterruptedException e) {
9946                    }
9947                }
9948            }
9949            Watchdog.getInstance().setAllowRestart(true);
9950        }
9951    }
9952
9953    @Override
9954    public void restart() {
9955        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9956                != PackageManager.PERMISSION_GRANTED) {
9957            throw new SecurityException("Requires permission "
9958                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9959        }
9960
9961        Log.i(TAG, "Sending shutdown broadcast...");
9962
9963        BroadcastReceiver br = new BroadcastReceiver() {
9964            @Override public void onReceive(Context context, Intent intent) {
9965                // Now the broadcast is done, finish up the low-level shutdown.
9966                Log.i(TAG, "Shutting down activity manager...");
9967                shutdown(10000);
9968                Log.i(TAG, "Shutdown complete, restarting!");
9969                Process.killProcess(Process.myPid());
9970                System.exit(10);
9971            }
9972        };
9973
9974        // First send the high-level shut down broadcast.
9975        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9976        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9977        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9978        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9979        mContext.sendOrderedBroadcastAsUser(intent,
9980                UserHandle.ALL, null, br, mHandler, 0, null, null);
9981        */
9982        br.onReceive(mContext, intent);
9983    }
9984
9985    private long getLowRamTimeSinceIdle(long now) {
9986        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9987    }
9988
9989    @Override
9990    public void performIdleMaintenance() {
9991        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9992                != PackageManager.PERMISSION_GRANTED) {
9993            throw new SecurityException("Requires permission "
9994                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9995        }
9996
9997        synchronized (this) {
9998            final long now = SystemClock.uptimeMillis();
9999            final long timeSinceLastIdle = now - mLastIdleTime;
10000            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10001            mLastIdleTime = now;
10002            mLowRamTimeSinceLastIdle = 0;
10003            if (mLowRamStartTime != 0) {
10004                mLowRamStartTime = now;
10005            }
10006
10007            StringBuilder sb = new StringBuilder(128);
10008            sb.append("Idle maintenance over ");
10009            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10010            sb.append(" low RAM for ");
10011            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10012            Slog.i(TAG, sb.toString());
10013
10014            // If at least 1/3 of our time since the last idle period has been spent
10015            // with RAM low, then we want to kill processes.
10016            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10017
10018            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10019                ProcessRecord proc = mLruProcesses.get(i);
10020                if (proc.notCachedSinceIdle) {
10021                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10022                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10023                        if (doKilling && proc.initialIdlePss != 0
10024                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10025                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
10026                                    + " from " + proc.initialIdlePss + ")");
10027                        }
10028                    }
10029                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10030                    proc.notCachedSinceIdle = true;
10031                    proc.initialIdlePss = 0;
10032                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10033                            isSleeping(), now);
10034                }
10035            }
10036
10037            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10038            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10039        }
10040    }
10041
10042    private void retrieveSettings() {
10043        final ContentResolver resolver = mContext.getContentResolver();
10044        String debugApp = Settings.Global.getString(
10045            resolver, Settings.Global.DEBUG_APP);
10046        boolean waitForDebugger = Settings.Global.getInt(
10047            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10048        boolean alwaysFinishActivities = Settings.Global.getInt(
10049            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10050        boolean forceRtl = Settings.Global.getInt(
10051                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10052        // Transfer any global setting for forcing RTL layout, into a System Property
10053        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10054
10055        Configuration configuration = new Configuration();
10056        Settings.System.getConfiguration(resolver, configuration);
10057        if (forceRtl) {
10058            // This will take care of setting the correct layout direction flags
10059            configuration.setLayoutDirection(configuration.locale);
10060        }
10061
10062        synchronized (this) {
10063            mDebugApp = mOrigDebugApp = debugApp;
10064            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10065            mAlwaysFinishActivities = alwaysFinishActivities;
10066            // This happens before any activities are started, so we can
10067            // change mConfiguration in-place.
10068            updateConfigurationLocked(configuration, null, false, true);
10069            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10070        }
10071    }
10072
10073    public boolean testIsSystemReady() {
10074        // no need to synchronize(this) just to read & return the value
10075        return mSystemReady;
10076    }
10077
10078    private static File getCalledPreBootReceiversFile() {
10079        File dataDir = Environment.getDataDirectory();
10080        File systemDir = new File(dataDir, "system");
10081        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10082        return fname;
10083    }
10084
10085    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10086        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10087        File file = getCalledPreBootReceiversFile();
10088        FileInputStream fis = null;
10089        try {
10090            fis = new FileInputStream(file);
10091            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10092            int fvers = dis.readInt();
10093            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10094                String vers = dis.readUTF();
10095                String codename = dis.readUTF();
10096                String build = dis.readUTF();
10097                if (android.os.Build.VERSION.RELEASE.equals(vers)
10098                        && android.os.Build.VERSION.CODENAME.equals(codename)
10099                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10100                    int num = dis.readInt();
10101                    while (num > 0) {
10102                        num--;
10103                        String pkg = dis.readUTF();
10104                        String cls = dis.readUTF();
10105                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10106                    }
10107                }
10108            }
10109        } catch (FileNotFoundException e) {
10110        } catch (IOException e) {
10111            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10112        } finally {
10113            if (fis != null) {
10114                try {
10115                    fis.close();
10116                } catch (IOException e) {
10117                }
10118            }
10119        }
10120        return lastDoneReceivers;
10121    }
10122
10123    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10124        File file = getCalledPreBootReceiversFile();
10125        FileOutputStream fos = null;
10126        DataOutputStream dos = null;
10127        try {
10128            fos = new FileOutputStream(file);
10129            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10130            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10131            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10132            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10133            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10134            dos.writeInt(list.size());
10135            for (int i=0; i<list.size(); i++) {
10136                dos.writeUTF(list.get(i).getPackageName());
10137                dos.writeUTF(list.get(i).getClassName());
10138            }
10139        } catch (IOException e) {
10140            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10141            file.delete();
10142        } finally {
10143            FileUtils.sync(fos);
10144            if (dos != null) {
10145                try {
10146                    dos.close();
10147                } catch (IOException e) {
10148                    // TODO Auto-generated catch block
10149                    e.printStackTrace();
10150                }
10151            }
10152        }
10153    }
10154
10155    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10156            ArrayList<ComponentName> doneReceivers, int userId) {
10157        boolean waitingUpdate = false;
10158        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10159        List<ResolveInfo> ris = null;
10160        try {
10161            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10162                    intent, null, 0, userId);
10163        } catch (RemoteException e) {
10164        }
10165        if (ris != null) {
10166            for (int i=ris.size()-1; i>=0; i--) {
10167                if ((ris.get(i).activityInfo.applicationInfo.flags
10168                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10169                    ris.remove(i);
10170                }
10171            }
10172            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10173
10174            // For User 0, load the version number. When delivering to a new user, deliver
10175            // to all receivers.
10176            if (userId == UserHandle.USER_OWNER) {
10177                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10178                for (int i=0; i<ris.size(); i++) {
10179                    ActivityInfo ai = ris.get(i).activityInfo;
10180                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10181                    if (lastDoneReceivers.contains(comp)) {
10182                        // We already did the pre boot receiver for this app with the current
10183                        // platform version, so don't do it again...
10184                        ris.remove(i);
10185                        i--;
10186                        // ...however, do keep it as one that has been done, so we don't
10187                        // forget about it when rewriting the file of last done receivers.
10188                        doneReceivers.add(comp);
10189                    }
10190                }
10191            }
10192
10193            // If primary user, send broadcast to all available users, else just to userId
10194            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10195                    : new int[] { userId };
10196            for (int i = 0; i < ris.size(); i++) {
10197                ActivityInfo ai = ris.get(i).activityInfo;
10198                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10199                doneReceivers.add(comp);
10200                intent.setComponent(comp);
10201                for (int j=0; j<users.length; j++) {
10202                    IIntentReceiver finisher = null;
10203                    // On last receiver and user, set up a completion callback
10204                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10205                        finisher = new IIntentReceiver.Stub() {
10206                            public void performReceive(Intent intent, int resultCode,
10207                                    String data, Bundle extras, boolean ordered,
10208                                    boolean sticky, int sendingUser) {
10209                                // The raw IIntentReceiver interface is called
10210                                // with the AM lock held, so redispatch to
10211                                // execute our code without the lock.
10212                                mHandler.post(onFinishCallback);
10213                            }
10214                        };
10215                    }
10216                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10217                            + " for user " + users[j]);
10218                    broadcastIntentLocked(null, null, intent, null, finisher,
10219                            0, null, null, null, AppOpsManager.OP_NONE,
10220                            true, false, MY_PID, Process.SYSTEM_UID,
10221                            users[j]);
10222                    if (finisher != null) {
10223                        waitingUpdate = true;
10224                    }
10225                }
10226            }
10227        }
10228
10229        return waitingUpdate;
10230    }
10231
10232    public void systemReady(final Runnable goingCallback) {
10233        synchronized(this) {
10234            if (mSystemReady) {
10235                // If we're done calling all the receivers, run the next "boot phase" passed in
10236                // by the SystemServer
10237                if (goingCallback != null) {
10238                    goingCallback.run();
10239                }
10240                return;
10241            }
10242
10243            // Make sure we have the current profile info, since it is needed for
10244            // security checks.
10245            updateCurrentProfileIdsLocked();
10246
10247            if (mRecentTasks == null) {
10248                mRecentTasks = mTaskPersister.restoreTasksLocked();
10249                if (!mRecentTasks.isEmpty()) {
10250                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10251                }
10252                mTaskPersister.startPersisting();
10253            }
10254
10255            // Check to see if there are any update receivers to run.
10256            if (!mDidUpdate) {
10257                if (mWaitingUpdate) {
10258                    return;
10259                }
10260                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10261                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10262                    public void run() {
10263                        synchronized (ActivityManagerService.this) {
10264                            mDidUpdate = true;
10265                        }
10266                        writeLastDonePreBootReceivers(doneReceivers);
10267                        showBootMessage(mContext.getText(
10268                                R.string.android_upgrading_complete),
10269                                false);
10270                        systemReady(goingCallback);
10271                    }
10272                }, doneReceivers, UserHandle.USER_OWNER);
10273
10274                if (mWaitingUpdate) {
10275                    return;
10276                }
10277                mDidUpdate = true;
10278            }
10279
10280            mAppOpsService.systemReady();
10281            mSystemReady = true;
10282        }
10283
10284        ArrayList<ProcessRecord> procsToKill = null;
10285        synchronized(mPidsSelfLocked) {
10286            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10287                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10288                if (!isAllowedWhileBooting(proc.info)){
10289                    if (procsToKill == null) {
10290                        procsToKill = new ArrayList<ProcessRecord>();
10291                    }
10292                    procsToKill.add(proc);
10293                }
10294            }
10295        }
10296
10297        synchronized(this) {
10298            if (procsToKill != null) {
10299                for (int i=procsToKill.size()-1; i>=0; i--) {
10300                    ProcessRecord proc = procsToKill.get(i);
10301                    Slog.i(TAG, "Removing system update proc: " + proc);
10302                    removeProcessLocked(proc, true, false, "system update done");
10303                }
10304            }
10305
10306            // Now that we have cleaned up any update processes, we
10307            // are ready to start launching real processes and know that
10308            // we won't trample on them any more.
10309            mProcessesReady = true;
10310        }
10311
10312        Slog.i(TAG, "System now ready");
10313        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10314            SystemClock.uptimeMillis());
10315
10316        synchronized(this) {
10317            // Make sure we have no pre-ready processes sitting around.
10318
10319            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10320                ResolveInfo ri = mContext.getPackageManager()
10321                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10322                                STOCK_PM_FLAGS);
10323                CharSequence errorMsg = null;
10324                if (ri != null) {
10325                    ActivityInfo ai = ri.activityInfo;
10326                    ApplicationInfo app = ai.applicationInfo;
10327                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10328                        mTopAction = Intent.ACTION_FACTORY_TEST;
10329                        mTopData = null;
10330                        mTopComponent = new ComponentName(app.packageName,
10331                                ai.name);
10332                    } else {
10333                        errorMsg = mContext.getResources().getText(
10334                                com.android.internal.R.string.factorytest_not_system);
10335                    }
10336                } else {
10337                    errorMsg = mContext.getResources().getText(
10338                            com.android.internal.R.string.factorytest_no_action);
10339                }
10340                if (errorMsg != null) {
10341                    mTopAction = null;
10342                    mTopData = null;
10343                    mTopComponent = null;
10344                    Message msg = Message.obtain();
10345                    msg.what = SHOW_FACTORY_ERROR_MSG;
10346                    msg.getData().putCharSequence("msg", errorMsg);
10347                    mHandler.sendMessage(msg);
10348                }
10349            }
10350        }
10351
10352        retrieveSettings();
10353
10354        synchronized (this) {
10355            readGrantedUriPermissionsLocked();
10356        }
10357
10358        if (goingCallback != null) goingCallback.run();
10359
10360        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10361                Integer.toString(mCurrentUserId), mCurrentUserId);
10362        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10363                Integer.toString(mCurrentUserId), mCurrentUserId);
10364        mSystemServiceManager.startUser(mCurrentUserId);
10365
10366        synchronized (this) {
10367            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10368                try {
10369                    List apps = AppGlobals.getPackageManager().
10370                        getPersistentApplications(STOCK_PM_FLAGS);
10371                    if (apps != null) {
10372                        int N = apps.size();
10373                        int i;
10374                        for (i=0; i<N; i++) {
10375                            ApplicationInfo info
10376                                = (ApplicationInfo)apps.get(i);
10377                            if (info != null &&
10378                                    !info.packageName.equals("android")) {
10379                                addAppLocked(info, false, null /* ABI override */);
10380                            }
10381                        }
10382                    }
10383                } catch (RemoteException ex) {
10384                    // pm is in same process, this will never happen.
10385                }
10386            }
10387
10388            // Start up initial activity.
10389            mBooting = true;
10390
10391            try {
10392                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10393                    Message msg = Message.obtain();
10394                    msg.what = SHOW_UID_ERROR_MSG;
10395                    mHandler.sendMessage(msg);
10396                }
10397            } catch (RemoteException e) {
10398            }
10399
10400            long ident = Binder.clearCallingIdentity();
10401            try {
10402                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10403                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10404                        | Intent.FLAG_RECEIVER_FOREGROUND);
10405                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10406                broadcastIntentLocked(null, null, intent,
10407                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10408                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10409                intent = new Intent(Intent.ACTION_USER_STARTING);
10410                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10411                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10412                broadcastIntentLocked(null, null, intent,
10413                        null, new IIntentReceiver.Stub() {
10414                            @Override
10415                            public void performReceive(Intent intent, int resultCode, String data,
10416                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10417                                    throws RemoteException {
10418                            }
10419                        }, 0, null, null,
10420                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10421                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10422            } catch (Throwable t) {
10423                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10424            } finally {
10425                Binder.restoreCallingIdentity(ident);
10426            }
10427            mStackSupervisor.resumeTopActivitiesLocked();
10428            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10429        }
10430    }
10431
10432    private boolean makeAppCrashingLocked(ProcessRecord app,
10433            String shortMsg, String longMsg, String stackTrace) {
10434        app.crashing = true;
10435        app.crashingReport = generateProcessError(app,
10436                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10437        startAppProblemLocked(app);
10438        app.stopFreezingAllLocked();
10439        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10440    }
10441
10442    private void makeAppNotRespondingLocked(ProcessRecord app,
10443            String activity, String shortMsg, String longMsg) {
10444        app.notResponding = true;
10445        app.notRespondingReport = generateProcessError(app,
10446                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10447                activity, shortMsg, longMsg, null);
10448        startAppProblemLocked(app);
10449        app.stopFreezingAllLocked();
10450    }
10451
10452    /**
10453     * Generate a process error record, suitable for attachment to a ProcessRecord.
10454     *
10455     * @param app The ProcessRecord in which the error occurred.
10456     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10457     *                      ActivityManager.AppErrorStateInfo
10458     * @param activity The activity associated with the crash, if known.
10459     * @param shortMsg Short message describing the crash.
10460     * @param longMsg Long message describing the crash.
10461     * @param stackTrace Full crash stack trace, may be null.
10462     *
10463     * @return Returns a fully-formed AppErrorStateInfo record.
10464     */
10465    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10466            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10467        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10468
10469        report.condition = condition;
10470        report.processName = app.processName;
10471        report.pid = app.pid;
10472        report.uid = app.info.uid;
10473        report.tag = activity;
10474        report.shortMsg = shortMsg;
10475        report.longMsg = longMsg;
10476        report.stackTrace = stackTrace;
10477
10478        return report;
10479    }
10480
10481    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10482        synchronized (this) {
10483            app.crashing = false;
10484            app.crashingReport = null;
10485            app.notResponding = false;
10486            app.notRespondingReport = null;
10487            if (app.anrDialog == fromDialog) {
10488                app.anrDialog = null;
10489            }
10490            if (app.waitDialog == fromDialog) {
10491                app.waitDialog = null;
10492            }
10493            if (app.pid > 0 && app.pid != MY_PID) {
10494                handleAppCrashLocked(app, null, null, null);
10495                killUnneededProcessLocked(app, "user request after error");
10496            }
10497        }
10498    }
10499
10500    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10501            String stackTrace) {
10502        long now = SystemClock.uptimeMillis();
10503
10504        Long crashTime;
10505        if (!app.isolated) {
10506            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10507        } else {
10508            crashTime = null;
10509        }
10510        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10511            // This process loses!
10512            Slog.w(TAG, "Process " + app.info.processName
10513                    + " has crashed too many times: killing!");
10514            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10515                    app.userId, app.info.processName, app.uid);
10516            mStackSupervisor.handleAppCrashLocked(app);
10517            if (!app.persistent) {
10518                // We don't want to start this process again until the user
10519                // explicitly does so...  but for persistent process, we really
10520                // need to keep it running.  If a persistent process is actually
10521                // repeatedly crashing, then badness for everyone.
10522                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10523                        app.info.processName);
10524                if (!app.isolated) {
10525                    // XXX We don't have a way to mark isolated processes
10526                    // as bad, since they don't have a peristent identity.
10527                    mBadProcesses.put(app.info.processName, app.uid,
10528                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10529                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10530                }
10531                app.bad = true;
10532                app.removed = true;
10533                // Don't let services in this process be restarted and potentially
10534                // annoy the user repeatedly.  Unless it is persistent, since those
10535                // processes run critical code.
10536                removeProcessLocked(app, false, false, "crash");
10537                mStackSupervisor.resumeTopActivitiesLocked();
10538                return false;
10539            }
10540            mStackSupervisor.resumeTopActivitiesLocked();
10541        } else {
10542            mStackSupervisor.finishTopRunningActivityLocked(app);
10543        }
10544
10545        // Bump up the crash count of any services currently running in the proc.
10546        for (int i=app.services.size()-1; i>=0; i--) {
10547            // Any services running in the application need to be placed
10548            // back in the pending list.
10549            ServiceRecord sr = app.services.valueAt(i);
10550            sr.crashCount++;
10551        }
10552
10553        // If the crashing process is what we consider to be the "home process" and it has been
10554        // replaced by a third-party app, clear the package preferred activities from packages
10555        // with a home activity running in the process to prevent a repeatedly crashing app
10556        // from blocking the user to manually clear the list.
10557        final ArrayList<ActivityRecord> activities = app.activities;
10558        if (app == mHomeProcess && activities.size() > 0
10559                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10560            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10561                final ActivityRecord r = activities.get(activityNdx);
10562                if (r.isHomeActivity()) {
10563                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10564                    try {
10565                        ActivityThread.getPackageManager()
10566                                .clearPackagePreferredActivities(r.packageName);
10567                    } catch (RemoteException c) {
10568                        // pm is in same process, this will never happen.
10569                    }
10570                }
10571            }
10572        }
10573
10574        if (!app.isolated) {
10575            // XXX Can't keep track of crash times for isolated processes,
10576            // because they don't have a perisistent identity.
10577            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10578        }
10579
10580        if (app.crashHandler != null) mHandler.post(app.crashHandler);
10581        return true;
10582    }
10583
10584    void startAppProblemLocked(ProcessRecord app) {
10585        if (app.userId == mCurrentUserId) {
10586            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10587                    mContext, app.info.packageName, app.info.flags);
10588        } else {
10589            // If this app is not running under the current user, then we
10590            // can't give it a report button because that would require
10591            // launching the report UI under a different user.
10592            app.errorReportReceiver = null;
10593        }
10594        skipCurrentReceiverLocked(app);
10595    }
10596
10597    void skipCurrentReceiverLocked(ProcessRecord app) {
10598        for (BroadcastQueue queue : mBroadcastQueues) {
10599            queue.skipCurrentReceiverLocked(app);
10600        }
10601    }
10602
10603    /**
10604     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10605     * The application process will exit immediately after this call returns.
10606     * @param app object of the crashing app, null for the system server
10607     * @param crashInfo describing the exception
10608     */
10609    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10610        ProcessRecord r = findAppProcess(app, "Crash");
10611        final String processName = app == null ? "system_server"
10612                : (r == null ? "unknown" : r.processName);
10613
10614        handleApplicationCrashInner("crash", r, processName, crashInfo);
10615    }
10616
10617    /* Native crash reporting uses this inner version because it needs to be somewhat
10618     * decoupled from the AM-managed cleanup lifecycle
10619     */
10620    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10621            ApplicationErrorReport.CrashInfo crashInfo) {
10622        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10623                UserHandle.getUserId(Binder.getCallingUid()), processName,
10624                r == null ? -1 : r.info.flags,
10625                crashInfo.exceptionClassName,
10626                crashInfo.exceptionMessage,
10627                crashInfo.throwFileName,
10628                crashInfo.throwLineNumber);
10629
10630        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10631
10632        crashApplication(r, crashInfo);
10633    }
10634
10635    public void handleApplicationStrictModeViolation(
10636            IBinder app,
10637            int violationMask,
10638            StrictMode.ViolationInfo info) {
10639        ProcessRecord r = findAppProcess(app, "StrictMode");
10640        if (r == null) {
10641            return;
10642        }
10643
10644        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10645            Integer stackFingerprint = info.hashCode();
10646            boolean logIt = true;
10647            synchronized (mAlreadyLoggedViolatedStacks) {
10648                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10649                    logIt = false;
10650                    // TODO: sub-sample into EventLog for these, with
10651                    // the info.durationMillis?  Then we'd get
10652                    // the relative pain numbers, without logging all
10653                    // the stack traces repeatedly.  We'd want to do
10654                    // likewise in the client code, which also does
10655                    // dup suppression, before the Binder call.
10656                } else {
10657                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10658                        mAlreadyLoggedViolatedStacks.clear();
10659                    }
10660                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10661                }
10662            }
10663            if (logIt) {
10664                logStrictModeViolationToDropBox(r, info);
10665            }
10666        }
10667
10668        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10669            AppErrorResult result = new AppErrorResult();
10670            synchronized (this) {
10671                final long origId = Binder.clearCallingIdentity();
10672
10673                Message msg = Message.obtain();
10674                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10675                HashMap<String, Object> data = new HashMap<String, Object>();
10676                data.put("result", result);
10677                data.put("app", r);
10678                data.put("violationMask", violationMask);
10679                data.put("info", info);
10680                msg.obj = data;
10681                mHandler.sendMessage(msg);
10682
10683                Binder.restoreCallingIdentity(origId);
10684            }
10685            int res = result.get();
10686            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10687        }
10688    }
10689
10690    // Depending on the policy in effect, there could be a bunch of
10691    // these in quick succession so we try to batch these together to
10692    // minimize disk writes, number of dropbox entries, and maximize
10693    // compression, by having more fewer, larger records.
10694    private void logStrictModeViolationToDropBox(
10695            ProcessRecord process,
10696            StrictMode.ViolationInfo info) {
10697        if (info == null) {
10698            return;
10699        }
10700        final boolean isSystemApp = process == null ||
10701                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10702                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10703        final String processName = process == null ? "unknown" : process.processName;
10704        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10705        final DropBoxManager dbox = (DropBoxManager)
10706                mContext.getSystemService(Context.DROPBOX_SERVICE);
10707
10708        // Exit early if the dropbox isn't configured to accept this report type.
10709        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10710
10711        boolean bufferWasEmpty;
10712        boolean needsFlush;
10713        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10714        synchronized (sb) {
10715            bufferWasEmpty = sb.length() == 0;
10716            appendDropBoxProcessHeaders(process, processName, sb);
10717            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10718            sb.append("System-App: ").append(isSystemApp).append("\n");
10719            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10720            if (info.violationNumThisLoop != 0) {
10721                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10722            }
10723            if (info.numAnimationsRunning != 0) {
10724                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10725            }
10726            if (info.broadcastIntentAction != null) {
10727                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10728            }
10729            if (info.durationMillis != -1) {
10730                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10731            }
10732            if (info.numInstances != -1) {
10733                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10734            }
10735            if (info.tags != null) {
10736                for (String tag : info.tags) {
10737                    sb.append("Span-Tag: ").append(tag).append("\n");
10738                }
10739            }
10740            sb.append("\n");
10741            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10742                sb.append(info.crashInfo.stackTrace);
10743            }
10744            sb.append("\n");
10745
10746            // Only buffer up to ~64k.  Various logging bits truncate
10747            // things at 128k.
10748            needsFlush = (sb.length() > 64 * 1024);
10749        }
10750
10751        // Flush immediately if the buffer's grown too large, or this
10752        // is a non-system app.  Non-system apps are isolated with a
10753        // different tag & policy and not batched.
10754        //
10755        // Batching is useful during internal testing with
10756        // StrictMode settings turned up high.  Without batching,
10757        // thousands of separate files could be created on boot.
10758        if (!isSystemApp || needsFlush) {
10759            new Thread("Error dump: " + dropboxTag) {
10760                @Override
10761                public void run() {
10762                    String report;
10763                    synchronized (sb) {
10764                        report = sb.toString();
10765                        sb.delete(0, sb.length());
10766                        sb.trimToSize();
10767                    }
10768                    if (report.length() != 0) {
10769                        dbox.addText(dropboxTag, report);
10770                    }
10771                }
10772            }.start();
10773            return;
10774        }
10775
10776        // System app batching:
10777        if (!bufferWasEmpty) {
10778            // An existing dropbox-writing thread is outstanding, so
10779            // we don't need to start it up.  The existing thread will
10780            // catch the buffer appends we just did.
10781            return;
10782        }
10783
10784        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10785        // (After this point, we shouldn't access AMS internal data structures.)
10786        new Thread("Error dump: " + dropboxTag) {
10787            @Override
10788            public void run() {
10789                // 5 second sleep to let stacks arrive and be batched together
10790                try {
10791                    Thread.sleep(5000);  // 5 seconds
10792                } catch (InterruptedException e) {}
10793
10794                String errorReport;
10795                synchronized (mStrictModeBuffer) {
10796                    errorReport = mStrictModeBuffer.toString();
10797                    if (errorReport.length() == 0) {
10798                        return;
10799                    }
10800                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10801                    mStrictModeBuffer.trimToSize();
10802                }
10803                dbox.addText(dropboxTag, errorReport);
10804            }
10805        }.start();
10806    }
10807
10808    /**
10809     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10810     * @param app object of the crashing app, null for the system server
10811     * @param tag reported by the caller
10812     * @param crashInfo describing the context of the error
10813     * @return true if the process should exit immediately (WTF is fatal)
10814     */
10815    public boolean handleApplicationWtf(IBinder app, String tag,
10816            ApplicationErrorReport.CrashInfo crashInfo) {
10817        ProcessRecord r = findAppProcess(app, "WTF");
10818        final String processName = app == null ? "system_server"
10819                : (r == null ? "unknown" : r.processName);
10820
10821        EventLog.writeEvent(EventLogTags.AM_WTF,
10822                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10823                processName,
10824                r == null ? -1 : r.info.flags,
10825                tag, crashInfo.exceptionMessage);
10826
10827        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10828
10829        if (r != null && r.pid != Process.myPid() &&
10830                Settings.Global.getInt(mContext.getContentResolver(),
10831                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10832            crashApplication(r, crashInfo);
10833            return true;
10834        } else {
10835            return false;
10836        }
10837    }
10838
10839    /**
10840     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10841     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10842     */
10843    private ProcessRecord findAppProcess(IBinder app, String reason) {
10844        if (app == null) {
10845            return null;
10846        }
10847
10848        synchronized (this) {
10849            final int NP = mProcessNames.getMap().size();
10850            for (int ip=0; ip<NP; ip++) {
10851                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10852                final int NA = apps.size();
10853                for (int ia=0; ia<NA; ia++) {
10854                    ProcessRecord p = apps.valueAt(ia);
10855                    if (p.thread != null && p.thread.asBinder() == app) {
10856                        return p;
10857                    }
10858                }
10859            }
10860
10861            Slog.w(TAG, "Can't find mystery application for " + reason
10862                    + " from pid=" + Binder.getCallingPid()
10863                    + " uid=" + Binder.getCallingUid() + ": " + app);
10864            return null;
10865        }
10866    }
10867
10868    /**
10869     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10870     * to append various headers to the dropbox log text.
10871     */
10872    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10873            StringBuilder sb) {
10874        // Watchdog thread ends up invoking this function (with
10875        // a null ProcessRecord) to add the stack file to dropbox.
10876        // Do not acquire a lock on this (am) in such cases, as it
10877        // could cause a potential deadlock, if and when watchdog
10878        // is invoked due to unavailability of lock on am and it
10879        // would prevent watchdog from killing system_server.
10880        if (process == null) {
10881            sb.append("Process: ").append(processName).append("\n");
10882            return;
10883        }
10884        // Note: ProcessRecord 'process' is guarded by the service
10885        // instance.  (notably process.pkgList, which could otherwise change
10886        // concurrently during execution of this method)
10887        synchronized (this) {
10888            sb.append("Process: ").append(processName).append("\n");
10889            int flags = process.info.flags;
10890            IPackageManager pm = AppGlobals.getPackageManager();
10891            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10892            for (int ip=0; ip<process.pkgList.size(); ip++) {
10893                String pkg = process.pkgList.keyAt(ip);
10894                sb.append("Package: ").append(pkg);
10895                try {
10896                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10897                    if (pi != null) {
10898                        sb.append(" v").append(pi.versionCode);
10899                        if (pi.versionName != null) {
10900                            sb.append(" (").append(pi.versionName).append(")");
10901                        }
10902                    }
10903                } catch (RemoteException e) {
10904                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10905                }
10906                sb.append("\n");
10907            }
10908        }
10909    }
10910
10911    private static String processClass(ProcessRecord process) {
10912        if (process == null || process.pid == MY_PID) {
10913            return "system_server";
10914        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10915            return "system_app";
10916        } else {
10917            return "data_app";
10918        }
10919    }
10920
10921    /**
10922     * Write a description of an error (crash, WTF, ANR) to the drop box.
10923     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10924     * @param process which caused the error, null means the system server
10925     * @param activity which triggered the error, null if unknown
10926     * @param parent activity related to the error, null if unknown
10927     * @param subject line related to the error, null if absent
10928     * @param report in long form describing the error, null if absent
10929     * @param logFile to include in the report, null if none
10930     * @param crashInfo giving an application stack trace, null if absent
10931     */
10932    public void addErrorToDropBox(String eventType,
10933            ProcessRecord process, String processName, ActivityRecord activity,
10934            ActivityRecord parent, String subject,
10935            final String report, final File logFile,
10936            final ApplicationErrorReport.CrashInfo crashInfo) {
10937        // NOTE -- this must never acquire the ActivityManagerService lock,
10938        // otherwise the watchdog may be prevented from resetting the system.
10939
10940        final String dropboxTag = processClass(process) + "_" + eventType;
10941        final DropBoxManager dbox = (DropBoxManager)
10942                mContext.getSystemService(Context.DROPBOX_SERVICE);
10943
10944        // Exit early if the dropbox isn't configured to accept this report type.
10945        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10946
10947        final StringBuilder sb = new StringBuilder(1024);
10948        appendDropBoxProcessHeaders(process, processName, sb);
10949        if (activity != null) {
10950            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10951        }
10952        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10953            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10954        }
10955        if (parent != null && parent != activity) {
10956            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10957        }
10958        if (subject != null) {
10959            sb.append("Subject: ").append(subject).append("\n");
10960        }
10961        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10962        if (Debug.isDebuggerConnected()) {
10963            sb.append("Debugger: Connected\n");
10964        }
10965        sb.append("\n");
10966
10967        // Do the rest in a worker thread to avoid blocking the caller on I/O
10968        // (After this point, we shouldn't access AMS internal data structures.)
10969        Thread worker = new Thread("Error dump: " + dropboxTag) {
10970            @Override
10971            public void run() {
10972                if (report != null) {
10973                    sb.append(report);
10974                }
10975                if (logFile != null) {
10976                    try {
10977                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10978                                    "\n\n[[TRUNCATED]]"));
10979                    } catch (IOException e) {
10980                        Slog.e(TAG, "Error reading " + logFile, e);
10981                    }
10982                }
10983                if (crashInfo != null && crashInfo.stackTrace != null) {
10984                    sb.append(crashInfo.stackTrace);
10985                }
10986
10987                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10988                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10989                if (lines > 0) {
10990                    sb.append("\n");
10991
10992                    // Merge several logcat streams, and take the last N lines
10993                    InputStreamReader input = null;
10994                    try {
10995                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10996                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10997                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10998
10999                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11000                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11001                        input = new InputStreamReader(logcat.getInputStream());
11002
11003                        int num;
11004                        char[] buf = new char[8192];
11005                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11006                    } catch (IOException e) {
11007                        Slog.e(TAG, "Error running logcat", e);
11008                    } finally {
11009                        if (input != null) try { input.close(); } catch (IOException e) {}
11010                    }
11011                }
11012
11013                dbox.addText(dropboxTag, sb.toString());
11014            }
11015        };
11016
11017        if (process == null) {
11018            // If process is null, we are being called from some internal code
11019            // and may be about to die -- run this synchronously.
11020            worker.run();
11021        } else {
11022            worker.start();
11023        }
11024    }
11025
11026    /**
11027     * Bring up the "unexpected error" dialog box for a crashing app.
11028     * Deal with edge cases (intercepts from instrumented applications,
11029     * ActivityController, error intent receivers, that sort of thing).
11030     * @param r the application crashing
11031     * @param crashInfo describing the failure
11032     */
11033    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11034        long timeMillis = System.currentTimeMillis();
11035        String shortMsg = crashInfo.exceptionClassName;
11036        String longMsg = crashInfo.exceptionMessage;
11037        String stackTrace = crashInfo.stackTrace;
11038        if (shortMsg != null && longMsg != null) {
11039            longMsg = shortMsg + ": " + longMsg;
11040        } else if (shortMsg != null) {
11041            longMsg = shortMsg;
11042        }
11043
11044        AppErrorResult result = new AppErrorResult();
11045        synchronized (this) {
11046            if (mController != null) {
11047                try {
11048                    String name = r != null ? r.processName : null;
11049                    int pid = r != null ? r.pid : Binder.getCallingPid();
11050                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11051                    if (!mController.appCrashed(name, pid,
11052                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11053                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11054                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11055                            Slog.w(TAG, "Skip killing native crashed app " + name
11056                                    + "(" + pid + ") during testing");
11057                        } else {
11058                            Slog.w(TAG, "Force-killing crashed app " + name
11059                                    + " at watcher's request");
11060                            Process.killProcess(pid);
11061                            if (r != null) {
11062                                Process.killProcessGroup(uid, pid);
11063                            }
11064                        }
11065                        return;
11066                    }
11067                } catch (RemoteException e) {
11068                    mController = null;
11069                    Watchdog.getInstance().setActivityController(null);
11070                }
11071            }
11072
11073            final long origId = Binder.clearCallingIdentity();
11074
11075            // If this process is running instrumentation, finish it.
11076            if (r != null && r.instrumentationClass != null) {
11077                Slog.w(TAG, "Error in app " + r.processName
11078                      + " running instrumentation " + r.instrumentationClass + ":");
11079                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11080                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11081                Bundle info = new Bundle();
11082                info.putString("shortMsg", shortMsg);
11083                info.putString("longMsg", longMsg);
11084                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11085                Binder.restoreCallingIdentity(origId);
11086                return;
11087            }
11088
11089            // If we can't identify the process or it's already exceeded its crash quota,
11090            // quit right away without showing a crash dialog.
11091            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11092                Binder.restoreCallingIdentity(origId);
11093                return;
11094            }
11095
11096            Message msg = Message.obtain();
11097            msg.what = SHOW_ERROR_MSG;
11098            HashMap data = new HashMap();
11099            data.put("result", result);
11100            data.put("app", r);
11101            msg.obj = data;
11102            mHandler.sendMessage(msg);
11103
11104            Binder.restoreCallingIdentity(origId);
11105        }
11106
11107        int res = result.get();
11108
11109        Intent appErrorIntent = null;
11110        synchronized (this) {
11111            if (r != null && !r.isolated) {
11112                // XXX Can't keep track of crash time for isolated processes,
11113                // since they don't have a persistent identity.
11114                mProcessCrashTimes.put(r.info.processName, r.uid,
11115                        SystemClock.uptimeMillis());
11116            }
11117            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11118                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11119            }
11120        }
11121
11122        if (appErrorIntent != null) {
11123            try {
11124                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11125            } catch (ActivityNotFoundException e) {
11126                Slog.w(TAG, "bug report receiver dissappeared", e);
11127            }
11128        }
11129    }
11130
11131    Intent createAppErrorIntentLocked(ProcessRecord r,
11132            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11133        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11134        if (report == null) {
11135            return null;
11136        }
11137        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11138        result.setComponent(r.errorReportReceiver);
11139        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11140        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11141        return result;
11142    }
11143
11144    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11145            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11146        if (r.errorReportReceiver == null) {
11147            return null;
11148        }
11149
11150        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11151            return null;
11152        }
11153
11154        ApplicationErrorReport report = new ApplicationErrorReport();
11155        report.packageName = r.info.packageName;
11156        report.installerPackageName = r.errorReportReceiver.getPackageName();
11157        report.processName = r.processName;
11158        report.time = timeMillis;
11159        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11160
11161        if (r.crashing || r.forceCrashReport) {
11162            report.type = ApplicationErrorReport.TYPE_CRASH;
11163            report.crashInfo = crashInfo;
11164        } else if (r.notResponding) {
11165            report.type = ApplicationErrorReport.TYPE_ANR;
11166            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11167
11168            report.anrInfo.activity = r.notRespondingReport.tag;
11169            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11170            report.anrInfo.info = r.notRespondingReport.longMsg;
11171        }
11172
11173        return report;
11174    }
11175
11176    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11177        enforceNotIsolatedCaller("getProcessesInErrorState");
11178        // assume our apps are happy - lazy create the list
11179        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11180
11181        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11182                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11183        int userId = UserHandle.getUserId(Binder.getCallingUid());
11184
11185        synchronized (this) {
11186
11187            // iterate across all processes
11188            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11189                ProcessRecord app = mLruProcesses.get(i);
11190                if (!allUsers && app.userId != userId) {
11191                    continue;
11192                }
11193                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11194                    // This one's in trouble, so we'll generate a report for it
11195                    // crashes are higher priority (in case there's a crash *and* an anr)
11196                    ActivityManager.ProcessErrorStateInfo report = null;
11197                    if (app.crashing) {
11198                        report = app.crashingReport;
11199                    } else if (app.notResponding) {
11200                        report = app.notRespondingReport;
11201                    }
11202
11203                    if (report != null) {
11204                        if (errList == null) {
11205                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11206                        }
11207                        errList.add(report);
11208                    } else {
11209                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11210                                " crashing = " + app.crashing +
11211                                " notResponding = " + app.notResponding);
11212                    }
11213                }
11214            }
11215        }
11216
11217        return errList;
11218    }
11219
11220    static int procStateToImportance(int procState, int memAdj,
11221            ActivityManager.RunningAppProcessInfo currApp) {
11222        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11223        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11224            currApp.lru = memAdj;
11225        } else {
11226            currApp.lru = 0;
11227        }
11228        return imp;
11229    }
11230
11231    private void fillInProcMemInfo(ProcessRecord app,
11232            ActivityManager.RunningAppProcessInfo outInfo) {
11233        outInfo.pid = app.pid;
11234        outInfo.uid = app.info.uid;
11235        if (mHeavyWeightProcess == app) {
11236            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11237        }
11238        if (app.persistent) {
11239            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11240        }
11241        if (app.activities.size() > 0) {
11242            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11243        }
11244        outInfo.lastTrimLevel = app.trimMemoryLevel;
11245        int adj = app.curAdj;
11246        int procState = app.curProcState;
11247        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11248        outInfo.importanceReasonCode = app.adjTypeCode;
11249        outInfo.processState = app.curProcState;
11250    }
11251
11252    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11253        enforceNotIsolatedCaller("getRunningAppProcesses");
11254        // Lazy instantiation of list
11255        List<ActivityManager.RunningAppProcessInfo> runList = null;
11256        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11257                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11258        int userId = UserHandle.getUserId(Binder.getCallingUid());
11259        synchronized (this) {
11260            // Iterate across all processes
11261            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11262                ProcessRecord app = mLruProcesses.get(i);
11263                if (!allUsers && app.userId != userId) {
11264                    continue;
11265                }
11266                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11267                    // Generate process state info for running application
11268                    ActivityManager.RunningAppProcessInfo currApp =
11269                        new ActivityManager.RunningAppProcessInfo(app.processName,
11270                                app.pid, app.getPackageList());
11271                    fillInProcMemInfo(app, currApp);
11272                    if (app.adjSource instanceof ProcessRecord) {
11273                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11274                        currApp.importanceReasonImportance =
11275                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11276                                        app.adjSourceProcState);
11277                    } else if (app.adjSource instanceof ActivityRecord) {
11278                        ActivityRecord r = (ActivityRecord)app.adjSource;
11279                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11280                    }
11281                    if (app.adjTarget instanceof ComponentName) {
11282                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11283                    }
11284                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11285                    //        + " lru=" + currApp.lru);
11286                    if (runList == null) {
11287                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11288                    }
11289                    runList.add(currApp);
11290                }
11291            }
11292        }
11293        return runList;
11294    }
11295
11296    public List<ApplicationInfo> getRunningExternalApplications() {
11297        enforceNotIsolatedCaller("getRunningExternalApplications");
11298        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11299        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11300        if (runningApps != null && runningApps.size() > 0) {
11301            Set<String> extList = new HashSet<String>();
11302            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11303                if (app.pkgList != null) {
11304                    for (String pkg : app.pkgList) {
11305                        extList.add(pkg);
11306                    }
11307                }
11308            }
11309            IPackageManager pm = AppGlobals.getPackageManager();
11310            for (String pkg : extList) {
11311                try {
11312                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11313                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11314                        retList.add(info);
11315                    }
11316                } catch (RemoteException e) {
11317                }
11318            }
11319        }
11320        return retList;
11321    }
11322
11323    @Override
11324    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11325        enforceNotIsolatedCaller("getMyMemoryState");
11326        synchronized (this) {
11327            ProcessRecord proc;
11328            synchronized (mPidsSelfLocked) {
11329                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11330            }
11331            fillInProcMemInfo(proc, outInfo);
11332        }
11333    }
11334
11335    @Override
11336    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11337        if (checkCallingPermission(android.Manifest.permission.DUMP)
11338                != PackageManager.PERMISSION_GRANTED) {
11339            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11340                    + Binder.getCallingPid()
11341                    + ", uid=" + Binder.getCallingUid()
11342                    + " without permission "
11343                    + android.Manifest.permission.DUMP);
11344            return;
11345        }
11346
11347        boolean dumpAll = false;
11348        boolean dumpClient = false;
11349        String dumpPackage = null;
11350
11351        int opti = 0;
11352        while (opti < args.length) {
11353            String opt = args[opti];
11354            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11355                break;
11356            }
11357            opti++;
11358            if ("-a".equals(opt)) {
11359                dumpAll = true;
11360            } else if ("-c".equals(opt)) {
11361                dumpClient = true;
11362            } else if ("-h".equals(opt)) {
11363                pw.println("Activity manager dump options:");
11364                pw.println("  [-a] [-c] [-h] [cmd] ...");
11365                pw.println("  cmd may be one of:");
11366                pw.println("    a[ctivities]: activity stack state");
11367                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11368                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11369                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11370                pw.println("    o[om]: out of memory management");
11371                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11372                pw.println("    provider [COMP_SPEC]: provider client-side state");
11373                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11374                pw.println("    service [COMP_SPEC]: service client-side state");
11375                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11376                pw.println("    all: dump all activities");
11377                pw.println("    top: dump the top activity");
11378                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11379                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11380                pw.println("    a partial substring in a component name, a");
11381                pw.println("    hex object identifier.");
11382                pw.println("  -a: include all available server state.");
11383                pw.println("  -c: include client state.");
11384                return;
11385            } else {
11386                pw.println("Unknown argument: " + opt + "; use -h for help");
11387            }
11388        }
11389
11390        long origId = Binder.clearCallingIdentity();
11391        boolean more = false;
11392        // Is the caller requesting to dump a particular piece of data?
11393        if (opti < args.length) {
11394            String cmd = args[opti];
11395            opti++;
11396            if ("activities".equals(cmd) || "a".equals(cmd)) {
11397                synchronized (this) {
11398                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11399                }
11400            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11401                String[] newArgs;
11402                String name;
11403                if (opti >= args.length) {
11404                    name = null;
11405                    newArgs = EMPTY_STRING_ARRAY;
11406                } else {
11407                    name = args[opti];
11408                    opti++;
11409                    newArgs = new String[args.length - opti];
11410                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11411                            args.length - opti);
11412                }
11413                synchronized (this) {
11414                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11415                }
11416            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11417                String[] newArgs;
11418                String name;
11419                if (opti >= args.length) {
11420                    name = null;
11421                    newArgs = EMPTY_STRING_ARRAY;
11422                } else {
11423                    name = args[opti];
11424                    opti++;
11425                    newArgs = new String[args.length - opti];
11426                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11427                            args.length - opti);
11428                }
11429                synchronized (this) {
11430                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11431                }
11432            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11433                String[] newArgs;
11434                String name;
11435                if (opti >= args.length) {
11436                    name = null;
11437                    newArgs = EMPTY_STRING_ARRAY;
11438                } else {
11439                    name = args[opti];
11440                    opti++;
11441                    newArgs = new String[args.length - opti];
11442                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11443                            args.length - opti);
11444                }
11445                synchronized (this) {
11446                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11447                }
11448            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11449                synchronized (this) {
11450                    dumpOomLocked(fd, pw, args, opti, true);
11451                }
11452            } else if ("provider".equals(cmd)) {
11453                String[] newArgs;
11454                String name;
11455                if (opti >= args.length) {
11456                    name = null;
11457                    newArgs = EMPTY_STRING_ARRAY;
11458                } else {
11459                    name = args[opti];
11460                    opti++;
11461                    newArgs = new String[args.length - opti];
11462                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11463                }
11464                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11465                    pw.println("No providers match: " + name);
11466                    pw.println("Use -h for help.");
11467                }
11468            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11469                synchronized (this) {
11470                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11471                }
11472            } else if ("service".equals(cmd)) {
11473                String[] newArgs;
11474                String name;
11475                if (opti >= args.length) {
11476                    name = null;
11477                    newArgs = EMPTY_STRING_ARRAY;
11478                } else {
11479                    name = args[opti];
11480                    opti++;
11481                    newArgs = new String[args.length - opti];
11482                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11483                            args.length - opti);
11484                }
11485                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11486                    pw.println("No services match: " + name);
11487                    pw.println("Use -h for help.");
11488                }
11489            } else if ("package".equals(cmd)) {
11490                String[] newArgs;
11491                if (opti >= args.length) {
11492                    pw.println("package: no package name specified");
11493                    pw.println("Use -h for help.");
11494                } else {
11495                    dumpPackage = args[opti];
11496                    opti++;
11497                    newArgs = new String[args.length - opti];
11498                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11499                            args.length - opti);
11500                    args = newArgs;
11501                    opti = 0;
11502                    more = true;
11503                }
11504            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11505                synchronized (this) {
11506                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11507                }
11508            } else {
11509                // Dumping a single activity?
11510                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11511                    pw.println("Bad activity command, or no activities match: " + cmd);
11512                    pw.println("Use -h for help.");
11513                }
11514            }
11515            if (!more) {
11516                Binder.restoreCallingIdentity(origId);
11517                return;
11518            }
11519        }
11520
11521        // No piece of data specified, dump everything.
11522        synchronized (this) {
11523            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11524            pw.println();
11525            if (dumpAll) {
11526                pw.println("-------------------------------------------------------------------------------");
11527            }
11528            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11529            pw.println();
11530            if (dumpAll) {
11531                pw.println("-------------------------------------------------------------------------------");
11532            }
11533            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11534            pw.println();
11535            if (dumpAll) {
11536                pw.println("-------------------------------------------------------------------------------");
11537            }
11538            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11539            pw.println();
11540            if (dumpAll) {
11541                pw.println("-------------------------------------------------------------------------------");
11542            }
11543            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11544            pw.println();
11545            if (dumpAll) {
11546                pw.println("-------------------------------------------------------------------------------");
11547            }
11548            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11549        }
11550        Binder.restoreCallingIdentity(origId);
11551    }
11552
11553    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11554            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11555        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11556
11557        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11558                dumpPackage);
11559        boolean needSep = printedAnything;
11560
11561        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11562                dumpPackage, needSep, "  mFocusedActivity: ");
11563        if (printed) {
11564            printedAnything = true;
11565            needSep = false;
11566        }
11567
11568        if (dumpPackage == null) {
11569            if (needSep) {
11570                pw.println();
11571            }
11572            needSep = true;
11573            printedAnything = true;
11574            mStackSupervisor.dump(pw, "  ");
11575        }
11576
11577        if (mRecentTasks.size() > 0) {
11578            boolean printedHeader = false;
11579
11580            final int N = mRecentTasks.size();
11581            for (int i=0; i<N; i++) {
11582                TaskRecord tr = mRecentTasks.get(i);
11583                if (dumpPackage != null) {
11584                    if (tr.realActivity == null ||
11585                            !dumpPackage.equals(tr.realActivity)) {
11586                        continue;
11587                    }
11588                }
11589                if (!printedHeader) {
11590                    if (needSep) {
11591                        pw.println();
11592                    }
11593                    pw.println("  Recent tasks:");
11594                    printedHeader = true;
11595                    printedAnything = true;
11596                }
11597                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11598                        pw.println(tr);
11599                if (dumpAll) {
11600                    mRecentTasks.get(i).dump(pw, "    ");
11601                }
11602            }
11603        }
11604
11605        if (!printedAnything) {
11606            pw.println("  (nothing)");
11607        }
11608    }
11609
11610    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11611            int opti, boolean dumpAll, String dumpPackage) {
11612        boolean needSep = false;
11613        boolean printedAnything = false;
11614        int numPers = 0;
11615
11616        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11617
11618        if (dumpAll) {
11619            final int NP = mProcessNames.getMap().size();
11620            for (int ip=0; ip<NP; ip++) {
11621                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11622                final int NA = procs.size();
11623                for (int ia=0; ia<NA; ia++) {
11624                    ProcessRecord r = procs.valueAt(ia);
11625                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11626                        continue;
11627                    }
11628                    if (!needSep) {
11629                        pw.println("  All known processes:");
11630                        needSep = true;
11631                        printedAnything = true;
11632                    }
11633                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11634                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11635                        pw.print(" "); pw.println(r);
11636                    r.dump(pw, "    ");
11637                    if (r.persistent) {
11638                        numPers++;
11639                    }
11640                }
11641            }
11642        }
11643
11644        if (mIsolatedProcesses.size() > 0) {
11645            boolean printed = false;
11646            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11647                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11648                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11649                    continue;
11650                }
11651                if (!printed) {
11652                    if (needSep) {
11653                        pw.println();
11654                    }
11655                    pw.println("  Isolated process list (sorted by uid):");
11656                    printedAnything = true;
11657                    printed = true;
11658                    needSep = true;
11659                }
11660                pw.println(String.format("%sIsolated #%2d: %s",
11661                        "    ", i, r.toString()));
11662            }
11663        }
11664
11665        if (mLruProcesses.size() > 0) {
11666            if (needSep) {
11667                pw.println();
11668            }
11669            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11670                    pw.print(" total, non-act at ");
11671                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11672                    pw.print(", non-svc at ");
11673                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11674                    pw.println("):");
11675            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11676            needSep = true;
11677            printedAnything = true;
11678        }
11679
11680        if (dumpAll || dumpPackage != null) {
11681            synchronized (mPidsSelfLocked) {
11682                boolean printed = false;
11683                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11684                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11685                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11686                        continue;
11687                    }
11688                    if (!printed) {
11689                        if (needSep) pw.println();
11690                        needSep = true;
11691                        pw.println("  PID mappings:");
11692                        printed = true;
11693                        printedAnything = true;
11694                    }
11695                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11696                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11697                }
11698            }
11699        }
11700
11701        if (mForegroundProcesses.size() > 0) {
11702            synchronized (mPidsSelfLocked) {
11703                boolean printed = false;
11704                for (int i=0; i<mForegroundProcesses.size(); i++) {
11705                    ProcessRecord r = mPidsSelfLocked.get(
11706                            mForegroundProcesses.valueAt(i).pid);
11707                    if (dumpPackage != null && (r == null
11708                            || !r.pkgList.containsKey(dumpPackage))) {
11709                        continue;
11710                    }
11711                    if (!printed) {
11712                        if (needSep) pw.println();
11713                        needSep = true;
11714                        pw.println("  Foreground Processes:");
11715                        printed = true;
11716                        printedAnything = true;
11717                    }
11718                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11719                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11720                }
11721            }
11722        }
11723
11724        if (mPersistentStartingProcesses.size() > 0) {
11725            if (needSep) pw.println();
11726            needSep = true;
11727            printedAnything = true;
11728            pw.println("  Persisent processes that are starting:");
11729            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11730                    "Starting Norm", "Restarting PERS", dumpPackage);
11731        }
11732
11733        if (mRemovedProcesses.size() > 0) {
11734            if (needSep) pw.println();
11735            needSep = true;
11736            printedAnything = true;
11737            pw.println("  Processes that are being removed:");
11738            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11739                    "Removed Norm", "Removed PERS", dumpPackage);
11740        }
11741
11742        if (mProcessesOnHold.size() > 0) {
11743            if (needSep) pw.println();
11744            needSep = true;
11745            printedAnything = true;
11746            pw.println("  Processes that are on old until the system is ready:");
11747            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11748                    "OnHold Norm", "OnHold PERS", dumpPackage);
11749        }
11750
11751        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11752
11753        if (mProcessCrashTimes.getMap().size() > 0) {
11754            boolean printed = false;
11755            long now = SystemClock.uptimeMillis();
11756            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11757            final int NP = pmap.size();
11758            for (int ip=0; ip<NP; ip++) {
11759                String pname = pmap.keyAt(ip);
11760                SparseArray<Long> uids = pmap.valueAt(ip);
11761                final int N = uids.size();
11762                for (int i=0; i<N; i++) {
11763                    int puid = uids.keyAt(i);
11764                    ProcessRecord r = mProcessNames.get(pname, puid);
11765                    if (dumpPackage != null && (r == null
11766                            || !r.pkgList.containsKey(dumpPackage))) {
11767                        continue;
11768                    }
11769                    if (!printed) {
11770                        if (needSep) pw.println();
11771                        needSep = true;
11772                        pw.println("  Time since processes crashed:");
11773                        printed = true;
11774                        printedAnything = true;
11775                    }
11776                    pw.print("    Process "); pw.print(pname);
11777                            pw.print(" uid "); pw.print(puid);
11778                            pw.print(": last crashed ");
11779                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11780                            pw.println(" ago");
11781                }
11782            }
11783        }
11784
11785        if (mBadProcesses.getMap().size() > 0) {
11786            boolean printed = false;
11787            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11788            final int NP = pmap.size();
11789            for (int ip=0; ip<NP; ip++) {
11790                String pname = pmap.keyAt(ip);
11791                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11792                final int N = uids.size();
11793                for (int i=0; i<N; i++) {
11794                    int puid = uids.keyAt(i);
11795                    ProcessRecord r = mProcessNames.get(pname, puid);
11796                    if (dumpPackage != null && (r == null
11797                            || !r.pkgList.containsKey(dumpPackage))) {
11798                        continue;
11799                    }
11800                    if (!printed) {
11801                        if (needSep) pw.println();
11802                        needSep = true;
11803                        pw.println("  Bad processes:");
11804                        printedAnything = true;
11805                    }
11806                    BadProcessInfo info = uids.valueAt(i);
11807                    pw.print("    Bad process "); pw.print(pname);
11808                            pw.print(" uid "); pw.print(puid);
11809                            pw.print(": crashed at time "); pw.println(info.time);
11810                    if (info.shortMsg != null) {
11811                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11812                    }
11813                    if (info.longMsg != null) {
11814                        pw.print("      Long msg: "); pw.println(info.longMsg);
11815                    }
11816                    if (info.stack != null) {
11817                        pw.println("      Stack:");
11818                        int lastPos = 0;
11819                        for (int pos=0; pos<info.stack.length(); pos++) {
11820                            if (info.stack.charAt(pos) == '\n') {
11821                                pw.print("        ");
11822                                pw.write(info.stack, lastPos, pos-lastPos);
11823                                pw.println();
11824                                lastPos = pos+1;
11825                            }
11826                        }
11827                        if (lastPos < info.stack.length()) {
11828                            pw.print("        ");
11829                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11830                            pw.println();
11831                        }
11832                    }
11833                }
11834            }
11835        }
11836
11837        if (dumpPackage == null) {
11838            pw.println();
11839            needSep = false;
11840            pw.println("  mStartedUsers:");
11841            for (int i=0; i<mStartedUsers.size(); i++) {
11842                UserStartedState uss = mStartedUsers.valueAt(i);
11843                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11844                        pw.print(": "); uss.dump("", pw);
11845            }
11846            pw.print("  mStartedUserArray: [");
11847            for (int i=0; i<mStartedUserArray.length; i++) {
11848                if (i > 0) pw.print(", ");
11849                pw.print(mStartedUserArray[i]);
11850            }
11851            pw.println("]");
11852            pw.print("  mUserLru: [");
11853            for (int i=0; i<mUserLru.size(); i++) {
11854                if (i > 0) pw.print(", ");
11855                pw.print(mUserLru.get(i));
11856            }
11857            pw.println("]");
11858            if (dumpAll) {
11859                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11860            }
11861            synchronized (mUserProfileGroupIdsSelfLocked) {
11862                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11863                    pw.println("  mUserProfileGroupIds:");
11864                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11865                        pw.print("    User #");
11866                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11867                        pw.print(" -> profile #");
11868                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11869                    }
11870                }
11871            }
11872        }
11873        if (mHomeProcess != null && (dumpPackage == null
11874                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11875            if (needSep) {
11876                pw.println();
11877                needSep = false;
11878            }
11879            pw.println("  mHomeProcess: " + mHomeProcess);
11880        }
11881        if (mPreviousProcess != null && (dumpPackage == null
11882                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11883            if (needSep) {
11884                pw.println();
11885                needSep = false;
11886            }
11887            pw.println("  mPreviousProcess: " + mPreviousProcess);
11888        }
11889        if (dumpAll) {
11890            StringBuilder sb = new StringBuilder(128);
11891            sb.append("  mPreviousProcessVisibleTime: ");
11892            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11893            pw.println(sb);
11894        }
11895        if (mHeavyWeightProcess != null && (dumpPackage == null
11896                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11897            if (needSep) {
11898                pw.println();
11899                needSep = false;
11900            }
11901            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11902        }
11903        if (dumpPackage == null) {
11904            pw.println("  mConfiguration: " + mConfiguration);
11905        }
11906        if (dumpAll) {
11907            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11908            if (mCompatModePackages.getPackages().size() > 0) {
11909                boolean printed = false;
11910                for (Map.Entry<String, Integer> entry
11911                        : mCompatModePackages.getPackages().entrySet()) {
11912                    String pkg = entry.getKey();
11913                    int mode = entry.getValue();
11914                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11915                        continue;
11916                    }
11917                    if (!printed) {
11918                        pw.println("  mScreenCompatPackages:");
11919                        printed = true;
11920                    }
11921                    pw.print("    "); pw.print(pkg); pw.print(": ");
11922                            pw.print(mode); pw.println();
11923                }
11924            }
11925        }
11926        if (dumpPackage == null) {
11927            if (mSleeping || mWentToSleep || mLockScreenShown) {
11928                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11929                        + " mLockScreenShown " + mLockScreenShown);
11930            }
11931            if (mShuttingDown || mRunningVoice) {
11932                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11933            }
11934        }
11935        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11936                || mOrigWaitForDebugger) {
11937            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11938                    || dumpPackage.equals(mOrigDebugApp)) {
11939                if (needSep) {
11940                    pw.println();
11941                    needSep = false;
11942                }
11943                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11944                        + " mDebugTransient=" + mDebugTransient
11945                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11946            }
11947        }
11948        if (mOpenGlTraceApp != null) {
11949            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11950                if (needSep) {
11951                    pw.println();
11952                    needSep = false;
11953                }
11954                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11955            }
11956        }
11957        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11958                || mProfileFd != null) {
11959            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11960                if (needSep) {
11961                    pw.println();
11962                    needSep = false;
11963                }
11964                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11965                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11966                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11967                        + mAutoStopProfiler);
11968            }
11969        }
11970        if (dumpPackage == null) {
11971            if (mAlwaysFinishActivities || mController != null) {
11972                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11973                        + " mController=" + mController);
11974            }
11975            if (dumpAll) {
11976                pw.println("  Total persistent processes: " + numPers);
11977                pw.println("  mProcessesReady=" + mProcessesReady
11978                        + " mSystemReady=" + mSystemReady);
11979                pw.println("  mBooting=" + mBooting
11980                        + " mBooted=" + mBooted
11981                        + " mFactoryTest=" + mFactoryTest);
11982                pw.print("  mLastPowerCheckRealtime=");
11983                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11984                        pw.println("");
11985                pw.print("  mLastPowerCheckUptime=");
11986                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11987                        pw.println("");
11988                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11989                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11990                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11991                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11992                        + " (" + mLruProcesses.size() + " total)"
11993                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11994                        + " mNumServiceProcs=" + mNumServiceProcs
11995                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11996                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11997                        + " mLastMemoryLevel" + mLastMemoryLevel
11998                        + " mLastNumProcesses" + mLastNumProcesses);
11999                long now = SystemClock.uptimeMillis();
12000                pw.print("  mLastIdleTime=");
12001                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12002                        pw.print(" mLowRamSinceLastIdle=");
12003                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12004                        pw.println();
12005            }
12006        }
12007
12008        if (!printedAnything) {
12009            pw.println("  (nothing)");
12010        }
12011    }
12012
12013    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12014            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12015        if (mProcessesToGc.size() > 0) {
12016            boolean printed = false;
12017            long now = SystemClock.uptimeMillis();
12018            for (int i=0; i<mProcessesToGc.size(); i++) {
12019                ProcessRecord proc = mProcessesToGc.get(i);
12020                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12021                    continue;
12022                }
12023                if (!printed) {
12024                    if (needSep) pw.println();
12025                    needSep = true;
12026                    pw.println("  Processes that are waiting to GC:");
12027                    printed = true;
12028                }
12029                pw.print("    Process "); pw.println(proc);
12030                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12031                        pw.print(", last gced=");
12032                        pw.print(now-proc.lastRequestedGc);
12033                        pw.print(" ms ago, last lowMem=");
12034                        pw.print(now-proc.lastLowMemory);
12035                        pw.println(" ms ago");
12036
12037            }
12038        }
12039        return needSep;
12040    }
12041
12042    void printOomLevel(PrintWriter pw, String name, int adj) {
12043        pw.print("    ");
12044        if (adj >= 0) {
12045            pw.print(' ');
12046            if (adj < 10) pw.print(' ');
12047        } else {
12048            if (adj > -10) pw.print(' ');
12049        }
12050        pw.print(adj);
12051        pw.print(": ");
12052        pw.print(name);
12053        pw.print(" (");
12054        pw.print(mProcessList.getMemLevel(adj)/1024);
12055        pw.println(" kB)");
12056    }
12057
12058    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12059            int opti, boolean dumpAll) {
12060        boolean needSep = false;
12061
12062        if (mLruProcesses.size() > 0) {
12063            if (needSep) pw.println();
12064            needSep = true;
12065            pw.println("  OOM levels:");
12066            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12067            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12068            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12069            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12070            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12071            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12072            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12073            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12074            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12075            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12076            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12077            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12078            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12079
12080            if (needSep) pw.println();
12081            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12082                    pw.print(" total, non-act at ");
12083                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12084                    pw.print(", non-svc at ");
12085                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12086                    pw.println("):");
12087            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12088            needSep = true;
12089        }
12090
12091        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12092
12093        pw.println();
12094        pw.println("  mHomeProcess: " + mHomeProcess);
12095        pw.println("  mPreviousProcess: " + mPreviousProcess);
12096        if (mHeavyWeightProcess != null) {
12097            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12098        }
12099
12100        return true;
12101    }
12102
12103    /**
12104     * There are three ways to call this:
12105     *  - no provider specified: dump all the providers
12106     *  - a flattened component name that matched an existing provider was specified as the
12107     *    first arg: dump that one provider
12108     *  - the first arg isn't the flattened component name of an existing provider:
12109     *    dump all providers whose component contains the first arg as a substring
12110     */
12111    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12112            int opti, boolean dumpAll) {
12113        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12114    }
12115
12116    static class ItemMatcher {
12117        ArrayList<ComponentName> components;
12118        ArrayList<String> strings;
12119        ArrayList<Integer> objects;
12120        boolean all;
12121
12122        ItemMatcher() {
12123            all = true;
12124        }
12125
12126        void build(String name) {
12127            ComponentName componentName = ComponentName.unflattenFromString(name);
12128            if (componentName != null) {
12129                if (components == null) {
12130                    components = new ArrayList<ComponentName>();
12131                }
12132                components.add(componentName);
12133                all = false;
12134            } else {
12135                int objectId = 0;
12136                // Not a '/' separated full component name; maybe an object ID?
12137                try {
12138                    objectId = Integer.parseInt(name, 16);
12139                    if (objects == null) {
12140                        objects = new ArrayList<Integer>();
12141                    }
12142                    objects.add(objectId);
12143                    all = false;
12144                } catch (RuntimeException e) {
12145                    // Not an integer; just do string match.
12146                    if (strings == null) {
12147                        strings = new ArrayList<String>();
12148                    }
12149                    strings.add(name);
12150                    all = false;
12151                }
12152            }
12153        }
12154
12155        int build(String[] args, int opti) {
12156            for (; opti<args.length; opti++) {
12157                String name = args[opti];
12158                if ("--".equals(name)) {
12159                    return opti+1;
12160                }
12161                build(name);
12162            }
12163            return opti;
12164        }
12165
12166        boolean match(Object object, ComponentName comp) {
12167            if (all) {
12168                return true;
12169            }
12170            if (components != null) {
12171                for (int i=0; i<components.size(); i++) {
12172                    if (components.get(i).equals(comp)) {
12173                        return true;
12174                    }
12175                }
12176            }
12177            if (objects != null) {
12178                for (int i=0; i<objects.size(); i++) {
12179                    if (System.identityHashCode(object) == objects.get(i)) {
12180                        return true;
12181                    }
12182                }
12183            }
12184            if (strings != null) {
12185                String flat = comp.flattenToString();
12186                for (int i=0; i<strings.size(); i++) {
12187                    if (flat.contains(strings.get(i))) {
12188                        return true;
12189                    }
12190                }
12191            }
12192            return false;
12193        }
12194    }
12195
12196    /**
12197     * There are three things that cmd can be:
12198     *  - a flattened component name that matches an existing activity
12199     *  - the cmd arg isn't the flattened component name of an existing activity:
12200     *    dump all activity whose component contains the cmd as a substring
12201     *  - A hex number of the ActivityRecord object instance.
12202     */
12203    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12204            int opti, boolean dumpAll) {
12205        ArrayList<ActivityRecord> activities;
12206
12207        synchronized (this) {
12208            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12209        }
12210
12211        if (activities.size() <= 0) {
12212            return false;
12213        }
12214
12215        String[] newArgs = new String[args.length - opti];
12216        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12217
12218        TaskRecord lastTask = null;
12219        boolean needSep = false;
12220        for (int i=activities.size()-1; i>=0; i--) {
12221            ActivityRecord r = activities.get(i);
12222            if (needSep) {
12223                pw.println();
12224            }
12225            needSep = true;
12226            synchronized (this) {
12227                if (lastTask != r.task) {
12228                    lastTask = r.task;
12229                    pw.print("TASK "); pw.print(lastTask.affinity);
12230                            pw.print(" id="); pw.println(lastTask.taskId);
12231                    if (dumpAll) {
12232                        lastTask.dump(pw, "  ");
12233                    }
12234                }
12235            }
12236            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12237        }
12238        return true;
12239    }
12240
12241    /**
12242     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12243     * there is a thread associated with the activity.
12244     */
12245    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12246            final ActivityRecord r, String[] args, boolean dumpAll) {
12247        String innerPrefix = prefix + "  ";
12248        synchronized (this) {
12249            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12250                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12251                    pw.print(" pid=");
12252                    if (r.app != null) pw.println(r.app.pid);
12253                    else pw.println("(not running)");
12254            if (dumpAll) {
12255                r.dump(pw, innerPrefix);
12256            }
12257        }
12258        if (r.app != null && r.app.thread != null) {
12259            // flush anything that is already in the PrintWriter since the thread is going
12260            // to write to the file descriptor directly
12261            pw.flush();
12262            try {
12263                TransferPipe tp = new TransferPipe();
12264                try {
12265                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12266                            r.appToken, innerPrefix, args);
12267                    tp.go(fd);
12268                } finally {
12269                    tp.kill();
12270                }
12271            } catch (IOException e) {
12272                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12273            } catch (RemoteException e) {
12274                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12275            }
12276        }
12277    }
12278
12279    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12280            int opti, boolean dumpAll, String dumpPackage) {
12281        boolean needSep = false;
12282        boolean onlyHistory = false;
12283        boolean printedAnything = false;
12284
12285        if ("history".equals(dumpPackage)) {
12286            if (opti < args.length && "-s".equals(args[opti])) {
12287                dumpAll = false;
12288            }
12289            onlyHistory = true;
12290            dumpPackage = null;
12291        }
12292
12293        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12294        if (!onlyHistory && dumpAll) {
12295            if (mRegisteredReceivers.size() > 0) {
12296                boolean printed = false;
12297                Iterator it = mRegisteredReceivers.values().iterator();
12298                while (it.hasNext()) {
12299                    ReceiverList r = (ReceiverList)it.next();
12300                    if (dumpPackage != null && (r.app == null ||
12301                            !dumpPackage.equals(r.app.info.packageName))) {
12302                        continue;
12303                    }
12304                    if (!printed) {
12305                        pw.println("  Registered Receivers:");
12306                        needSep = true;
12307                        printed = true;
12308                        printedAnything = true;
12309                    }
12310                    pw.print("  * "); pw.println(r);
12311                    r.dump(pw, "    ");
12312                }
12313            }
12314
12315            if (mReceiverResolver.dump(pw, needSep ?
12316                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12317                    "    ", dumpPackage, false)) {
12318                needSep = true;
12319                printedAnything = true;
12320            }
12321        }
12322
12323        for (BroadcastQueue q : mBroadcastQueues) {
12324            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12325            printedAnything |= needSep;
12326        }
12327
12328        needSep = true;
12329
12330        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12331            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12332                if (needSep) {
12333                    pw.println();
12334                }
12335                needSep = true;
12336                printedAnything = true;
12337                pw.print("  Sticky broadcasts for user ");
12338                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12339                StringBuilder sb = new StringBuilder(128);
12340                for (Map.Entry<String, ArrayList<Intent>> ent
12341                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12342                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12343                    if (dumpAll) {
12344                        pw.println(":");
12345                        ArrayList<Intent> intents = ent.getValue();
12346                        final int N = intents.size();
12347                        for (int i=0; i<N; i++) {
12348                            sb.setLength(0);
12349                            sb.append("    Intent: ");
12350                            intents.get(i).toShortString(sb, false, true, false, false);
12351                            pw.println(sb.toString());
12352                            Bundle bundle = intents.get(i).getExtras();
12353                            if (bundle != null) {
12354                                pw.print("      ");
12355                                pw.println(bundle.toString());
12356                            }
12357                        }
12358                    } else {
12359                        pw.println("");
12360                    }
12361                }
12362            }
12363        }
12364
12365        if (!onlyHistory && dumpAll) {
12366            pw.println();
12367            for (BroadcastQueue queue : mBroadcastQueues) {
12368                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12369                        + queue.mBroadcastsScheduled);
12370            }
12371            pw.println("  mHandler:");
12372            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12373            needSep = true;
12374            printedAnything = true;
12375        }
12376
12377        if (!printedAnything) {
12378            pw.println("  (nothing)");
12379        }
12380    }
12381
12382    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12383            int opti, boolean dumpAll, String dumpPackage) {
12384        boolean needSep;
12385        boolean printedAnything = false;
12386
12387        ItemMatcher matcher = new ItemMatcher();
12388        matcher.build(args, opti);
12389
12390        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12391
12392        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12393        printedAnything |= needSep;
12394
12395        if (mLaunchingProviders.size() > 0) {
12396            boolean printed = false;
12397            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12398                ContentProviderRecord r = mLaunchingProviders.get(i);
12399                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12400                    continue;
12401                }
12402                if (!printed) {
12403                    if (needSep) pw.println();
12404                    needSep = true;
12405                    pw.println("  Launching content providers:");
12406                    printed = true;
12407                    printedAnything = true;
12408                }
12409                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12410                        pw.println(r);
12411            }
12412        }
12413
12414        if (mGrantedUriPermissions.size() > 0) {
12415            boolean printed = false;
12416            int dumpUid = -2;
12417            if (dumpPackage != null) {
12418                try {
12419                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12420                } catch (NameNotFoundException e) {
12421                    dumpUid = -1;
12422                }
12423            }
12424            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12425                int uid = mGrantedUriPermissions.keyAt(i);
12426                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12427                    continue;
12428                }
12429                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12430                if (!printed) {
12431                    if (needSep) pw.println();
12432                    needSep = true;
12433                    pw.println("  Granted Uri Permissions:");
12434                    printed = true;
12435                    printedAnything = true;
12436                }
12437                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12438                for (UriPermission perm : perms.values()) {
12439                    pw.print("    "); pw.println(perm);
12440                    if (dumpAll) {
12441                        perm.dump(pw, "      ");
12442                    }
12443                }
12444            }
12445        }
12446
12447        if (!printedAnything) {
12448            pw.println("  (nothing)");
12449        }
12450    }
12451
12452    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12453            int opti, boolean dumpAll, String dumpPackage) {
12454        boolean printed = false;
12455
12456        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12457
12458        if (mIntentSenderRecords.size() > 0) {
12459            Iterator<WeakReference<PendingIntentRecord>> it
12460                    = mIntentSenderRecords.values().iterator();
12461            while (it.hasNext()) {
12462                WeakReference<PendingIntentRecord> ref = it.next();
12463                PendingIntentRecord rec = ref != null ? ref.get(): null;
12464                if (dumpPackage != null && (rec == null
12465                        || !dumpPackage.equals(rec.key.packageName))) {
12466                    continue;
12467                }
12468                printed = true;
12469                if (rec != null) {
12470                    pw.print("  * "); pw.println(rec);
12471                    if (dumpAll) {
12472                        rec.dump(pw, "    ");
12473                    }
12474                } else {
12475                    pw.print("  * "); pw.println(ref);
12476                }
12477            }
12478        }
12479
12480        if (!printed) {
12481            pw.println("  (nothing)");
12482        }
12483    }
12484
12485    private static final int dumpProcessList(PrintWriter pw,
12486            ActivityManagerService service, List list,
12487            String prefix, String normalLabel, String persistentLabel,
12488            String dumpPackage) {
12489        int numPers = 0;
12490        final int N = list.size()-1;
12491        for (int i=N; i>=0; i--) {
12492            ProcessRecord r = (ProcessRecord)list.get(i);
12493            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12494                continue;
12495            }
12496            pw.println(String.format("%s%s #%2d: %s",
12497                    prefix, (r.persistent ? persistentLabel : normalLabel),
12498                    i, r.toString()));
12499            if (r.persistent) {
12500                numPers++;
12501            }
12502        }
12503        return numPers;
12504    }
12505
12506    private static final boolean dumpProcessOomList(PrintWriter pw,
12507            ActivityManagerService service, List<ProcessRecord> origList,
12508            String prefix, String normalLabel, String persistentLabel,
12509            boolean inclDetails, String dumpPackage) {
12510
12511        ArrayList<Pair<ProcessRecord, Integer>> list
12512                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12513        for (int i=0; i<origList.size(); i++) {
12514            ProcessRecord r = origList.get(i);
12515            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12516                continue;
12517            }
12518            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12519        }
12520
12521        if (list.size() <= 0) {
12522            return false;
12523        }
12524
12525        Comparator<Pair<ProcessRecord, Integer>> comparator
12526                = new Comparator<Pair<ProcessRecord, Integer>>() {
12527            @Override
12528            public int compare(Pair<ProcessRecord, Integer> object1,
12529                    Pair<ProcessRecord, Integer> object2) {
12530                if (object1.first.setAdj != object2.first.setAdj) {
12531                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12532                }
12533                if (object1.second.intValue() != object2.second.intValue()) {
12534                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12535                }
12536                return 0;
12537            }
12538        };
12539
12540        Collections.sort(list, comparator);
12541
12542        final long curRealtime = SystemClock.elapsedRealtime();
12543        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12544        final long curUptime = SystemClock.uptimeMillis();
12545        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12546
12547        for (int i=list.size()-1; i>=0; i--) {
12548            ProcessRecord r = list.get(i).first;
12549            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12550            char schedGroup;
12551            switch (r.setSchedGroup) {
12552                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12553                    schedGroup = 'B';
12554                    break;
12555                case Process.THREAD_GROUP_DEFAULT:
12556                    schedGroup = 'F';
12557                    break;
12558                default:
12559                    schedGroup = '?';
12560                    break;
12561            }
12562            char foreground;
12563            if (r.foregroundActivities) {
12564                foreground = 'A';
12565            } else if (r.foregroundServices) {
12566                foreground = 'S';
12567            } else {
12568                foreground = ' ';
12569            }
12570            String procState = ProcessList.makeProcStateString(r.curProcState);
12571            pw.print(prefix);
12572            pw.print(r.persistent ? persistentLabel : normalLabel);
12573            pw.print(" #");
12574            int num = (origList.size()-1)-list.get(i).second;
12575            if (num < 10) pw.print(' ');
12576            pw.print(num);
12577            pw.print(": ");
12578            pw.print(oomAdj);
12579            pw.print(' ');
12580            pw.print(schedGroup);
12581            pw.print('/');
12582            pw.print(foreground);
12583            pw.print('/');
12584            pw.print(procState);
12585            pw.print(" trm:");
12586            if (r.trimMemoryLevel < 10) pw.print(' ');
12587            pw.print(r.trimMemoryLevel);
12588            pw.print(' ');
12589            pw.print(r.toShortString());
12590            pw.print(" (");
12591            pw.print(r.adjType);
12592            pw.println(')');
12593            if (r.adjSource != null || r.adjTarget != null) {
12594                pw.print(prefix);
12595                pw.print("    ");
12596                if (r.adjTarget instanceof ComponentName) {
12597                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12598                } else if (r.adjTarget != null) {
12599                    pw.print(r.adjTarget.toString());
12600                } else {
12601                    pw.print("{null}");
12602                }
12603                pw.print("<=");
12604                if (r.adjSource instanceof ProcessRecord) {
12605                    pw.print("Proc{");
12606                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12607                    pw.println("}");
12608                } else if (r.adjSource != null) {
12609                    pw.println(r.adjSource.toString());
12610                } else {
12611                    pw.println("{null}");
12612                }
12613            }
12614            if (inclDetails) {
12615                pw.print(prefix);
12616                pw.print("    ");
12617                pw.print("oom: max="); pw.print(r.maxAdj);
12618                pw.print(" curRaw="); pw.print(r.curRawAdj);
12619                pw.print(" setRaw="); pw.print(r.setRawAdj);
12620                pw.print(" cur="); pw.print(r.curAdj);
12621                pw.print(" set="); pw.println(r.setAdj);
12622                pw.print(prefix);
12623                pw.print("    ");
12624                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12625                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12626                pw.print(" lastPss="); pw.print(r.lastPss);
12627                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12628                pw.print(prefix);
12629                pw.print("    ");
12630                pw.print("cached="); pw.print(r.cached);
12631                pw.print(" empty="); pw.print(r.empty);
12632                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12633
12634                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12635                    if (r.lastWakeTime != 0) {
12636                        long wtime;
12637                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12638                        synchronized (stats) {
12639                            wtime = stats.getProcessWakeTime(r.info.uid,
12640                                    r.pid, curRealtime);
12641                        }
12642                        long timeUsed = wtime - r.lastWakeTime;
12643                        pw.print(prefix);
12644                        pw.print("    ");
12645                        pw.print("keep awake over ");
12646                        TimeUtils.formatDuration(realtimeSince, pw);
12647                        pw.print(" used ");
12648                        TimeUtils.formatDuration(timeUsed, pw);
12649                        pw.print(" (");
12650                        pw.print((timeUsed*100)/realtimeSince);
12651                        pw.println("%)");
12652                    }
12653                    if (r.lastCpuTime != 0) {
12654                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12655                        pw.print(prefix);
12656                        pw.print("    ");
12657                        pw.print("run cpu over ");
12658                        TimeUtils.formatDuration(uptimeSince, pw);
12659                        pw.print(" used ");
12660                        TimeUtils.formatDuration(timeUsed, pw);
12661                        pw.print(" (");
12662                        pw.print((timeUsed*100)/uptimeSince);
12663                        pw.println("%)");
12664                    }
12665                }
12666            }
12667        }
12668        return true;
12669    }
12670
12671    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12672        ArrayList<ProcessRecord> procs;
12673        synchronized (this) {
12674            if (args != null && args.length > start
12675                    && args[start].charAt(0) != '-') {
12676                procs = new ArrayList<ProcessRecord>();
12677                int pid = -1;
12678                try {
12679                    pid = Integer.parseInt(args[start]);
12680                } catch (NumberFormatException e) {
12681                }
12682                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12683                    ProcessRecord proc = mLruProcesses.get(i);
12684                    if (proc.pid == pid) {
12685                        procs.add(proc);
12686                    } else if (proc.processName.equals(args[start])) {
12687                        procs.add(proc);
12688                    }
12689                }
12690                if (procs.size() <= 0) {
12691                    return null;
12692                }
12693            } else {
12694                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12695            }
12696        }
12697        return procs;
12698    }
12699
12700    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12701            PrintWriter pw, String[] args) {
12702        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12703        if (procs == null) {
12704            pw.println("No process found for: " + args[0]);
12705            return;
12706        }
12707
12708        long uptime = SystemClock.uptimeMillis();
12709        long realtime = SystemClock.elapsedRealtime();
12710        pw.println("Applications Graphics Acceleration Info:");
12711        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12712
12713        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12714            ProcessRecord r = procs.get(i);
12715            if (r.thread != null) {
12716                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12717                pw.flush();
12718                try {
12719                    TransferPipe tp = new TransferPipe();
12720                    try {
12721                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12722                        tp.go(fd);
12723                    } finally {
12724                        tp.kill();
12725                    }
12726                } catch (IOException e) {
12727                    pw.println("Failure while dumping the app: " + r);
12728                    pw.flush();
12729                } catch (RemoteException e) {
12730                    pw.println("Got a RemoteException while dumping the app " + r);
12731                    pw.flush();
12732                }
12733            }
12734        }
12735    }
12736
12737    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12738        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12739        if (procs == null) {
12740            pw.println("No process found for: " + args[0]);
12741            return;
12742        }
12743
12744        pw.println("Applications Database Info:");
12745
12746        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12747            ProcessRecord r = procs.get(i);
12748            if (r.thread != null) {
12749                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12750                pw.flush();
12751                try {
12752                    TransferPipe tp = new TransferPipe();
12753                    try {
12754                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12755                        tp.go(fd);
12756                    } finally {
12757                        tp.kill();
12758                    }
12759                } catch (IOException e) {
12760                    pw.println("Failure while dumping the app: " + r);
12761                    pw.flush();
12762                } catch (RemoteException e) {
12763                    pw.println("Got a RemoteException while dumping the app " + r);
12764                    pw.flush();
12765                }
12766            }
12767        }
12768    }
12769
12770    final static class MemItem {
12771        final boolean isProc;
12772        final String label;
12773        final String shortLabel;
12774        final long pss;
12775        final int id;
12776        final boolean hasActivities;
12777        ArrayList<MemItem> subitems;
12778
12779        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12780                boolean _hasActivities) {
12781            isProc = true;
12782            label = _label;
12783            shortLabel = _shortLabel;
12784            pss = _pss;
12785            id = _id;
12786            hasActivities = _hasActivities;
12787        }
12788
12789        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12790            isProc = false;
12791            label = _label;
12792            shortLabel = _shortLabel;
12793            pss = _pss;
12794            id = _id;
12795            hasActivities = false;
12796        }
12797    }
12798
12799    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12800            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12801        if (sort && !isCompact) {
12802            Collections.sort(items, new Comparator<MemItem>() {
12803                @Override
12804                public int compare(MemItem lhs, MemItem rhs) {
12805                    if (lhs.pss < rhs.pss) {
12806                        return 1;
12807                    } else if (lhs.pss > rhs.pss) {
12808                        return -1;
12809                    }
12810                    return 0;
12811                }
12812            });
12813        }
12814
12815        for (int i=0; i<items.size(); i++) {
12816            MemItem mi = items.get(i);
12817            if (!isCompact) {
12818                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12819            } else if (mi.isProc) {
12820                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12821                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12822                pw.println(mi.hasActivities ? ",a" : ",e");
12823            } else {
12824                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12825                pw.println(mi.pss);
12826            }
12827            if (mi.subitems != null) {
12828                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12829                        true, isCompact);
12830            }
12831        }
12832    }
12833
12834    // These are in KB.
12835    static final long[] DUMP_MEM_BUCKETS = new long[] {
12836        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12837        120*1024, 160*1024, 200*1024,
12838        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12839        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12840    };
12841
12842    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12843            boolean stackLike) {
12844        int start = label.lastIndexOf('.');
12845        if (start >= 0) start++;
12846        else start = 0;
12847        int end = label.length();
12848        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12849            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12850                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12851                out.append(bucket);
12852                out.append(stackLike ? "MB." : "MB ");
12853                out.append(label, start, end);
12854                return;
12855            }
12856        }
12857        out.append(memKB/1024);
12858        out.append(stackLike ? "MB." : "MB ");
12859        out.append(label, start, end);
12860    }
12861
12862    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12863            ProcessList.NATIVE_ADJ,
12864            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12865            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12866            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12867            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12868            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12869    };
12870    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12871            "Native",
12872            "System", "Persistent", "Foreground",
12873            "Visible", "Perceptible",
12874            "Heavy Weight", "Backup",
12875            "A Services", "Home",
12876            "Previous", "B Services", "Cached"
12877    };
12878    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12879            "native",
12880            "sys", "pers", "fore",
12881            "vis", "percept",
12882            "heavy", "backup",
12883            "servicea", "home",
12884            "prev", "serviceb", "cached"
12885    };
12886
12887    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12888            long realtime, boolean isCheckinRequest, boolean isCompact) {
12889        if (isCheckinRequest || isCompact) {
12890            // short checkin version
12891            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12892        } else {
12893            pw.println("Applications Memory Usage (kB):");
12894            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12895        }
12896    }
12897
12898    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12899            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12900        boolean dumpDetails = false;
12901        boolean dumpFullDetails = false;
12902        boolean dumpDalvik = false;
12903        boolean oomOnly = false;
12904        boolean isCompact = false;
12905        boolean localOnly = false;
12906
12907        int opti = 0;
12908        while (opti < args.length) {
12909            String opt = args[opti];
12910            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12911                break;
12912            }
12913            opti++;
12914            if ("-a".equals(opt)) {
12915                dumpDetails = true;
12916                dumpFullDetails = true;
12917                dumpDalvik = true;
12918            } else if ("-d".equals(opt)) {
12919                dumpDalvik = true;
12920            } else if ("-c".equals(opt)) {
12921                isCompact = true;
12922            } else if ("--oom".equals(opt)) {
12923                oomOnly = true;
12924            } else if ("--local".equals(opt)) {
12925                localOnly = true;
12926            } else if ("-h".equals(opt)) {
12927                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12928                pw.println("  -a: include all available information for each process.");
12929                pw.println("  -d: include dalvik details when dumping process details.");
12930                pw.println("  -c: dump in a compact machine-parseable representation.");
12931                pw.println("  --oom: only show processes organized by oom adj.");
12932                pw.println("  --local: only collect details locally, don't call process.");
12933                pw.println("If [process] is specified it can be the name or ");
12934                pw.println("pid of a specific process to dump.");
12935                return;
12936            } else {
12937                pw.println("Unknown argument: " + opt + "; use -h for help");
12938            }
12939        }
12940
12941        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12942        long uptime = SystemClock.uptimeMillis();
12943        long realtime = SystemClock.elapsedRealtime();
12944        final long[] tmpLong = new long[1];
12945
12946        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12947        if (procs == null) {
12948            // No Java processes.  Maybe they want to print a native process.
12949            if (args != null && args.length > opti
12950                    && args[opti].charAt(0) != '-') {
12951                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12952                        = new ArrayList<ProcessCpuTracker.Stats>();
12953                updateCpuStatsNow();
12954                int findPid = -1;
12955                try {
12956                    findPid = Integer.parseInt(args[opti]);
12957                } catch (NumberFormatException e) {
12958                }
12959                synchronized (mProcessCpuThread) {
12960                    final int N = mProcessCpuTracker.countStats();
12961                    for (int i=0; i<N; i++) {
12962                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12963                        if (st.pid == findPid || (st.baseName != null
12964                                && st.baseName.equals(args[opti]))) {
12965                            nativeProcs.add(st);
12966                        }
12967                    }
12968                }
12969                if (nativeProcs.size() > 0) {
12970                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12971                            isCompact);
12972                    Debug.MemoryInfo mi = null;
12973                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12974                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12975                        final int pid = r.pid;
12976                        if (!isCheckinRequest && dumpDetails) {
12977                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12978                        }
12979                        if (mi == null) {
12980                            mi = new Debug.MemoryInfo();
12981                        }
12982                        if (dumpDetails || (!brief && !oomOnly)) {
12983                            Debug.getMemoryInfo(pid, mi);
12984                        } else {
12985                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12986                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12987                        }
12988                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12989                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12990                        if (isCheckinRequest) {
12991                            pw.println();
12992                        }
12993                    }
12994                    return;
12995                }
12996            }
12997            pw.println("No process found for: " + args[opti]);
12998            return;
12999        }
13000
13001        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13002            dumpDetails = true;
13003        }
13004
13005        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13006
13007        String[] innerArgs = new String[args.length-opti];
13008        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13009
13010        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13011        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13012        long nativePss=0, dalvikPss=0, otherPss=0;
13013        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13014
13015        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13016        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13017                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13018
13019        long totalPss = 0;
13020        long cachedPss = 0;
13021
13022        Debug.MemoryInfo mi = null;
13023        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13024            final ProcessRecord r = procs.get(i);
13025            final IApplicationThread thread;
13026            final int pid;
13027            final int oomAdj;
13028            final boolean hasActivities;
13029            synchronized (this) {
13030                thread = r.thread;
13031                pid = r.pid;
13032                oomAdj = r.getSetAdjWithServices();
13033                hasActivities = r.activities.size() > 0;
13034            }
13035            if (thread != null) {
13036                if (!isCheckinRequest && dumpDetails) {
13037                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13038                }
13039                if (mi == null) {
13040                    mi = new Debug.MemoryInfo();
13041                }
13042                if (dumpDetails || (!brief && !oomOnly)) {
13043                    Debug.getMemoryInfo(pid, mi);
13044                } else {
13045                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13046                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13047                }
13048                if (dumpDetails) {
13049                    if (localOnly) {
13050                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13051                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13052                        if (isCheckinRequest) {
13053                            pw.println();
13054                        }
13055                    } else {
13056                        try {
13057                            pw.flush();
13058                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13059                                    dumpDalvik, innerArgs);
13060                        } catch (RemoteException e) {
13061                            if (!isCheckinRequest) {
13062                                pw.println("Got RemoteException!");
13063                                pw.flush();
13064                            }
13065                        }
13066                    }
13067                }
13068
13069                final long myTotalPss = mi.getTotalPss();
13070                final long myTotalUss = mi.getTotalUss();
13071
13072                synchronized (this) {
13073                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13074                        // Record this for posterity if the process has been stable.
13075                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13076                    }
13077                }
13078
13079                if (!isCheckinRequest && mi != null) {
13080                    totalPss += myTotalPss;
13081                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13082                            (hasActivities ? " / activities)" : ")"),
13083                            r.processName, myTotalPss, pid, hasActivities);
13084                    procMems.add(pssItem);
13085                    procMemsMap.put(pid, pssItem);
13086
13087                    nativePss += mi.nativePss;
13088                    dalvikPss += mi.dalvikPss;
13089                    otherPss += mi.otherPss;
13090                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13091                        long mem = mi.getOtherPss(j);
13092                        miscPss[j] += mem;
13093                        otherPss -= mem;
13094                    }
13095
13096                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13097                        cachedPss += myTotalPss;
13098                    }
13099
13100                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13101                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13102                                || oomIndex == (oomPss.length-1)) {
13103                            oomPss[oomIndex] += myTotalPss;
13104                            if (oomProcs[oomIndex] == null) {
13105                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13106                            }
13107                            oomProcs[oomIndex].add(pssItem);
13108                            break;
13109                        }
13110                    }
13111                }
13112            }
13113        }
13114
13115        long nativeProcTotalPss = 0;
13116
13117        if (!isCheckinRequest && procs.size() > 1) {
13118            // If we are showing aggregations, also look for native processes to
13119            // include so that our aggregations are more accurate.
13120            updateCpuStatsNow();
13121            synchronized (mProcessCpuThread) {
13122                final int N = mProcessCpuTracker.countStats();
13123                for (int i=0; i<N; i++) {
13124                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13125                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13126                        if (mi == null) {
13127                            mi = new Debug.MemoryInfo();
13128                        }
13129                        if (!brief && !oomOnly) {
13130                            Debug.getMemoryInfo(st.pid, mi);
13131                        } else {
13132                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13133                            mi.nativePrivateDirty = (int)tmpLong[0];
13134                        }
13135
13136                        final long myTotalPss = mi.getTotalPss();
13137                        totalPss += myTotalPss;
13138                        nativeProcTotalPss += myTotalPss;
13139
13140                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13141                                st.name, myTotalPss, st.pid, false);
13142                        procMems.add(pssItem);
13143
13144                        nativePss += mi.nativePss;
13145                        dalvikPss += mi.dalvikPss;
13146                        otherPss += mi.otherPss;
13147                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13148                            long mem = mi.getOtherPss(j);
13149                            miscPss[j] += mem;
13150                            otherPss -= mem;
13151                        }
13152                        oomPss[0] += myTotalPss;
13153                        if (oomProcs[0] == null) {
13154                            oomProcs[0] = new ArrayList<MemItem>();
13155                        }
13156                        oomProcs[0].add(pssItem);
13157                    }
13158                }
13159            }
13160
13161            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13162
13163            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13164            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13165            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13166            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13167                String label = Debug.MemoryInfo.getOtherLabel(j);
13168                catMems.add(new MemItem(label, label, miscPss[j], j));
13169            }
13170
13171            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13172            for (int j=0; j<oomPss.length; j++) {
13173                if (oomPss[j] != 0) {
13174                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13175                            : DUMP_MEM_OOM_LABEL[j];
13176                    MemItem item = new MemItem(label, label, oomPss[j],
13177                            DUMP_MEM_OOM_ADJ[j]);
13178                    item.subitems = oomProcs[j];
13179                    oomMems.add(item);
13180                }
13181            }
13182
13183            if (!brief && !oomOnly && !isCompact) {
13184                pw.println();
13185                pw.println("Total PSS by process:");
13186                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13187                pw.println();
13188            }
13189            if (!isCompact) {
13190                pw.println("Total PSS by OOM adjustment:");
13191            }
13192            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13193            if (!brief && !oomOnly) {
13194                PrintWriter out = categoryPw != null ? categoryPw : pw;
13195                if (!isCompact) {
13196                    out.println();
13197                    out.println("Total PSS by category:");
13198                }
13199                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13200            }
13201            if (!isCompact) {
13202                pw.println();
13203            }
13204            MemInfoReader memInfo = new MemInfoReader();
13205            memInfo.readMemInfo();
13206            if (nativeProcTotalPss > 0) {
13207                synchronized (this) {
13208                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13209                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13210                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13211                            nativeProcTotalPss);
13212                }
13213            }
13214            if (!brief) {
13215                if (!isCompact) {
13216                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13217                    pw.print(" kB (status ");
13218                    switch (mLastMemoryLevel) {
13219                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13220                            pw.println("normal)");
13221                            break;
13222                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13223                            pw.println("moderate)");
13224                            break;
13225                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13226                            pw.println("low)");
13227                            break;
13228                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13229                            pw.println("critical)");
13230                            break;
13231                        default:
13232                            pw.print(mLastMemoryLevel);
13233                            pw.println(")");
13234                            break;
13235                    }
13236                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13237                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13238                            pw.print(cachedPss); pw.print(" cached pss + ");
13239                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13240                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13241                } else {
13242                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13243                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13244                            + memInfo.getFreeSizeKb()); pw.print(",");
13245                    pw.println(totalPss - cachedPss);
13246                }
13247            }
13248            if (!isCompact) {
13249                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13250                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13251                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13252                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13253                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13254                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13255                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13256                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13257                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13258                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13259                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13260            }
13261            if (!brief) {
13262                if (memInfo.getZramTotalSizeKb() != 0) {
13263                    if (!isCompact) {
13264                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13265                                pw.print(" kB physical used for ");
13266                                pw.print(memInfo.getSwapTotalSizeKb()
13267                                        - memInfo.getSwapFreeSizeKb());
13268                                pw.print(" kB in swap (");
13269                                pw.print(memInfo.getSwapTotalSizeKb());
13270                                pw.println(" kB total swap)");
13271                    } else {
13272                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13273                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13274                                pw.println(memInfo.getSwapFreeSizeKb());
13275                    }
13276                }
13277                final int[] SINGLE_LONG_FORMAT = new int[] {
13278                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13279                };
13280                long[] longOut = new long[1];
13281                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13282                        SINGLE_LONG_FORMAT, null, longOut, null);
13283                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13284                longOut[0] = 0;
13285                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13286                        SINGLE_LONG_FORMAT, null, longOut, null);
13287                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13288                longOut[0] = 0;
13289                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13290                        SINGLE_LONG_FORMAT, null, longOut, null);
13291                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13292                longOut[0] = 0;
13293                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13294                        SINGLE_LONG_FORMAT, null, longOut, null);
13295                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13296                if (!isCompact) {
13297                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13298                        pw.print("      KSM: "); pw.print(sharing);
13299                                pw.print(" kB saved from shared ");
13300                                pw.print(shared); pw.println(" kB");
13301                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13302                                pw.print(voltile); pw.println(" kB volatile");
13303                    }
13304                    pw.print("   Tuning: ");
13305                    pw.print(ActivityManager.staticGetMemoryClass());
13306                    pw.print(" (large ");
13307                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13308                    pw.print("), oom ");
13309                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13310                    pw.print(" kB");
13311                    pw.print(", restore limit ");
13312                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13313                    pw.print(" kB");
13314                    if (ActivityManager.isLowRamDeviceStatic()) {
13315                        pw.print(" (low-ram)");
13316                    }
13317                    if (ActivityManager.isHighEndGfx()) {
13318                        pw.print(" (high-end-gfx)");
13319                    }
13320                    pw.println();
13321                } else {
13322                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13323                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13324                    pw.println(voltile);
13325                    pw.print("tuning,");
13326                    pw.print(ActivityManager.staticGetMemoryClass());
13327                    pw.print(',');
13328                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13329                    pw.print(',');
13330                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13331                    if (ActivityManager.isLowRamDeviceStatic()) {
13332                        pw.print(",low-ram");
13333                    }
13334                    if (ActivityManager.isHighEndGfx()) {
13335                        pw.print(",high-end-gfx");
13336                    }
13337                    pw.println();
13338                }
13339            }
13340        }
13341    }
13342
13343    /**
13344     * Searches array of arguments for the specified string
13345     * @param args array of argument strings
13346     * @param value value to search for
13347     * @return true if the value is contained in the array
13348     */
13349    private static boolean scanArgs(String[] args, String value) {
13350        if (args != null) {
13351            for (String arg : args) {
13352                if (value.equals(arg)) {
13353                    return true;
13354                }
13355            }
13356        }
13357        return false;
13358    }
13359
13360    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13361            ContentProviderRecord cpr, boolean always) {
13362        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13363
13364        if (!inLaunching || always) {
13365            synchronized (cpr) {
13366                cpr.launchingApp = null;
13367                cpr.notifyAll();
13368            }
13369            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13370            String names[] = cpr.info.authority.split(";");
13371            for (int j = 0; j < names.length; j++) {
13372                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13373            }
13374        }
13375
13376        for (int i=0; i<cpr.connections.size(); i++) {
13377            ContentProviderConnection conn = cpr.connections.get(i);
13378            if (conn.waiting) {
13379                // If this connection is waiting for the provider, then we don't
13380                // need to mess with its process unless we are always removing
13381                // or for some reason the provider is not currently launching.
13382                if (inLaunching && !always) {
13383                    continue;
13384                }
13385            }
13386            ProcessRecord capp = conn.client;
13387            conn.dead = true;
13388            if (conn.stableCount > 0) {
13389                if (!capp.persistent && capp.thread != null
13390                        && capp.pid != 0
13391                        && capp.pid != MY_PID) {
13392                    killUnneededProcessLocked(capp, "depends on provider "
13393                            + cpr.name.flattenToShortString()
13394                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13395                }
13396            } else if (capp.thread != null && conn.provider.provider != null) {
13397                try {
13398                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13399                } catch (RemoteException e) {
13400                }
13401                // In the protocol here, we don't expect the client to correctly
13402                // clean up this connection, we'll just remove it.
13403                cpr.connections.remove(i);
13404                conn.client.conProviders.remove(conn);
13405            }
13406        }
13407
13408        if (inLaunching && always) {
13409            mLaunchingProviders.remove(cpr);
13410        }
13411        return inLaunching;
13412    }
13413
13414    /**
13415     * Main code for cleaning up a process when it has gone away.  This is
13416     * called both as a result of the process dying, or directly when stopping
13417     * a process when running in single process mode.
13418     */
13419    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13420            boolean restarting, boolean allowRestart, int index) {
13421        if (index >= 0) {
13422            removeLruProcessLocked(app);
13423            ProcessList.remove(app.pid);
13424        }
13425
13426        mProcessesToGc.remove(app);
13427        mPendingPssProcesses.remove(app);
13428
13429        // Dismiss any open dialogs.
13430        if (app.crashDialog != null && !app.forceCrashReport) {
13431            app.crashDialog.dismiss();
13432            app.crashDialog = null;
13433        }
13434        if (app.anrDialog != null) {
13435            app.anrDialog.dismiss();
13436            app.anrDialog = null;
13437        }
13438        if (app.waitDialog != null) {
13439            app.waitDialog.dismiss();
13440            app.waitDialog = null;
13441        }
13442
13443        app.crashing = false;
13444        app.notResponding = false;
13445
13446        app.resetPackageList(mProcessStats);
13447        app.unlinkDeathRecipient();
13448        app.makeInactive(mProcessStats);
13449        app.waitingToKill = null;
13450        app.forcingToForeground = null;
13451        updateProcessForegroundLocked(app, false, false);
13452        app.foregroundActivities = false;
13453        app.hasShownUi = false;
13454        app.treatLikeActivity = false;
13455        app.hasAboveClient = false;
13456        app.hasClientActivities = false;
13457
13458        mServices.killServicesLocked(app, allowRestart);
13459
13460        boolean restart = false;
13461
13462        // Remove published content providers.
13463        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13464            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13465            final boolean always = app.bad || !allowRestart;
13466            if (removeDyingProviderLocked(app, cpr, always) || always) {
13467                // We left the provider in the launching list, need to
13468                // restart it.
13469                restart = true;
13470            }
13471
13472            cpr.provider = null;
13473            cpr.proc = null;
13474        }
13475        app.pubProviders.clear();
13476
13477        // Take care of any launching providers waiting for this process.
13478        if (checkAppInLaunchingProvidersLocked(app, false)) {
13479            restart = true;
13480        }
13481
13482        // Unregister from connected content providers.
13483        if (!app.conProviders.isEmpty()) {
13484            for (int i=0; i<app.conProviders.size(); i++) {
13485                ContentProviderConnection conn = app.conProviders.get(i);
13486                conn.provider.connections.remove(conn);
13487            }
13488            app.conProviders.clear();
13489        }
13490
13491        // At this point there may be remaining entries in mLaunchingProviders
13492        // where we were the only one waiting, so they are no longer of use.
13493        // Look for these and clean up if found.
13494        // XXX Commented out for now.  Trying to figure out a way to reproduce
13495        // the actual situation to identify what is actually going on.
13496        if (false) {
13497            for (int i=0; i<mLaunchingProviders.size(); i++) {
13498                ContentProviderRecord cpr = (ContentProviderRecord)
13499                        mLaunchingProviders.get(i);
13500                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13501                    synchronized (cpr) {
13502                        cpr.launchingApp = null;
13503                        cpr.notifyAll();
13504                    }
13505                }
13506            }
13507        }
13508
13509        skipCurrentReceiverLocked(app);
13510
13511        // Unregister any receivers.
13512        for (int i=app.receivers.size()-1; i>=0; i--) {
13513            removeReceiverLocked(app.receivers.valueAt(i));
13514        }
13515        app.receivers.clear();
13516
13517        // If the app is undergoing backup, tell the backup manager about it
13518        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13519            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13520                    + mBackupTarget.appInfo + " died during backup");
13521            try {
13522                IBackupManager bm = IBackupManager.Stub.asInterface(
13523                        ServiceManager.getService(Context.BACKUP_SERVICE));
13524                bm.agentDisconnected(app.info.packageName);
13525            } catch (RemoteException e) {
13526                // can't happen; backup manager is local
13527            }
13528        }
13529
13530        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13531            ProcessChangeItem item = mPendingProcessChanges.get(i);
13532            if (item.pid == app.pid) {
13533                mPendingProcessChanges.remove(i);
13534                mAvailProcessChanges.add(item);
13535            }
13536        }
13537        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13538
13539        // If the caller is restarting this app, then leave it in its
13540        // current lists and let the caller take care of it.
13541        if (restarting) {
13542            return;
13543        }
13544
13545        if (!app.persistent || app.isolated) {
13546            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13547                    "Removing non-persistent process during cleanup: " + app);
13548            mProcessNames.remove(app.processName, app.uid);
13549            mIsolatedProcesses.remove(app.uid);
13550            if (mHeavyWeightProcess == app) {
13551                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13552                        mHeavyWeightProcess.userId, 0));
13553                mHeavyWeightProcess = null;
13554            }
13555        } else if (!app.removed) {
13556            // This app is persistent, so we need to keep its record around.
13557            // If it is not already on the pending app list, add it there
13558            // and start a new process for it.
13559            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13560                mPersistentStartingProcesses.add(app);
13561                restart = true;
13562            }
13563        }
13564        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13565                "Clean-up removing on hold: " + app);
13566        mProcessesOnHold.remove(app);
13567
13568        if (app == mHomeProcess) {
13569            mHomeProcess = null;
13570        }
13571        if (app == mPreviousProcess) {
13572            mPreviousProcess = null;
13573        }
13574
13575        if (restart && !app.isolated) {
13576            // We have components that still need to be running in the
13577            // process, so re-launch it.
13578            mProcessNames.put(app.processName, app.uid, app);
13579            startProcessLocked(app, "restart", app.processName);
13580        } else if (app.pid > 0 && app.pid != MY_PID) {
13581            // Goodbye!
13582            boolean removed;
13583            synchronized (mPidsSelfLocked) {
13584                mPidsSelfLocked.remove(app.pid);
13585                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13586            }
13587            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13588            if (app.isolated) {
13589                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13590            }
13591            app.setPid(0);
13592        }
13593    }
13594
13595    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13596        // Look through the content providers we are waiting to have launched,
13597        // and if any run in this process then either schedule a restart of
13598        // the process or kill the client waiting for it if this process has
13599        // gone bad.
13600        int NL = mLaunchingProviders.size();
13601        boolean restart = false;
13602        for (int i=0; i<NL; i++) {
13603            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13604            if (cpr.launchingApp == app) {
13605                if (!alwaysBad && !app.bad) {
13606                    restart = true;
13607                } else {
13608                    removeDyingProviderLocked(app, cpr, true);
13609                    // cpr should have been removed from mLaunchingProviders
13610                    NL = mLaunchingProviders.size();
13611                    i--;
13612                }
13613            }
13614        }
13615        return restart;
13616    }
13617
13618    // =========================================================
13619    // SERVICES
13620    // =========================================================
13621
13622    @Override
13623    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13624            int flags) {
13625        enforceNotIsolatedCaller("getServices");
13626        synchronized (this) {
13627            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13628        }
13629    }
13630
13631    @Override
13632    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13633        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13634        synchronized (this) {
13635            return mServices.getRunningServiceControlPanelLocked(name);
13636        }
13637    }
13638
13639    @Override
13640    public ComponentName startService(IApplicationThread caller, Intent service,
13641            String resolvedType, int userId) {
13642        enforceNotIsolatedCaller("startService");
13643        // Refuse possible leaked file descriptors
13644        if (service != null && service.hasFileDescriptors() == true) {
13645            throw new IllegalArgumentException("File descriptors passed in Intent");
13646        }
13647
13648        if (DEBUG_SERVICE)
13649            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13650        synchronized(this) {
13651            final int callingPid = Binder.getCallingPid();
13652            final int callingUid = Binder.getCallingUid();
13653            final long origId = Binder.clearCallingIdentity();
13654            ComponentName res = mServices.startServiceLocked(caller, service,
13655                    resolvedType, callingPid, callingUid, userId);
13656            Binder.restoreCallingIdentity(origId);
13657            return res;
13658        }
13659    }
13660
13661    ComponentName startServiceInPackage(int uid,
13662            Intent service, String resolvedType, int userId) {
13663        synchronized(this) {
13664            if (DEBUG_SERVICE)
13665                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13666            final long origId = Binder.clearCallingIdentity();
13667            ComponentName res = mServices.startServiceLocked(null, service,
13668                    resolvedType, -1, uid, userId);
13669            Binder.restoreCallingIdentity(origId);
13670            return res;
13671        }
13672    }
13673
13674    @Override
13675    public int stopService(IApplicationThread caller, Intent service,
13676            String resolvedType, int userId) {
13677        enforceNotIsolatedCaller("stopService");
13678        // Refuse possible leaked file descriptors
13679        if (service != null && service.hasFileDescriptors() == true) {
13680            throw new IllegalArgumentException("File descriptors passed in Intent");
13681        }
13682
13683        synchronized(this) {
13684            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13685        }
13686    }
13687
13688    @Override
13689    public IBinder peekService(Intent service, String resolvedType) {
13690        enforceNotIsolatedCaller("peekService");
13691        // Refuse possible leaked file descriptors
13692        if (service != null && service.hasFileDescriptors() == true) {
13693            throw new IllegalArgumentException("File descriptors passed in Intent");
13694        }
13695        synchronized(this) {
13696            return mServices.peekServiceLocked(service, resolvedType);
13697        }
13698    }
13699
13700    @Override
13701    public boolean stopServiceToken(ComponentName className, IBinder token,
13702            int startId) {
13703        synchronized(this) {
13704            return mServices.stopServiceTokenLocked(className, token, startId);
13705        }
13706    }
13707
13708    @Override
13709    public void setServiceForeground(ComponentName className, IBinder token,
13710            int id, Notification notification, boolean removeNotification) {
13711        synchronized(this) {
13712            mServices.setServiceForegroundLocked(className, token, id, notification,
13713                    removeNotification);
13714        }
13715    }
13716
13717    @Override
13718    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13719            boolean requireFull, String name, String callerPackage) {
13720        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13721                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13722    }
13723
13724    int unsafeConvertIncomingUser(int userId) {
13725        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13726                ? mCurrentUserId : userId;
13727    }
13728
13729    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13730            int allowMode, String name, String callerPackage) {
13731        final int callingUserId = UserHandle.getUserId(callingUid);
13732        if (callingUserId == userId) {
13733            return userId;
13734        }
13735
13736        // Note that we may be accessing mCurrentUserId outside of a lock...
13737        // shouldn't be a big deal, if this is being called outside
13738        // of a locked context there is intrinsically a race with
13739        // the value the caller will receive and someone else changing it.
13740        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13741        // we will switch to the calling user if access to the current user fails.
13742        int targetUserId = unsafeConvertIncomingUser(userId);
13743
13744        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13745            final boolean allow;
13746            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13747                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13748                // If the caller has this permission, they always pass go.  And collect $200.
13749                allow = true;
13750            } else if (allowMode == ALLOW_FULL_ONLY) {
13751                // We require full access, sucks to be you.
13752                allow = false;
13753            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13754                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13755                // If the caller does not have either permission, they are always doomed.
13756                allow = false;
13757            } else if (allowMode == ALLOW_NON_FULL) {
13758                // We are blanket allowing non-full access, you lucky caller!
13759                allow = true;
13760            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13761                // We may or may not allow this depending on whether the two users are
13762                // in the same profile.
13763                synchronized (mUserProfileGroupIdsSelfLocked) {
13764                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13765                            UserInfo.NO_PROFILE_GROUP_ID);
13766                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13767                            UserInfo.NO_PROFILE_GROUP_ID);
13768                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13769                            && callingProfile == targetProfile;
13770                }
13771            } else {
13772                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13773            }
13774            if (!allow) {
13775                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13776                    // In this case, they would like to just execute as their
13777                    // owner user instead of failing.
13778                    targetUserId = callingUserId;
13779                } else {
13780                    StringBuilder builder = new StringBuilder(128);
13781                    builder.append("Permission Denial: ");
13782                    builder.append(name);
13783                    if (callerPackage != null) {
13784                        builder.append(" from ");
13785                        builder.append(callerPackage);
13786                    }
13787                    builder.append(" asks to run as user ");
13788                    builder.append(userId);
13789                    builder.append(" but is calling from user ");
13790                    builder.append(UserHandle.getUserId(callingUid));
13791                    builder.append("; this requires ");
13792                    builder.append(INTERACT_ACROSS_USERS_FULL);
13793                    if (allowMode != ALLOW_FULL_ONLY) {
13794                        builder.append(" or ");
13795                        builder.append(INTERACT_ACROSS_USERS);
13796                    }
13797                    String msg = builder.toString();
13798                    Slog.w(TAG, msg);
13799                    throw new SecurityException(msg);
13800                }
13801            }
13802        }
13803        if (!allowAll && targetUserId < 0) {
13804            throw new IllegalArgumentException(
13805                    "Call does not support special user #" + targetUserId);
13806        }
13807        return targetUserId;
13808    }
13809
13810    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13811            String className, int flags) {
13812        boolean result = false;
13813        // For apps that don't have pre-defined UIDs, check for permission
13814        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13815            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13816                if (ActivityManager.checkUidPermission(
13817                        INTERACT_ACROSS_USERS,
13818                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13819                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13820                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13821                            + " requests FLAG_SINGLE_USER, but app does not hold "
13822                            + INTERACT_ACROSS_USERS;
13823                    Slog.w(TAG, msg);
13824                    throw new SecurityException(msg);
13825                }
13826                // Permission passed
13827                result = true;
13828            }
13829        } else if ("system".equals(componentProcessName)) {
13830            result = true;
13831        } else {
13832            // App with pre-defined UID, check if it's a persistent app
13833            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13834        }
13835        if (DEBUG_MU) {
13836            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13837                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13838        }
13839        return result;
13840    }
13841
13842    /**
13843     * Checks to see if the caller is in the same app as the singleton
13844     * component, or the component is in a special app. It allows special apps
13845     * to export singleton components but prevents exporting singleton
13846     * components for regular apps.
13847     */
13848    boolean isValidSingletonCall(int callingUid, int componentUid) {
13849        int componentAppId = UserHandle.getAppId(componentUid);
13850        return UserHandle.isSameApp(callingUid, componentUid)
13851                || componentAppId == Process.SYSTEM_UID
13852                || componentAppId == Process.PHONE_UID
13853                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13854                        == PackageManager.PERMISSION_GRANTED;
13855    }
13856
13857    public int bindService(IApplicationThread caller, IBinder token,
13858            Intent service, String resolvedType,
13859            IServiceConnection connection, int flags, int userId) {
13860        enforceNotIsolatedCaller("bindService");
13861        // Refuse possible leaked file descriptors
13862        if (service != null && service.hasFileDescriptors() == true) {
13863            throw new IllegalArgumentException("File descriptors passed in Intent");
13864        }
13865
13866        synchronized(this) {
13867            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13868                    connection, flags, userId);
13869        }
13870    }
13871
13872    public boolean unbindService(IServiceConnection connection) {
13873        synchronized (this) {
13874            return mServices.unbindServiceLocked(connection);
13875        }
13876    }
13877
13878    public void publishService(IBinder token, Intent intent, IBinder service) {
13879        // Refuse possible leaked file descriptors
13880        if (intent != null && intent.hasFileDescriptors() == true) {
13881            throw new IllegalArgumentException("File descriptors passed in Intent");
13882        }
13883
13884        synchronized(this) {
13885            if (!(token instanceof ServiceRecord)) {
13886                throw new IllegalArgumentException("Invalid service token");
13887            }
13888            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13889        }
13890    }
13891
13892    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13893        // Refuse possible leaked file descriptors
13894        if (intent != null && intent.hasFileDescriptors() == true) {
13895            throw new IllegalArgumentException("File descriptors passed in Intent");
13896        }
13897
13898        synchronized(this) {
13899            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13900        }
13901    }
13902
13903    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13904        synchronized(this) {
13905            if (!(token instanceof ServiceRecord)) {
13906                throw new IllegalArgumentException("Invalid service token");
13907            }
13908            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13909        }
13910    }
13911
13912    // =========================================================
13913    // BACKUP AND RESTORE
13914    // =========================================================
13915
13916    // Cause the target app to be launched if necessary and its backup agent
13917    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13918    // activity manager to announce its creation.
13919    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13920        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13921        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13922
13923        synchronized(this) {
13924            // !!! TODO: currently no check here that we're already bound
13925            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13926            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13927            synchronized (stats) {
13928                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13929            }
13930
13931            // Backup agent is now in use, its package can't be stopped.
13932            try {
13933                AppGlobals.getPackageManager().setPackageStoppedState(
13934                        app.packageName, false, UserHandle.getUserId(app.uid));
13935            } catch (RemoteException e) {
13936            } catch (IllegalArgumentException e) {
13937                Slog.w(TAG, "Failed trying to unstop package "
13938                        + app.packageName + ": " + e);
13939            }
13940
13941            BackupRecord r = new BackupRecord(ss, app, backupMode);
13942            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13943                    ? new ComponentName(app.packageName, app.backupAgentName)
13944                    : new ComponentName("android", "FullBackupAgent");
13945            // startProcessLocked() returns existing proc's record if it's already running
13946            ProcessRecord proc = startProcessLocked(app.processName, app,
13947                    false, 0, "backup", hostingName, false, false, false);
13948            if (proc == null) {
13949                Slog.e(TAG, "Unable to start backup agent process " + r);
13950                return false;
13951            }
13952
13953            r.app = proc;
13954            mBackupTarget = r;
13955            mBackupAppName = app.packageName;
13956
13957            // Try not to kill the process during backup
13958            updateOomAdjLocked(proc);
13959
13960            // If the process is already attached, schedule the creation of the backup agent now.
13961            // If it is not yet live, this will be done when it attaches to the framework.
13962            if (proc.thread != null) {
13963                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13964                try {
13965                    proc.thread.scheduleCreateBackupAgent(app,
13966                            compatibilityInfoForPackageLocked(app), backupMode);
13967                } catch (RemoteException e) {
13968                    // Will time out on the backup manager side
13969                }
13970            } else {
13971                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13972            }
13973            // Invariants: at this point, the target app process exists and the application
13974            // is either already running or in the process of coming up.  mBackupTarget and
13975            // mBackupAppName describe the app, so that when it binds back to the AM we
13976            // know that it's scheduled for a backup-agent operation.
13977        }
13978
13979        return true;
13980    }
13981
13982    @Override
13983    public void clearPendingBackup() {
13984        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13985        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13986
13987        synchronized (this) {
13988            mBackupTarget = null;
13989            mBackupAppName = null;
13990        }
13991    }
13992
13993    // A backup agent has just come up
13994    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13995        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13996                + " = " + agent);
13997
13998        synchronized(this) {
13999            if (!agentPackageName.equals(mBackupAppName)) {
14000                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14001                return;
14002            }
14003        }
14004
14005        long oldIdent = Binder.clearCallingIdentity();
14006        try {
14007            IBackupManager bm = IBackupManager.Stub.asInterface(
14008                    ServiceManager.getService(Context.BACKUP_SERVICE));
14009            bm.agentConnected(agentPackageName, agent);
14010        } catch (RemoteException e) {
14011            // can't happen; the backup manager service is local
14012        } catch (Exception e) {
14013            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14014            e.printStackTrace();
14015        } finally {
14016            Binder.restoreCallingIdentity(oldIdent);
14017        }
14018    }
14019
14020    // done with this agent
14021    public void unbindBackupAgent(ApplicationInfo appInfo) {
14022        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14023        if (appInfo == null) {
14024            Slog.w(TAG, "unbind backup agent for null app");
14025            return;
14026        }
14027
14028        synchronized(this) {
14029            try {
14030                if (mBackupAppName == null) {
14031                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14032                    return;
14033                }
14034
14035                if (!mBackupAppName.equals(appInfo.packageName)) {
14036                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14037                    return;
14038                }
14039
14040                // Not backing this app up any more; reset its OOM adjustment
14041                final ProcessRecord proc = mBackupTarget.app;
14042                updateOomAdjLocked(proc);
14043
14044                // If the app crashed during backup, 'thread' will be null here
14045                if (proc.thread != null) {
14046                    try {
14047                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14048                                compatibilityInfoForPackageLocked(appInfo));
14049                    } catch (Exception e) {
14050                        Slog.e(TAG, "Exception when unbinding backup agent:");
14051                        e.printStackTrace();
14052                    }
14053                }
14054            } finally {
14055                mBackupTarget = null;
14056                mBackupAppName = null;
14057            }
14058        }
14059    }
14060    // =========================================================
14061    // BROADCASTS
14062    // =========================================================
14063
14064    private final List getStickiesLocked(String action, IntentFilter filter,
14065            List cur, int userId) {
14066        final ContentResolver resolver = mContext.getContentResolver();
14067        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14068        if (stickies == null) {
14069            return cur;
14070        }
14071        final ArrayList<Intent> list = stickies.get(action);
14072        if (list == null) {
14073            return cur;
14074        }
14075        int N = list.size();
14076        for (int i=0; i<N; i++) {
14077            Intent intent = list.get(i);
14078            if (filter.match(resolver, intent, true, TAG) >= 0) {
14079                if (cur == null) {
14080                    cur = new ArrayList<Intent>();
14081                }
14082                cur.add(intent);
14083            }
14084        }
14085        return cur;
14086    }
14087
14088    boolean isPendingBroadcastProcessLocked(int pid) {
14089        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14090                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14091    }
14092
14093    void skipPendingBroadcastLocked(int pid) {
14094            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14095            for (BroadcastQueue queue : mBroadcastQueues) {
14096                queue.skipPendingBroadcastLocked(pid);
14097            }
14098    }
14099
14100    // The app just attached; send any pending broadcasts that it should receive
14101    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14102        boolean didSomething = false;
14103        for (BroadcastQueue queue : mBroadcastQueues) {
14104            didSomething |= queue.sendPendingBroadcastsLocked(app);
14105        }
14106        return didSomething;
14107    }
14108
14109    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14110            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14111        enforceNotIsolatedCaller("registerReceiver");
14112        int callingUid;
14113        int callingPid;
14114        synchronized(this) {
14115            ProcessRecord callerApp = null;
14116            if (caller != null) {
14117                callerApp = getRecordForAppLocked(caller);
14118                if (callerApp == null) {
14119                    throw new SecurityException(
14120                            "Unable to find app for caller " + caller
14121                            + " (pid=" + Binder.getCallingPid()
14122                            + ") when registering receiver " + receiver);
14123                }
14124                if (callerApp.info.uid != Process.SYSTEM_UID &&
14125                        !callerApp.pkgList.containsKey(callerPackage) &&
14126                        !"android".equals(callerPackage)) {
14127                    throw new SecurityException("Given caller package " + callerPackage
14128                            + " is not running in process " + callerApp);
14129                }
14130                callingUid = callerApp.info.uid;
14131                callingPid = callerApp.pid;
14132            } else {
14133                callerPackage = null;
14134                callingUid = Binder.getCallingUid();
14135                callingPid = Binder.getCallingPid();
14136            }
14137
14138            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14139                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14140
14141            List allSticky = null;
14142
14143            // Look for any matching sticky broadcasts...
14144            Iterator actions = filter.actionsIterator();
14145            if (actions != null) {
14146                while (actions.hasNext()) {
14147                    String action = (String)actions.next();
14148                    allSticky = getStickiesLocked(action, filter, allSticky,
14149                            UserHandle.USER_ALL);
14150                    allSticky = getStickiesLocked(action, filter, allSticky,
14151                            UserHandle.getUserId(callingUid));
14152                }
14153            } else {
14154                allSticky = getStickiesLocked(null, filter, allSticky,
14155                        UserHandle.USER_ALL);
14156                allSticky = getStickiesLocked(null, filter, allSticky,
14157                        UserHandle.getUserId(callingUid));
14158            }
14159
14160            // The first sticky in the list is returned directly back to
14161            // the client.
14162            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14163
14164            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14165                    + ": " + sticky);
14166
14167            if (receiver == null) {
14168                return sticky;
14169            }
14170
14171            ReceiverList rl
14172                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14173            if (rl == null) {
14174                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14175                        userId, receiver);
14176                if (rl.app != null) {
14177                    rl.app.receivers.add(rl);
14178                } else {
14179                    try {
14180                        receiver.asBinder().linkToDeath(rl, 0);
14181                    } catch (RemoteException e) {
14182                        return sticky;
14183                    }
14184                    rl.linkedToDeath = true;
14185                }
14186                mRegisteredReceivers.put(receiver.asBinder(), rl);
14187            } else if (rl.uid != callingUid) {
14188                throw new IllegalArgumentException(
14189                        "Receiver requested to register for uid " + callingUid
14190                        + " was previously registered for uid " + rl.uid);
14191            } else if (rl.pid != callingPid) {
14192                throw new IllegalArgumentException(
14193                        "Receiver requested to register for pid " + callingPid
14194                        + " was previously registered for pid " + rl.pid);
14195            } else if (rl.userId != userId) {
14196                throw new IllegalArgumentException(
14197                        "Receiver requested to register for user " + userId
14198                        + " was previously registered for user " + rl.userId);
14199            }
14200            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14201                    permission, callingUid, userId);
14202            rl.add(bf);
14203            if (!bf.debugCheck()) {
14204                Slog.w(TAG, "==> For Dynamic broadast");
14205            }
14206            mReceiverResolver.addFilter(bf);
14207
14208            // Enqueue broadcasts for all existing stickies that match
14209            // this filter.
14210            if (allSticky != null) {
14211                ArrayList receivers = new ArrayList();
14212                receivers.add(bf);
14213
14214                int N = allSticky.size();
14215                for (int i=0; i<N; i++) {
14216                    Intent intent = (Intent)allSticky.get(i);
14217                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14218                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14219                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14220                            null, null, false, true, true, -1);
14221                    queue.enqueueParallelBroadcastLocked(r);
14222                    queue.scheduleBroadcastsLocked();
14223                }
14224            }
14225
14226            return sticky;
14227        }
14228    }
14229
14230    public void unregisterReceiver(IIntentReceiver receiver) {
14231        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14232
14233        final long origId = Binder.clearCallingIdentity();
14234        try {
14235            boolean doTrim = false;
14236
14237            synchronized(this) {
14238                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14239                if (rl != null) {
14240                    if (rl.curBroadcast != null) {
14241                        BroadcastRecord r = rl.curBroadcast;
14242                        final boolean doNext = finishReceiverLocked(
14243                                receiver.asBinder(), r.resultCode, r.resultData,
14244                                r.resultExtras, r.resultAbort);
14245                        if (doNext) {
14246                            doTrim = true;
14247                            r.queue.processNextBroadcast(false);
14248                        }
14249                    }
14250
14251                    if (rl.app != null) {
14252                        rl.app.receivers.remove(rl);
14253                    }
14254                    removeReceiverLocked(rl);
14255                    if (rl.linkedToDeath) {
14256                        rl.linkedToDeath = false;
14257                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14258                    }
14259                }
14260            }
14261
14262            // If we actually concluded any broadcasts, we might now be able
14263            // to trim the recipients' apps from our working set
14264            if (doTrim) {
14265                trimApplications();
14266                return;
14267            }
14268
14269        } finally {
14270            Binder.restoreCallingIdentity(origId);
14271        }
14272    }
14273
14274    void removeReceiverLocked(ReceiverList rl) {
14275        mRegisteredReceivers.remove(rl.receiver.asBinder());
14276        int N = rl.size();
14277        for (int i=0; i<N; i++) {
14278            mReceiverResolver.removeFilter(rl.get(i));
14279        }
14280    }
14281
14282    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14283        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14284            ProcessRecord r = mLruProcesses.get(i);
14285            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14286                try {
14287                    r.thread.dispatchPackageBroadcast(cmd, packages);
14288                } catch (RemoteException ex) {
14289                }
14290            }
14291        }
14292    }
14293
14294    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14295            int[] users) {
14296        List<ResolveInfo> receivers = null;
14297        try {
14298            HashSet<ComponentName> singleUserReceivers = null;
14299            boolean scannedFirstReceivers = false;
14300            for (int user : users) {
14301                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14302                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14303                if (user != 0 && newReceivers != null) {
14304                    // If this is not the primary user, we need to check for
14305                    // any receivers that should be filtered out.
14306                    for (int i=0; i<newReceivers.size(); i++) {
14307                        ResolveInfo ri = newReceivers.get(i);
14308                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14309                            newReceivers.remove(i);
14310                            i--;
14311                        }
14312                    }
14313                }
14314                if (newReceivers != null && newReceivers.size() == 0) {
14315                    newReceivers = null;
14316                }
14317                if (receivers == null) {
14318                    receivers = newReceivers;
14319                } else if (newReceivers != null) {
14320                    // We need to concatenate the additional receivers
14321                    // found with what we have do far.  This would be easy,
14322                    // but we also need to de-dup any receivers that are
14323                    // singleUser.
14324                    if (!scannedFirstReceivers) {
14325                        // Collect any single user receivers we had already retrieved.
14326                        scannedFirstReceivers = true;
14327                        for (int i=0; i<receivers.size(); i++) {
14328                            ResolveInfo ri = receivers.get(i);
14329                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14330                                ComponentName cn = new ComponentName(
14331                                        ri.activityInfo.packageName, ri.activityInfo.name);
14332                                if (singleUserReceivers == null) {
14333                                    singleUserReceivers = new HashSet<ComponentName>();
14334                                }
14335                                singleUserReceivers.add(cn);
14336                            }
14337                        }
14338                    }
14339                    // Add the new results to the existing results, tracking
14340                    // and de-dupping single user receivers.
14341                    for (int i=0; i<newReceivers.size(); i++) {
14342                        ResolveInfo ri = newReceivers.get(i);
14343                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14344                            ComponentName cn = new ComponentName(
14345                                    ri.activityInfo.packageName, ri.activityInfo.name);
14346                            if (singleUserReceivers == null) {
14347                                singleUserReceivers = new HashSet<ComponentName>();
14348                            }
14349                            if (!singleUserReceivers.contains(cn)) {
14350                                singleUserReceivers.add(cn);
14351                                receivers.add(ri);
14352                            }
14353                        } else {
14354                            receivers.add(ri);
14355                        }
14356                    }
14357                }
14358            }
14359        } catch (RemoteException ex) {
14360            // pm is in same process, this will never happen.
14361        }
14362        return receivers;
14363    }
14364
14365    private final int broadcastIntentLocked(ProcessRecord callerApp,
14366            String callerPackage, Intent intent, String resolvedType,
14367            IIntentReceiver resultTo, int resultCode, String resultData,
14368            Bundle map, String requiredPermission, int appOp,
14369            boolean ordered, boolean sticky, int callingPid, int callingUid,
14370            int userId) {
14371        intent = new Intent(intent);
14372
14373        // By default broadcasts do not go to stopped apps.
14374        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14375
14376        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14377            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14378            + " ordered=" + ordered + " userid=" + userId);
14379        if ((resultTo != null) && !ordered) {
14380            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14381        }
14382
14383        userId = handleIncomingUser(callingPid, callingUid, userId,
14384                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14385
14386        // Make sure that the user who is receiving this broadcast is started.
14387        // If not, we will just skip it.
14388
14389
14390        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14391            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14392                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14393                Slog.w(TAG, "Skipping broadcast of " + intent
14394                        + ": user " + userId + " is stopped");
14395                return ActivityManager.BROADCAST_SUCCESS;
14396            }
14397        }
14398
14399        /*
14400         * Prevent non-system code (defined here to be non-persistent
14401         * processes) from sending protected broadcasts.
14402         */
14403        int callingAppId = UserHandle.getAppId(callingUid);
14404        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14405            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14406            || callingAppId == Process.NFC_UID || callingUid == 0) {
14407            // Always okay.
14408        } else if (callerApp == null || !callerApp.persistent) {
14409            try {
14410                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14411                        intent.getAction())) {
14412                    String msg = "Permission Denial: not allowed to send broadcast "
14413                            + intent.getAction() + " from pid="
14414                            + callingPid + ", uid=" + callingUid;
14415                    Slog.w(TAG, msg);
14416                    throw new SecurityException(msg);
14417                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14418                    // Special case for compatibility: we don't want apps to send this,
14419                    // but historically it has not been protected and apps may be using it
14420                    // to poke their own app widget.  So, instead of making it protected,
14421                    // just limit it to the caller.
14422                    if (callerApp == null) {
14423                        String msg = "Permission Denial: not allowed to send broadcast "
14424                                + intent.getAction() + " from unknown caller.";
14425                        Slog.w(TAG, msg);
14426                        throw new SecurityException(msg);
14427                    } else if (intent.getComponent() != null) {
14428                        // They are good enough to send to an explicit component...  verify
14429                        // it is being sent to the calling app.
14430                        if (!intent.getComponent().getPackageName().equals(
14431                                callerApp.info.packageName)) {
14432                            String msg = "Permission Denial: not allowed to send broadcast "
14433                                    + intent.getAction() + " to "
14434                                    + intent.getComponent().getPackageName() + " from "
14435                                    + callerApp.info.packageName;
14436                            Slog.w(TAG, msg);
14437                            throw new SecurityException(msg);
14438                        }
14439                    } else {
14440                        // Limit broadcast to their own package.
14441                        intent.setPackage(callerApp.info.packageName);
14442                    }
14443                }
14444            } catch (RemoteException e) {
14445                Slog.w(TAG, "Remote exception", e);
14446                return ActivityManager.BROADCAST_SUCCESS;
14447            }
14448        }
14449
14450        // Handle special intents: if this broadcast is from the package
14451        // manager about a package being removed, we need to remove all of
14452        // its activities from the history stack.
14453        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14454                intent.getAction());
14455        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14456                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14457                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14458                || uidRemoved) {
14459            if (checkComponentPermission(
14460                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14461                    callingPid, callingUid, -1, true)
14462                    == PackageManager.PERMISSION_GRANTED) {
14463                if (uidRemoved) {
14464                    final Bundle intentExtras = intent.getExtras();
14465                    final int uid = intentExtras != null
14466                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14467                    if (uid >= 0) {
14468                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14469                        synchronized (bs) {
14470                            bs.removeUidStatsLocked(uid);
14471                        }
14472                        mAppOpsService.uidRemoved(uid);
14473                    }
14474                } else {
14475                    // If resources are unavailable just force stop all
14476                    // those packages and flush the attribute cache as well.
14477                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14478                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14479                        if (list != null && (list.length > 0)) {
14480                            for (String pkg : list) {
14481                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14482                                        "storage unmount");
14483                            }
14484                            sendPackageBroadcastLocked(
14485                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14486                        }
14487                    } else {
14488                        Uri data = intent.getData();
14489                        String ssp;
14490                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14491                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14492                                    intent.getAction());
14493                            boolean fullUninstall = removed &&
14494                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14495                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14496                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14497                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14498                                        false, fullUninstall, userId,
14499                                        removed ? "pkg removed" : "pkg changed");
14500                            }
14501                            if (removed) {
14502                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14503                                        new String[] {ssp}, userId);
14504                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14505                                    mAppOpsService.packageRemoved(
14506                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14507
14508                                    // Remove all permissions granted from/to this package
14509                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14510                                }
14511                            }
14512                        }
14513                    }
14514                }
14515            } else {
14516                String msg = "Permission Denial: " + intent.getAction()
14517                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14518                        + ", uid=" + callingUid + ")"
14519                        + " requires "
14520                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14521                Slog.w(TAG, msg);
14522                throw new SecurityException(msg);
14523            }
14524
14525        // Special case for adding a package: by default turn on compatibility
14526        // mode.
14527        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14528            Uri data = intent.getData();
14529            String ssp;
14530            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14531                mCompatModePackages.handlePackageAddedLocked(ssp,
14532                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14533            }
14534        }
14535
14536        /*
14537         * If this is the time zone changed action, queue up a message that will reset the timezone
14538         * of all currently running processes. This message will get queued up before the broadcast
14539         * happens.
14540         */
14541        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14542            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14543        }
14544
14545        /*
14546         * If the user set the time, let all running processes know.
14547         */
14548        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14549            final int is24Hour = intent.getBooleanExtra(
14550                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14551            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14552        }
14553
14554        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14555            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14556        }
14557
14558        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14559            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14560            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14561        }
14562
14563        // Add to the sticky list if requested.
14564        if (sticky) {
14565            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14566                    callingPid, callingUid)
14567                    != PackageManager.PERMISSION_GRANTED) {
14568                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14569                        + callingPid + ", uid=" + callingUid
14570                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14571                Slog.w(TAG, msg);
14572                throw new SecurityException(msg);
14573            }
14574            if (requiredPermission != null) {
14575                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14576                        + " and enforce permission " + requiredPermission);
14577                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14578            }
14579            if (intent.getComponent() != null) {
14580                throw new SecurityException(
14581                        "Sticky broadcasts can't target a specific component");
14582            }
14583            // We use userId directly here, since the "all" target is maintained
14584            // as a separate set of sticky broadcasts.
14585            if (userId != UserHandle.USER_ALL) {
14586                // But first, if this is not a broadcast to all users, then
14587                // make sure it doesn't conflict with an existing broadcast to
14588                // all users.
14589                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14590                        UserHandle.USER_ALL);
14591                if (stickies != null) {
14592                    ArrayList<Intent> list = stickies.get(intent.getAction());
14593                    if (list != null) {
14594                        int N = list.size();
14595                        int i;
14596                        for (i=0; i<N; i++) {
14597                            if (intent.filterEquals(list.get(i))) {
14598                                throw new IllegalArgumentException(
14599                                        "Sticky broadcast " + intent + " for user "
14600                                        + userId + " conflicts with existing global broadcast");
14601                            }
14602                        }
14603                    }
14604                }
14605            }
14606            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14607            if (stickies == null) {
14608                stickies = new ArrayMap<String, ArrayList<Intent>>();
14609                mStickyBroadcasts.put(userId, stickies);
14610            }
14611            ArrayList<Intent> list = stickies.get(intent.getAction());
14612            if (list == null) {
14613                list = new ArrayList<Intent>();
14614                stickies.put(intent.getAction(), list);
14615            }
14616            int N = list.size();
14617            int i;
14618            for (i=0; i<N; i++) {
14619                if (intent.filterEquals(list.get(i))) {
14620                    // This sticky already exists, replace it.
14621                    list.set(i, new Intent(intent));
14622                    break;
14623                }
14624            }
14625            if (i >= N) {
14626                list.add(new Intent(intent));
14627            }
14628        }
14629
14630        int[] users;
14631        if (userId == UserHandle.USER_ALL) {
14632            // Caller wants broadcast to go to all started users.
14633            users = mStartedUserArray;
14634        } else {
14635            // Caller wants broadcast to go to one specific user.
14636            users = new int[] {userId};
14637        }
14638
14639        // Figure out who all will receive this broadcast.
14640        List receivers = null;
14641        List<BroadcastFilter> registeredReceivers = null;
14642        // Need to resolve the intent to interested receivers...
14643        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14644                 == 0) {
14645            receivers = collectReceiverComponents(intent, resolvedType, users);
14646        }
14647        if (intent.getComponent() == null) {
14648            registeredReceivers = mReceiverResolver.queryIntent(intent,
14649                    resolvedType, false, userId);
14650        }
14651
14652        final boolean replacePending =
14653                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14654
14655        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14656                + " replacePending=" + replacePending);
14657
14658        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14659        if (!ordered && NR > 0) {
14660            // If we are not serializing this broadcast, then send the
14661            // registered receivers separately so they don't wait for the
14662            // components to be launched.
14663            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14664            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14665                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14666                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14667                    ordered, sticky, false, userId);
14668            if (DEBUG_BROADCAST) Slog.v(
14669                    TAG, "Enqueueing parallel broadcast " + r);
14670            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14671            if (!replaced) {
14672                queue.enqueueParallelBroadcastLocked(r);
14673                queue.scheduleBroadcastsLocked();
14674            }
14675            registeredReceivers = null;
14676            NR = 0;
14677        }
14678
14679        // Merge into one list.
14680        int ir = 0;
14681        if (receivers != null) {
14682            // A special case for PACKAGE_ADDED: do not allow the package
14683            // being added to see this broadcast.  This prevents them from
14684            // using this as a back door to get run as soon as they are
14685            // installed.  Maybe in the future we want to have a special install
14686            // broadcast or such for apps, but we'd like to deliberately make
14687            // this decision.
14688            String skipPackages[] = null;
14689            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14690                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14691                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14692                Uri data = intent.getData();
14693                if (data != null) {
14694                    String pkgName = data.getSchemeSpecificPart();
14695                    if (pkgName != null) {
14696                        skipPackages = new String[] { pkgName };
14697                    }
14698                }
14699            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14700                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14701            }
14702            if (skipPackages != null && (skipPackages.length > 0)) {
14703                for (String skipPackage : skipPackages) {
14704                    if (skipPackage != null) {
14705                        int NT = receivers.size();
14706                        for (int it=0; it<NT; it++) {
14707                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14708                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14709                                receivers.remove(it);
14710                                it--;
14711                                NT--;
14712                            }
14713                        }
14714                    }
14715                }
14716            }
14717
14718            int NT = receivers != null ? receivers.size() : 0;
14719            int it = 0;
14720            ResolveInfo curt = null;
14721            BroadcastFilter curr = null;
14722            while (it < NT && ir < NR) {
14723                if (curt == null) {
14724                    curt = (ResolveInfo)receivers.get(it);
14725                }
14726                if (curr == null) {
14727                    curr = registeredReceivers.get(ir);
14728                }
14729                if (curr.getPriority() >= curt.priority) {
14730                    // Insert this broadcast record into the final list.
14731                    receivers.add(it, curr);
14732                    ir++;
14733                    curr = null;
14734                    it++;
14735                    NT++;
14736                } else {
14737                    // Skip to the next ResolveInfo in the final list.
14738                    it++;
14739                    curt = null;
14740                }
14741            }
14742        }
14743        while (ir < NR) {
14744            if (receivers == null) {
14745                receivers = new ArrayList();
14746            }
14747            receivers.add(registeredReceivers.get(ir));
14748            ir++;
14749        }
14750
14751        if ((receivers != null && receivers.size() > 0)
14752                || resultTo != null) {
14753            BroadcastQueue queue = broadcastQueueForIntent(intent);
14754            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14755                    callerPackage, callingPid, callingUid, resolvedType,
14756                    requiredPermission, appOp, receivers, resultTo, resultCode,
14757                    resultData, map, ordered, sticky, false, userId);
14758            if (DEBUG_BROADCAST) Slog.v(
14759                    TAG, "Enqueueing ordered broadcast " + r
14760                    + ": prev had " + queue.mOrderedBroadcasts.size());
14761            if (DEBUG_BROADCAST) {
14762                int seq = r.intent.getIntExtra("seq", -1);
14763                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14764            }
14765            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14766            if (!replaced) {
14767                queue.enqueueOrderedBroadcastLocked(r);
14768                queue.scheduleBroadcastsLocked();
14769            }
14770        }
14771
14772        return ActivityManager.BROADCAST_SUCCESS;
14773    }
14774
14775    final Intent verifyBroadcastLocked(Intent intent) {
14776        // Refuse possible leaked file descriptors
14777        if (intent != null && intent.hasFileDescriptors() == true) {
14778            throw new IllegalArgumentException("File descriptors passed in Intent");
14779        }
14780
14781        int flags = intent.getFlags();
14782
14783        if (!mProcessesReady) {
14784            // if the caller really truly claims to know what they're doing, go
14785            // ahead and allow the broadcast without launching any receivers
14786            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14787                intent = new Intent(intent);
14788                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14789            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14790                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14791                        + " before boot completion");
14792                throw new IllegalStateException("Cannot broadcast before boot completed");
14793            }
14794        }
14795
14796        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14797            throw new IllegalArgumentException(
14798                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14799        }
14800
14801        return intent;
14802    }
14803
14804    public final int broadcastIntent(IApplicationThread caller,
14805            Intent intent, String resolvedType, IIntentReceiver resultTo,
14806            int resultCode, String resultData, Bundle map,
14807            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14808        enforceNotIsolatedCaller("broadcastIntent");
14809        synchronized(this) {
14810            intent = verifyBroadcastLocked(intent);
14811
14812            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14813            final int callingPid = Binder.getCallingPid();
14814            final int callingUid = Binder.getCallingUid();
14815            final long origId = Binder.clearCallingIdentity();
14816            int res = broadcastIntentLocked(callerApp,
14817                    callerApp != null ? callerApp.info.packageName : null,
14818                    intent, resolvedType, resultTo,
14819                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14820                    callingPid, callingUid, userId);
14821            Binder.restoreCallingIdentity(origId);
14822            return res;
14823        }
14824    }
14825
14826    int broadcastIntentInPackage(String packageName, int uid,
14827            Intent intent, String resolvedType, IIntentReceiver resultTo,
14828            int resultCode, String resultData, Bundle map,
14829            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14830        synchronized(this) {
14831            intent = verifyBroadcastLocked(intent);
14832
14833            final long origId = Binder.clearCallingIdentity();
14834            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14835                    resultTo, resultCode, resultData, map, requiredPermission,
14836                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14837            Binder.restoreCallingIdentity(origId);
14838            return res;
14839        }
14840    }
14841
14842    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14843        // Refuse possible leaked file descriptors
14844        if (intent != null && intent.hasFileDescriptors() == true) {
14845            throw new IllegalArgumentException("File descriptors passed in Intent");
14846        }
14847
14848        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14849                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14850
14851        synchronized(this) {
14852            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14853                    != PackageManager.PERMISSION_GRANTED) {
14854                String msg = "Permission Denial: unbroadcastIntent() from pid="
14855                        + Binder.getCallingPid()
14856                        + ", uid=" + Binder.getCallingUid()
14857                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14858                Slog.w(TAG, msg);
14859                throw new SecurityException(msg);
14860            }
14861            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14862            if (stickies != null) {
14863                ArrayList<Intent> list = stickies.get(intent.getAction());
14864                if (list != null) {
14865                    int N = list.size();
14866                    int i;
14867                    for (i=0; i<N; i++) {
14868                        if (intent.filterEquals(list.get(i))) {
14869                            list.remove(i);
14870                            break;
14871                        }
14872                    }
14873                    if (list.size() <= 0) {
14874                        stickies.remove(intent.getAction());
14875                    }
14876                }
14877                if (stickies.size() <= 0) {
14878                    mStickyBroadcasts.remove(userId);
14879                }
14880            }
14881        }
14882    }
14883
14884    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14885            String resultData, Bundle resultExtras, boolean resultAbort) {
14886        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14887        if (r == null) {
14888            Slog.w(TAG, "finishReceiver called but not found on queue");
14889            return false;
14890        }
14891
14892        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14893    }
14894
14895    void backgroundServicesFinishedLocked(int userId) {
14896        for (BroadcastQueue queue : mBroadcastQueues) {
14897            queue.backgroundServicesFinishedLocked(userId);
14898        }
14899    }
14900
14901    public void finishReceiver(IBinder who, int resultCode, String resultData,
14902            Bundle resultExtras, boolean resultAbort) {
14903        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14904
14905        // Refuse possible leaked file descriptors
14906        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14907            throw new IllegalArgumentException("File descriptors passed in Bundle");
14908        }
14909
14910        final long origId = Binder.clearCallingIdentity();
14911        try {
14912            boolean doNext = false;
14913            BroadcastRecord r;
14914
14915            synchronized(this) {
14916                r = broadcastRecordForReceiverLocked(who);
14917                if (r != null) {
14918                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14919                        resultData, resultExtras, resultAbort, true);
14920                }
14921            }
14922
14923            if (doNext) {
14924                r.queue.processNextBroadcast(false);
14925            }
14926            trimApplications();
14927        } finally {
14928            Binder.restoreCallingIdentity(origId);
14929        }
14930    }
14931
14932    // =========================================================
14933    // INSTRUMENTATION
14934    // =========================================================
14935
14936    public boolean startInstrumentation(ComponentName className,
14937            String profileFile, int flags, Bundle arguments,
14938            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14939            int userId, String abiOverride) {
14940        enforceNotIsolatedCaller("startInstrumentation");
14941        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14942                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14943        // Refuse possible leaked file descriptors
14944        if (arguments != null && arguments.hasFileDescriptors()) {
14945            throw new IllegalArgumentException("File descriptors passed in Bundle");
14946        }
14947
14948        synchronized(this) {
14949            InstrumentationInfo ii = null;
14950            ApplicationInfo ai = null;
14951            try {
14952                ii = mContext.getPackageManager().getInstrumentationInfo(
14953                    className, STOCK_PM_FLAGS);
14954                ai = AppGlobals.getPackageManager().getApplicationInfo(
14955                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14956            } catch (PackageManager.NameNotFoundException e) {
14957            } catch (RemoteException e) {
14958            }
14959            if (ii == null) {
14960                reportStartInstrumentationFailure(watcher, className,
14961                        "Unable to find instrumentation info for: " + className);
14962                return false;
14963            }
14964            if (ai == null) {
14965                reportStartInstrumentationFailure(watcher, className,
14966                        "Unable to find instrumentation target package: " + ii.targetPackage);
14967                return false;
14968            }
14969
14970            int match = mContext.getPackageManager().checkSignatures(
14971                    ii.targetPackage, ii.packageName);
14972            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14973                String msg = "Permission Denial: starting instrumentation "
14974                        + className + " from pid="
14975                        + Binder.getCallingPid()
14976                        + ", uid=" + Binder.getCallingPid()
14977                        + " not allowed because package " + ii.packageName
14978                        + " does not have a signature matching the target "
14979                        + ii.targetPackage;
14980                reportStartInstrumentationFailure(watcher, className, msg);
14981                throw new SecurityException(msg);
14982            }
14983
14984            final long origId = Binder.clearCallingIdentity();
14985            // Instrumentation can kill and relaunch even persistent processes
14986            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14987                    "start instr");
14988            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14989            app.instrumentationClass = className;
14990            app.instrumentationInfo = ai;
14991            app.instrumentationProfileFile = profileFile;
14992            app.instrumentationArguments = arguments;
14993            app.instrumentationWatcher = watcher;
14994            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14995            app.instrumentationResultClass = className;
14996            Binder.restoreCallingIdentity(origId);
14997        }
14998
14999        return true;
15000    }
15001
15002    /**
15003     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15004     * error to the logs, but if somebody is watching, send the report there too.  This enables
15005     * the "am" command to report errors with more information.
15006     *
15007     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15008     * @param cn The component name of the instrumentation.
15009     * @param report The error report.
15010     */
15011    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15012            ComponentName cn, String report) {
15013        Slog.w(TAG, report);
15014        try {
15015            if (watcher != null) {
15016                Bundle results = new Bundle();
15017                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15018                results.putString("Error", report);
15019                watcher.instrumentationStatus(cn, -1, results);
15020            }
15021        } catch (RemoteException e) {
15022            Slog.w(TAG, e);
15023        }
15024    }
15025
15026    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15027        if (app.instrumentationWatcher != null) {
15028            try {
15029                // NOTE:  IInstrumentationWatcher *must* be oneway here
15030                app.instrumentationWatcher.instrumentationFinished(
15031                    app.instrumentationClass,
15032                    resultCode,
15033                    results);
15034            } catch (RemoteException e) {
15035            }
15036        }
15037        if (app.instrumentationUiAutomationConnection != null) {
15038            try {
15039                app.instrumentationUiAutomationConnection.shutdown();
15040            } catch (RemoteException re) {
15041                /* ignore */
15042            }
15043            // Only a UiAutomation can set this flag and now that
15044            // it is finished we make sure it is reset to its default.
15045            mUserIsMonkey = false;
15046        }
15047        app.instrumentationWatcher = null;
15048        app.instrumentationUiAutomationConnection = null;
15049        app.instrumentationClass = null;
15050        app.instrumentationInfo = null;
15051        app.instrumentationProfileFile = null;
15052        app.instrumentationArguments = null;
15053
15054        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15055                "finished inst");
15056    }
15057
15058    public void finishInstrumentation(IApplicationThread target,
15059            int resultCode, Bundle results) {
15060        int userId = UserHandle.getCallingUserId();
15061        // Refuse possible leaked file descriptors
15062        if (results != null && results.hasFileDescriptors()) {
15063            throw new IllegalArgumentException("File descriptors passed in Intent");
15064        }
15065
15066        synchronized(this) {
15067            ProcessRecord app = getRecordForAppLocked(target);
15068            if (app == null) {
15069                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15070                return;
15071            }
15072            final long origId = Binder.clearCallingIdentity();
15073            finishInstrumentationLocked(app, resultCode, results);
15074            Binder.restoreCallingIdentity(origId);
15075        }
15076    }
15077
15078    // =========================================================
15079    // CONFIGURATION
15080    // =========================================================
15081
15082    public ConfigurationInfo getDeviceConfigurationInfo() {
15083        ConfigurationInfo config = new ConfigurationInfo();
15084        synchronized (this) {
15085            config.reqTouchScreen = mConfiguration.touchscreen;
15086            config.reqKeyboardType = mConfiguration.keyboard;
15087            config.reqNavigation = mConfiguration.navigation;
15088            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15089                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15090                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15091            }
15092            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15093                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15094                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15095            }
15096            config.reqGlEsVersion = GL_ES_VERSION;
15097        }
15098        return config;
15099    }
15100
15101    ActivityStack getFocusedStack() {
15102        return mStackSupervisor.getFocusedStack();
15103    }
15104
15105    public Configuration getConfiguration() {
15106        Configuration ci;
15107        synchronized(this) {
15108            ci = new Configuration(mConfiguration);
15109        }
15110        return ci;
15111    }
15112
15113    public void updatePersistentConfiguration(Configuration values) {
15114        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15115                "updateConfiguration()");
15116        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15117                "updateConfiguration()");
15118        if (values == null) {
15119            throw new NullPointerException("Configuration must not be null");
15120        }
15121
15122        synchronized(this) {
15123            final long origId = Binder.clearCallingIdentity();
15124            updateConfigurationLocked(values, null, true, false);
15125            Binder.restoreCallingIdentity(origId);
15126        }
15127    }
15128
15129    public void updateConfiguration(Configuration values) {
15130        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15131                "updateConfiguration()");
15132
15133        synchronized(this) {
15134            if (values == null && mWindowManager != null) {
15135                // sentinel: fetch the current configuration from the window manager
15136                values = mWindowManager.computeNewConfiguration();
15137            }
15138
15139            if (mWindowManager != null) {
15140                mProcessList.applyDisplaySize(mWindowManager);
15141            }
15142
15143            final long origId = Binder.clearCallingIdentity();
15144            if (values != null) {
15145                Settings.System.clearConfiguration(values);
15146            }
15147            updateConfigurationLocked(values, null, false, false);
15148            Binder.restoreCallingIdentity(origId);
15149        }
15150    }
15151
15152    /**
15153     * Do either or both things: (1) change the current configuration, and (2)
15154     * make sure the given activity is running with the (now) current
15155     * configuration.  Returns true if the activity has been left running, or
15156     * false if <var>starting</var> is being destroyed to match the new
15157     * configuration.
15158     * @param persistent TODO
15159     */
15160    boolean updateConfigurationLocked(Configuration values,
15161            ActivityRecord starting, boolean persistent, boolean initLocale) {
15162        int changes = 0;
15163
15164        if (values != null) {
15165            Configuration newConfig = new Configuration(mConfiguration);
15166            changes = newConfig.updateFrom(values);
15167            if (changes != 0) {
15168                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15169                    Slog.i(TAG, "Updating configuration to: " + values);
15170                }
15171
15172                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15173
15174                if (values.locale != null && !initLocale) {
15175                    saveLocaleLocked(values.locale,
15176                                     !values.locale.equals(mConfiguration.locale),
15177                                     values.userSetLocale);
15178                }
15179
15180                mConfigurationSeq++;
15181                if (mConfigurationSeq <= 0) {
15182                    mConfigurationSeq = 1;
15183                }
15184                newConfig.seq = mConfigurationSeq;
15185                mConfiguration = newConfig;
15186                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15187                //mUsageStatsService.noteStartConfig(newConfig);
15188
15189                final Configuration configCopy = new Configuration(mConfiguration);
15190
15191                // TODO: If our config changes, should we auto dismiss any currently
15192                // showing dialogs?
15193                mShowDialogs = shouldShowDialogs(newConfig);
15194
15195                AttributeCache ac = AttributeCache.instance();
15196                if (ac != null) {
15197                    ac.updateConfiguration(configCopy);
15198                }
15199
15200                // Make sure all resources in our process are updated
15201                // right now, so that anyone who is going to retrieve
15202                // resource values after we return will be sure to get
15203                // the new ones.  This is especially important during
15204                // boot, where the first config change needs to guarantee
15205                // all resources have that config before following boot
15206                // code is executed.
15207                mSystemThread.applyConfigurationToResources(configCopy);
15208
15209                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15210                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15211                    msg.obj = new Configuration(configCopy);
15212                    mHandler.sendMessage(msg);
15213                }
15214
15215                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15216                    ProcessRecord app = mLruProcesses.get(i);
15217                    try {
15218                        if (app.thread != null) {
15219                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15220                                    + app.processName + " new config " + mConfiguration);
15221                            app.thread.scheduleConfigurationChanged(configCopy);
15222                        }
15223                    } catch (Exception e) {
15224                    }
15225                }
15226                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15227                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15228                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15229                        | Intent.FLAG_RECEIVER_FOREGROUND);
15230                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15231                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15232                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15233                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15234                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15235                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15236                    broadcastIntentLocked(null, null, intent,
15237                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15238                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15239                }
15240            }
15241        }
15242
15243        boolean kept = true;
15244        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15245        // mainStack is null during startup.
15246        if (mainStack != null) {
15247            if (changes != 0 && starting == null) {
15248                // If the configuration changed, and the caller is not already
15249                // in the process of starting an activity, then find the top
15250                // activity to check if its configuration needs to change.
15251                starting = mainStack.topRunningActivityLocked(null);
15252            }
15253
15254            if (starting != null) {
15255                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15256                // And we need to make sure at this point that all other activities
15257                // are made visible with the correct configuration.
15258                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15259            }
15260        }
15261
15262        if (values != null && mWindowManager != null) {
15263            mWindowManager.setNewConfiguration(mConfiguration);
15264        }
15265
15266        return kept;
15267    }
15268
15269    /**
15270     * Decide based on the configuration whether we should shouw the ANR,
15271     * crash, etc dialogs.  The idea is that if there is no affordnace to
15272     * press the on-screen buttons, we shouldn't show the dialog.
15273     *
15274     * A thought: SystemUI might also want to get told about this, the Power
15275     * dialog / global actions also might want different behaviors.
15276     */
15277    private static final boolean shouldShowDialogs(Configuration config) {
15278        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15279                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15280    }
15281
15282    /**
15283     * Save the locale.  You must be inside a synchronized (this) block.
15284     */
15285    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15286        if(isDiff) {
15287            SystemProperties.set("user.language", l.getLanguage());
15288            SystemProperties.set("user.region", l.getCountry());
15289        }
15290
15291        if(isPersist) {
15292            SystemProperties.set("persist.sys.language", l.getLanguage());
15293            SystemProperties.set("persist.sys.country", l.getCountry());
15294            SystemProperties.set("persist.sys.localevar", l.getVariant());
15295        }
15296    }
15297
15298    @Override
15299    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15300        ActivityRecord srec = ActivityRecord.forToken(token);
15301        return srec != null && srec.task.affinity != null &&
15302                srec.task.affinity.equals(destAffinity);
15303    }
15304
15305    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15306            Intent resultData) {
15307
15308        synchronized (this) {
15309            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15310            if (stack != null) {
15311                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15312            }
15313            return false;
15314        }
15315    }
15316
15317    public int getLaunchedFromUid(IBinder activityToken) {
15318        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15319        if (srec == null) {
15320            return -1;
15321        }
15322        return srec.launchedFromUid;
15323    }
15324
15325    public String getLaunchedFromPackage(IBinder activityToken) {
15326        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15327        if (srec == null) {
15328            return null;
15329        }
15330        return srec.launchedFromPackage;
15331    }
15332
15333    // =========================================================
15334    // LIFETIME MANAGEMENT
15335    // =========================================================
15336
15337    // Returns which broadcast queue the app is the current [or imminent] receiver
15338    // on, or 'null' if the app is not an active broadcast recipient.
15339    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15340        BroadcastRecord r = app.curReceiver;
15341        if (r != null) {
15342            return r.queue;
15343        }
15344
15345        // It's not the current receiver, but it might be starting up to become one
15346        synchronized (this) {
15347            for (BroadcastQueue queue : mBroadcastQueues) {
15348                r = queue.mPendingBroadcast;
15349                if (r != null && r.curApp == app) {
15350                    // found it; report which queue it's in
15351                    return queue;
15352                }
15353            }
15354        }
15355
15356        return null;
15357    }
15358
15359    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15360            boolean doingAll, long now) {
15361        if (mAdjSeq == app.adjSeq) {
15362            // This adjustment has already been computed.
15363            return app.curRawAdj;
15364        }
15365
15366        if (app.thread == null) {
15367            app.adjSeq = mAdjSeq;
15368            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15369            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15370            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15371        }
15372
15373        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15374        app.adjSource = null;
15375        app.adjTarget = null;
15376        app.empty = false;
15377        app.cached = false;
15378
15379        final int activitiesSize = app.activities.size();
15380
15381        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15382            // The max adjustment doesn't allow this app to be anything
15383            // below foreground, so it is not worth doing work for it.
15384            app.adjType = "fixed";
15385            app.adjSeq = mAdjSeq;
15386            app.curRawAdj = app.maxAdj;
15387            app.foregroundActivities = false;
15388            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15389            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15390            // System processes can do UI, and when they do we want to have
15391            // them trim their memory after the user leaves the UI.  To
15392            // facilitate this, here we need to determine whether or not it
15393            // is currently showing UI.
15394            app.systemNoUi = true;
15395            if (app == TOP_APP) {
15396                app.systemNoUi = false;
15397            } else if (activitiesSize > 0) {
15398                for (int j = 0; j < activitiesSize; j++) {
15399                    final ActivityRecord r = app.activities.get(j);
15400                    if (r.visible) {
15401                        app.systemNoUi = false;
15402                    }
15403                }
15404            }
15405            if (!app.systemNoUi) {
15406                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15407            }
15408            return (app.curAdj=app.maxAdj);
15409        }
15410
15411        app.systemNoUi = false;
15412
15413        // Determine the importance of the process, starting with most
15414        // important to least, and assign an appropriate OOM adjustment.
15415        int adj;
15416        int schedGroup;
15417        int procState;
15418        boolean foregroundActivities = false;
15419        BroadcastQueue queue;
15420        if (app == TOP_APP) {
15421            // The last app on the list is the foreground app.
15422            adj = ProcessList.FOREGROUND_APP_ADJ;
15423            schedGroup = Process.THREAD_GROUP_DEFAULT;
15424            app.adjType = "top-activity";
15425            foregroundActivities = true;
15426            procState = ActivityManager.PROCESS_STATE_TOP;
15427        } else if (app.instrumentationClass != null) {
15428            // Don't want to kill running instrumentation.
15429            adj = ProcessList.FOREGROUND_APP_ADJ;
15430            schedGroup = Process.THREAD_GROUP_DEFAULT;
15431            app.adjType = "instrumentation";
15432            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15433        } else if ((queue = isReceivingBroadcast(app)) != null) {
15434            // An app that is currently receiving a broadcast also
15435            // counts as being in the foreground for OOM killer purposes.
15436            // It's placed in a sched group based on the nature of the
15437            // broadcast as reflected by which queue it's active in.
15438            adj = ProcessList.FOREGROUND_APP_ADJ;
15439            schedGroup = (queue == mFgBroadcastQueue)
15440                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15441            app.adjType = "broadcast";
15442            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15443        } else if (app.executingServices.size() > 0) {
15444            // An app that is currently executing a service callback also
15445            // counts as being in the foreground.
15446            adj = ProcessList.FOREGROUND_APP_ADJ;
15447            schedGroup = app.execServicesFg ?
15448                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15449            app.adjType = "exec-service";
15450            procState = ActivityManager.PROCESS_STATE_SERVICE;
15451            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15452        } else {
15453            // As far as we know the process is empty.  We may change our mind later.
15454            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15455            // At this point we don't actually know the adjustment.  Use the cached adj
15456            // value that the caller wants us to.
15457            adj = cachedAdj;
15458            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15459            app.cached = true;
15460            app.empty = true;
15461            app.adjType = "cch-empty";
15462        }
15463
15464        // Examine all activities if not already foreground.
15465        if (!foregroundActivities && activitiesSize > 0) {
15466            for (int j = 0; j < activitiesSize; j++) {
15467                final ActivityRecord r = app.activities.get(j);
15468                if (r.app != app) {
15469                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15470                            + app + "?!?");
15471                    continue;
15472                }
15473                if (r.visible) {
15474                    // App has a visible activity; only upgrade adjustment.
15475                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15476                        adj = ProcessList.VISIBLE_APP_ADJ;
15477                        app.adjType = "visible";
15478                    }
15479                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15480                        procState = ActivityManager.PROCESS_STATE_TOP;
15481                    }
15482                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15483                    app.cached = false;
15484                    app.empty = false;
15485                    foregroundActivities = true;
15486                    break;
15487                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15488                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15489                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15490                        app.adjType = "pausing";
15491                    }
15492                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15493                        procState = ActivityManager.PROCESS_STATE_TOP;
15494                    }
15495                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15496                    app.cached = false;
15497                    app.empty = false;
15498                    foregroundActivities = true;
15499                } else if (r.state == ActivityState.STOPPING) {
15500                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15501                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15502                        app.adjType = "stopping";
15503                    }
15504                    // For the process state, we will at this point consider the
15505                    // process to be cached.  It will be cached either as an activity
15506                    // or empty depending on whether the activity is finishing.  We do
15507                    // this so that we can treat the process as cached for purposes of
15508                    // memory trimming (determing current memory level, trim command to
15509                    // send to process) since there can be an arbitrary number of stopping
15510                    // processes and they should soon all go into the cached state.
15511                    if (!r.finishing) {
15512                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15513                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15514                        }
15515                    }
15516                    app.cached = false;
15517                    app.empty = false;
15518                    foregroundActivities = true;
15519                } else {
15520                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15521                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15522                        app.adjType = "cch-act";
15523                    }
15524                }
15525            }
15526        }
15527
15528        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15529            if (app.foregroundServices) {
15530                // The user is aware of this app, so make it visible.
15531                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15532                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15533                app.cached = false;
15534                app.adjType = "fg-service";
15535                schedGroup = Process.THREAD_GROUP_DEFAULT;
15536            } else if (app.forcingToForeground != null) {
15537                // The user is aware of this app, so make it visible.
15538                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15539                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15540                app.cached = false;
15541                app.adjType = "force-fg";
15542                app.adjSource = app.forcingToForeground;
15543                schedGroup = Process.THREAD_GROUP_DEFAULT;
15544            }
15545        }
15546
15547        if (app == mHeavyWeightProcess) {
15548            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15549                // We don't want to kill the current heavy-weight process.
15550                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15551                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15552                app.cached = false;
15553                app.adjType = "heavy";
15554            }
15555            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15556                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15557            }
15558        }
15559
15560        if (app == mHomeProcess) {
15561            if (adj > ProcessList.HOME_APP_ADJ) {
15562                // This process is hosting what we currently consider to be the
15563                // home app, so we don't want to let it go into the background.
15564                adj = ProcessList.HOME_APP_ADJ;
15565                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15566                app.cached = false;
15567                app.adjType = "home";
15568            }
15569            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15570                procState = ActivityManager.PROCESS_STATE_HOME;
15571            }
15572        }
15573
15574        if (app == mPreviousProcess && app.activities.size() > 0) {
15575            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15576                // This was the previous process that showed UI to the user.
15577                // We want to try to keep it around more aggressively, to give
15578                // a good experience around switching between two apps.
15579                adj = ProcessList.PREVIOUS_APP_ADJ;
15580                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15581                app.cached = false;
15582                app.adjType = "previous";
15583            }
15584            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15585                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15586            }
15587        }
15588
15589        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15590                + " reason=" + app.adjType);
15591
15592        // By default, we use the computed adjustment.  It may be changed if
15593        // there are applications dependent on our services or providers, but
15594        // this gives us a baseline and makes sure we don't get into an
15595        // infinite recursion.
15596        app.adjSeq = mAdjSeq;
15597        app.curRawAdj = adj;
15598        app.hasStartedServices = false;
15599
15600        if (mBackupTarget != null && app == mBackupTarget.app) {
15601            // If possible we want to avoid killing apps while they're being backed up
15602            if (adj > ProcessList.BACKUP_APP_ADJ) {
15603                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15604                adj = ProcessList.BACKUP_APP_ADJ;
15605                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15606                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15607                }
15608                app.adjType = "backup";
15609                app.cached = false;
15610            }
15611            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15612                procState = ActivityManager.PROCESS_STATE_BACKUP;
15613            }
15614        }
15615
15616        boolean mayBeTop = false;
15617
15618        for (int is = app.services.size()-1;
15619                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15620                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15621                        || procState > ActivityManager.PROCESS_STATE_TOP);
15622                is--) {
15623            ServiceRecord s = app.services.valueAt(is);
15624            if (s.startRequested) {
15625                app.hasStartedServices = true;
15626                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15627                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15628                }
15629                if (app.hasShownUi && app != mHomeProcess) {
15630                    // If this process has shown some UI, let it immediately
15631                    // go to the LRU list because it may be pretty heavy with
15632                    // UI stuff.  We'll tag it with a label just to help
15633                    // debug and understand what is going on.
15634                    if (adj > ProcessList.SERVICE_ADJ) {
15635                        app.adjType = "cch-started-ui-services";
15636                    }
15637                } else {
15638                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15639                        // This service has seen some activity within
15640                        // recent memory, so we will keep its process ahead
15641                        // of the background processes.
15642                        if (adj > ProcessList.SERVICE_ADJ) {
15643                            adj = ProcessList.SERVICE_ADJ;
15644                            app.adjType = "started-services";
15645                            app.cached = false;
15646                        }
15647                    }
15648                    // If we have let the service slide into the background
15649                    // state, still have some text describing what it is doing
15650                    // even though the service no longer has an impact.
15651                    if (adj > ProcessList.SERVICE_ADJ) {
15652                        app.adjType = "cch-started-services";
15653                    }
15654                }
15655            }
15656            for (int conni = s.connections.size()-1;
15657                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15658                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15659                            || procState > ActivityManager.PROCESS_STATE_TOP);
15660                    conni--) {
15661                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15662                for (int i = 0;
15663                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15664                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15665                                || procState > ActivityManager.PROCESS_STATE_TOP);
15666                        i++) {
15667                    // XXX should compute this based on the max of
15668                    // all connected clients.
15669                    ConnectionRecord cr = clist.get(i);
15670                    if (cr.binding.client == app) {
15671                        // Binding to ourself is not interesting.
15672                        continue;
15673                    }
15674                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15675                        ProcessRecord client = cr.binding.client;
15676                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15677                                TOP_APP, doingAll, now);
15678                        int clientProcState = client.curProcState;
15679                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15680                            // If the other app is cached for any reason, for purposes here
15681                            // we are going to consider it empty.  The specific cached state
15682                            // doesn't propagate except under certain conditions.
15683                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15684                        }
15685                        String adjType = null;
15686                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15687                            // Not doing bind OOM management, so treat
15688                            // this guy more like a started service.
15689                            if (app.hasShownUi && app != mHomeProcess) {
15690                                // If this process has shown some UI, let it immediately
15691                                // go to the LRU list because it may be pretty heavy with
15692                                // UI stuff.  We'll tag it with a label just to help
15693                                // debug and understand what is going on.
15694                                if (adj > clientAdj) {
15695                                    adjType = "cch-bound-ui-services";
15696                                }
15697                                app.cached = false;
15698                                clientAdj = adj;
15699                                clientProcState = procState;
15700                            } else {
15701                                if (now >= (s.lastActivity
15702                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15703                                    // This service has not seen activity within
15704                                    // recent memory, so allow it to drop to the
15705                                    // LRU list if there is no other reason to keep
15706                                    // it around.  We'll also tag it with a label just
15707                                    // to help debug and undertand what is going on.
15708                                    if (adj > clientAdj) {
15709                                        adjType = "cch-bound-services";
15710                                    }
15711                                    clientAdj = adj;
15712                                }
15713                            }
15714                        }
15715                        if (adj > clientAdj) {
15716                            // If this process has recently shown UI, and
15717                            // the process that is binding to it is less
15718                            // important than being visible, then we don't
15719                            // care about the binding as much as we care
15720                            // about letting this process get into the LRU
15721                            // list to be killed and restarted if needed for
15722                            // memory.
15723                            if (app.hasShownUi && app != mHomeProcess
15724                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15725                                adjType = "cch-bound-ui-services";
15726                            } else {
15727                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15728                                        |Context.BIND_IMPORTANT)) != 0) {
15729                                    adj = clientAdj;
15730                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15731                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15732                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15733                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15734                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15735                                    adj = clientAdj;
15736                                } else {
15737                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15738                                        adj = ProcessList.VISIBLE_APP_ADJ;
15739                                    }
15740                                }
15741                                if (!client.cached) {
15742                                    app.cached = false;
15743                                }
15744                                adjType = "service";
15745                            }
15746                        }
15747                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15748                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15749                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15750                            }
15751                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15752                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15753                                    // Special handling of clients who are in the top state.
15754                                    // We *may* want to consider this process to be in the
15755                                    // top state as well, but only if there is not another
15756                                    // reason for it to be running.  Being on the top is a
15757                                    // special state, meaning you are specifically running
15758                                    // for the current top app.  If the process is already
15759                                    // running in the background for some other reason, it
15760                                    // is more important to continue considering it to be
15761                                    // in the background state.
15762                                    mayBeTop = true;
15763                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15764                                } else {
15765                                    // Special handling for above-top states (persistent
15766                                    // processes).  These should not bring the current process
15767                                    // into the top state, since they are not on top.  Instead
15768                                    // give them the best state after that.
15769                                    clientProcState =
15770                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15771                                }
15772                            }
15773                        } else {
15774                            if (clientProcState <
15775                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15776                                clientProcState =
15777                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15778                            }
15779                        }
15780                        if (procState > clientProcState) {
15781                            procState = clientProcState;
15782                        }
15783                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15784                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15785                            app.pendingUiClean = true;
15786                        }
15787                        if (adjType != null) {
15788                            app.adjType = adjType;
15789                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15790                                    .REASON_SERVICE_IN_USE;
15791                            app.adjSource = cr.binding.client;
15792                            app.adjSourceProcState = clientProcState;
15793                            app.adjTarget = s.name;
15794                        }
15795                    }
15796                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15797                        app.treatLikeActivity = true;
15798                    }
15799                    final ActivityRecord a = cr.activity;
15800                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15801                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15802                                (a.visible || a.state == ActivityState.RESUMED
15803                                 || a.state == ActivityState.PAUSING)) {
15804                            adj = ProcessList.FOREGROUND_APP_ADJ;
15805                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15806                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15807                            }
15808                            app.cached = false;
15809                            app.adjType = "service";
15810                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15811                                    .REASON_SERVICE_IN_USE;
15812                            app.adjSource = a;
15813                            app.adjSourceProcState = procState;
15814                            app.adjTarget = s.name;
15815                        }
15816                    }
15817                }
15818            }
15819        }
15820
15821        for (int provi = app.pubProviders.size()-1;
15822                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15823                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15824                        || procState > ActivityManager.PROCESS_STATE_TOP);
15825                provi--) {
15826            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15827            for (int i = cpr.connections.size()-1;
15828                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15829                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15830                            || procState > ActivityManager.PROCESS_STATE_TOP);
15831                    i--) {
15832                ContentProviderConnection conn = cpr.connections.get(i);
15833                ProcessRecord client = conn.client;
15834                if (client == app) {
15835                    // Being our own client is not interesting.
15836                    continue;
15837                }
15838                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15839                int clientProcState = client.curProcState;
15840                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15841                    // If the other app is cached for any reason, for purposes here
15842                    // we are going to consider it empty.
15843                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15844                }
15845                if (adj > clientAdj) {
15846                    if (app.hasShownUi && app != mHomeProcess
15847                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15848                        app.adjType = "cch-ui-provider";
15849                    } else {
15850                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15851                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15852                        app.adjType = "provider";
15853                    }
15854                    app.cached &= client.cached;
15855                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15856                            .REASON_PROVIDER_IN_USE;
15857                    app.adjSource = client;
15858                    app.adjSourceProcState = clientProcState;
15859                    app.adjTarget = cpr.name;
15860                }
15861                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15862                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15863                        // Special handling of clients who are in the top state.
15864                        // We *may* want to consider this process to be in the
15865                        // top state as well, but only if there is not another
15866                        // reason for it to be running.  Being on the top is a
15867                        // special state, meaning you are specifically running
15868                        // for the current top app.  If the process is already
15869                        // running in the background for some other reason, it
15870                        // is more important to continue considering it to be
15871                        // in the background state.
15872                        mayBeTop = true;
15873                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15874                    } else {
15875                        // Special handling for above-top states (persistent
15876                        // processes).  These should not bring the current process
15877                        // into the top state, since they are not on top.  Instead
15878                        // give them the best state after that.
15879                        clientProcState =
15880                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15881                    }
15882                }
15883                if (procState > clientProcState) {
15884                    procState = clientProcState;
15885                }
15886                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15887                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15888                }
15889            }
15890            // If the provider has external (non-framework) process
15891            // dependencies, ensure that its adjustment is at least
15892            // FOREGROUND_APP_ADJ.
15893            if (cpr.hasExternalProcessHandles()) {
15894                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15895                    adj = ProcessList.FOREGROUND_APP_ADJ;
15896                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15897                    app.cached = false;
15898                    app.adjType = "provider";
15899                    app.adjTarget = cpr.name;
15900                }
15901                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15902                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15903                }
15904            }
15905        }
15906
15907        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15908            // A client of one of our services or providers is in the top state.  We
15909            // *may* want to be in the top state, but not if we are already running in
15910            // the background for some other reason.  For the decision here, we are going
15911            // to pick out a few specific states that we want to remain in when a client
15912            // is top (states that tend to be longer-term) and otherwise allow it to go
15913            // to the top state.
15914            switch (procState) {
15915                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15916                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15917                case ActivityManager.PROCESS_STATE_SERVICE:
15918                    // These all are longer-term states, so pull them up to the top
15919                    // of the background states, but not all the way to the top state.
15920                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15921                    break;
15922                default:
15923                    // Otherwise, top is a better choice, so take it.
15924                    procState = ActivityManager.PROCESS_STATE_TOP;
15925                    break;
15926            }
15927        }
15928
15929        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15930            if (app.hasClientActivities) {
15931                // This is a cached process, but with client activities.  Mark it so.
15932                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15933                app.adjType = "cch-client-act";
15934            } else if (app.treatLikeActivity) {
15935                // This is a cached process, but somebody wants us to treat it like it has
15936                // an activity, okay!
15937                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15938                app.adjType = "cch-as-act";
15939            }
15940        }
15941
15942        if (adj == ProcessList.SERVICE_ADJ) {
15943            if (doingAll) {
15944                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15945                mNewNumServiceProcs++;
15946                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15947                if (!app.serviceb) {
15948                    // This service isn't far enough down on the LRU list to
15949                    // normally be a B service, but if we are low on RAM and it
15950                    // is large we want to force it down since we would prefer to
15951                    // keep launcher over it.
15952                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15953                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15954                        app.serviceHighRam = true;
15955                        app.serviceb = true;
15956                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15957                    } else {
15958                        mNewNumAServiceProcs++;
15959                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15960                    }
15961                } else {
15962                    app.serviceHighRam = false;
15963                }
15964            }
15965            if (app.serviceb) {
15966                adj = ProcessList.SERVICE_B_ADJ;
15967            }
15968        }
15969
15970        app.curRawAdj = adj;
15971
15972        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15973        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15974        if (adj > app.maxAdj) {
15975            adj = app.maxAdj;
15976            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15977                schedGroup = Process.THREAD_GROUP_DEFAULT;
15978            }
15979        }
15980
15981        // Do final modification to adj.  Everything we do between here and applying
15982        // the final setAdj must be done in this function, because we will also use
15983        // it when computing the final cached adj later.  Note that we don't need to
15984        // worry about this for max adj above, since max adj will always be used to
15985        // keep it out of the cached vaues.
15986        app.curAdj = app.modifyRawOomAdj(adj);
15987        app.curSchedGroup = schedGroup;
15988        app.curProcState = procState;
15989        app.foregroundActivities = foregroundActivities;
15990
15991        return app.curRawAdj;
15992    }
15993
15994    /**
15995     * Schedule PSS collection of a process.
15996     */
15997    void requestPssLocked(ProcessRecord proc, int procState) {
15998        if (mPendingPssProcesses.contains(proc)) {
15999            return;
16000        }
16001        if (mPendingPssProcesses.size() == 0) {
16002            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16003        }
16004        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16005        proc.pssProcState = procState;
16006        mPendingPssProcesses.add(proc);
16007    }
16008
16009    /**
16010     * Schedule PSS collection of all processes.
16011     */
16012    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16013        if (!always) {
16014            if (now < (mLastFullPssTime +
16015                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16016                return;
16017            }
16018        }
16019        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16020        mLastFullPssTime = now;
16021        mFullPssPending = true;
16022        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16023        mPendingPssProcesses.clear();
16024        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16025            ProcessRecord app = mLruProcesses.get(i);
16026            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16027                app.pssProcState = app.setProcState;
16028                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16029                        isSleeping(), now);
16030                mPendingPssProcesses.add(app);
16031            }
16032        }
16033        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16034    }
16035
16036    /**
16037     * Ask a given process to GC right now.
16038     */
16039    final void performAppGcLocked(ProcessRecord app) {
16040        try {
16041            app.lastRequestedGc = SystemClock.uptimeMillis();
16042            if (app.thread != null) {
16043                if (app.reportLowMemory) {
16044                    app.reportLowMemory = false;
16045                    app.thread.scheduleLowMemory();
16046                } else {
16047                    app.thread.processInBackground();
16048                }
16049            }
16050        } catch (Exception e) {
16051            // whatever.
16052        }
16053    }
16054
16055    /**
16056     * Returns true if things are idle enough to perform GCs.
16057     */
16058    private final boolean canGcNowLocked() {
16059        boolean processingBroadcasts = false;
16060        for (BroadcastQueue q : mBroadcastQueues) {
16061            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16062                processingBroadcasts = true;
16063            }
16064        }
16065        return !processingBroadcasts
16066                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16067    }
16068
16069    /**
16070     * Perform GCs on all processes that are waiting for it, but only
16071     * if things are idle.
16072     */
16073    final void performAppGcsLocked() {
16074        final int N = mProcessesToGc.size();
16075        if (N <= 0) {
16076            return;
16077        }
16078        if (canGcNowLocked()) {
16079            while (mProcessesToGc.size() > 0) {
16080                ProcessRecord proc = mProcessesToGc.remove(0);
16081                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16082                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16083                            <= SystemClock.uptimeMillis()) {
16084                        // To avoid spamming the system, we will GC processes one
16085                        // at a time, waiting a few seconds between each.
16086                        performAppGcLocked(proc);
16087                        scheduleAppGcsLocked();
16088                        return;
16089                    } else {
16090                        // It hasn't been long enough since we last GCed this
16091                        // process...  put it in the list to wait for its time.
16092                        addProcessToGcListLocked(proc);
16093                        break;
16094                    }
16095                }
16096            }
16097
16098            scheduleAppGcsLocked();
16099        }
16100    }
16101
16102    /**
16103     * If all looks good, perform GCs on all processes waiting for them.
16104     */
16105    final void performAppGcsIfAppropriateLocked() {
16106        if (canGcNowLocked()) {
16107            performAppGcsLocked();
16108            return;
16109        }
16110        // Still not idle, wait some more.
16111        scheduleAppGcsLocked();
16112    }
16113
16114    /**
16115     * Schedule the execution of all pending app GCs.
16116     */
16117    final void scheduleAppGcsLocked() {
16118        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16119
16120        if (mProcessesToGc.size() > 0) {
16121            // Schedule a GC for the time to the next process.
16122            ProcessRecord proc = mProcessesToGc.get(0);
16123            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16124
16125            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16126            long now = SystemClock.uptimeMillis();
16127            if (when < (now+GC_TIMEOUT)) {
16128                when = now + GC_TIMEOUT;
16129            }
16130            mHandler.sendMessageAtTime(msg, when);
16131        }
16132    }
16133
16134    /**
16135     * Add a process to the array of processes waiting to be GCed.  Keeps the
16136     * list in sorted order by the last GC time.  The process can't already be
16137     * on the list.
16138     */
16139    final void addProcessToGcListLocked(ProcessRecord proc) {
16140        boolean added = false;
16141        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16142            if (mProcessesToGc.get(i).lastRequestedGc <
16143                    proc.lastRequestedGc) {
16144                added = true;
16145                mProcessesToGc.add(i+1, proc);
16146                break;
16147            }
16148        }
16149        if (!added) {
16150            mProcessesToGc.add(0, proc);
16151        }
16152    }
16153
16154    /**
16155     * Set up to ask a process to GC itself.  This will either do it
16156     * immediately, or put it on the list of processes to gc the next
16157     * time things are idle.
16158     */
16159    final void scheduleAppGcLocked(ProcessRecord app) {
16160        long now = SystemClock.uptimeMillis();
16161        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16162            return;
16163        }
16164        if (!mProcessesToGc.contains(app)) {
16165            addProcessToGcListLocked(app);
16166            scheduleAppGcsLocked();
16167        }
16168    }
16169
16170    final void checkExcessivePowerUsageLocked(boolean doKills) {
16171        updateCpuStatsNow();
16172
16173        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16174        boolean doWakeKills = doKills;
16175        boolean doCpuKills = doKills;
16176        if (mLastPowerCheckRealtime == 0) {
16177            doWakeKills = false;
16178        }
16179        if (mLastPowerCheckUptime == 0) {
16180            doCpuKills = false;
16181        }
16182        if (stats.isScreenOn()) {
16183            doWakeKills = false;
16184        }
16185        final long curRealtime = SystemClock.elapsedRealtime();
16186        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16187        final long curUptime = SystemClock.uptimeMillis();
16188        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16189        mLastPowerCheckRealtime = curRealtime;
16190        mLastPowerCheckUptime = curUptime;
16191        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16192            doWakeKills = false;
16193        }
16194        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16195            doCpuKills = false;
16196        }
16197        int i = mLruProcesses.size();
16198        while (i > 0) {
16199            i--;
16200            ProcessRecord app = mLruProcesses.get(i);
16201            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16202                long wtime;
16203                synchronized (stats) {
16204                    wtime = stats.getProcessWakeTime(app.info.uid,
16205                            app.pid, curRealtime);
16206                }
16207                long wtimeUsed = wtime - app.lastWakeTime;
16208                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16209                if (DEBUG_POWER) {
16210                    StringBuilder sb = new StringBuilder(128);
16211                    sb.append("Wake for ");
16212                    app.toShortString(sb);
16213                    sb.append(": over ");
16214                    TimeUtils.formatDuration(realtimeSince, sb);
16215                    sb.append(" used ");
16216                    TimeUtils.formatDuration(wtimeUsed, sb);
16217                    sb.append(" (");
16218                    sb.append((wtimeUsed*100)/realtimeSince);
16219                    sb.append("%)");
16220                    Slog.i(TAG, sb.toString());
16221                    sb.setLength(0);
16222                    sb.append("CPU for ");
16223                    app.toShortString(sb);
16224                    sb.append(": over ");
16225                    TimeUtils.formatDuration(uptimeSince, sb);
16226                    sb.append(" used ");
16227                    TimeUtils.formatDuration(cputimeUsed, sb);
16228                    sb.append(" (");
16229                    sb.append((cputimeUsed*100)/uptimeSince);
16230                    sb.append("%)");
16231                    Slog.i(TAG, sb.toString());
16232                }
16233                // If a process has held a wake lock for more
16234                // than 50% of the time during this period,
16235                // that sounds bad.  Kill!
16236                if (doWakeKills && realtimeSince > 0
16237                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16238                    synchronized (stats) {
16239                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16240                                realtimeSince, wtimeUsed);
16241                    }
16242                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16243                            + " during " + realtimeSince);
16244                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16245                } else if (doCpuKills && uptimeSince > 0
16246                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16247                    synchronized (stats) {
16248                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16249                                uptimeSince, cputimeUsed);
16250                    }
16251                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16252                            + " during " + uptimeSince);
16253                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16254                } else {
16255                    app.lastWakeTime = wtime;
16256                    app.lastCpuTime = app.curCpuTime;
16257                }
16258            }
16259        }
16260    }
16261
16262    private final boolean applyOomAdjLocked(ProcessRecord app,
16263            ProcessRecord TOP_APP, boolean doingAll, long now) {
16264        boolean success = true;
16265
16266        if (app.curRawAdj != app.setRawAdj) {
16267            app.setRawAdj = app.curRawAdj;
16268        }
16269
16270        int changes = 0;
16271
16272        if (app.curAdj != app.setAdj) {
16273            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16274            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16275                TAG, "Set " + app.pid + " " + app.processName +
16276                " adj " + app.curAdj + ": " + app.adjType);
16277            app.setAdj = app.curAdj;
16278        }
16279
16280        if (app.setSchedGroup != app.curSchedGroup) {
16281            app.setSchedGroup = app.curSchedGroup;
16282            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16283                    "Setting process group of " + app.processName
16284                    + " to " + app.curSchedGroup);
16285            if (app.waitingToKill != null &&
16286                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16287                killUnneededProcessLocked(app, app.waitingToKill);
16288                success = false;
16289            } else {
16290                if (true) {
16291                    long oldId = Binder.clearCallingIdentity();
16292                    try {
16293                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16294                    } catch (Exception e) {
16295                        Slog.w(TAG, "Failed setting process group of " + app.pid
16296                                + " to " + app.curSchedGroup);
16297                        e.printStackTrace();
16298                    } finally {
16299                        Binder.restoreCallingIdentity(oldId);
16300                    }
16301                } else {
16302                    if (app.thread != null) {
16303                        try {
16304                            app.thread.setSchedulingGroup(app.curSchedGroup);
16305                        } catch (RemoteException e) {
16306                        }
16307                    }
16308                }
16309                Process.setSwappiness(app.pid,
16310                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16311            }
16312        }
16313        if (app.repForegroundActivities != app.foregroundActivities) {
16314            app.repForegroundActivities = app.foregroundActivities;
16315            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16316        }
16317        if (app.repProcState != app.curProcState) {
16318            app.repProcState = app.curProcState;
16319            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16320            if (app.thread != null) {
16321                try {
16322                    if (false) {
16323                        //RuntimeException h = new RuntimeException("here");
16324                        Slog.i(TAG, "Sending new process state " + app.repProcState
16325                                + " to " + app /*, h*/);
16326                    }
16327                    app.thread.setProcessState(app.repProcState);
16328                } catch (RemoteException e) {
16329                }
16330            }
16331        }
16332        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16333                app.setProcState)) {
16334            app.lastStateTime = now;
16335            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16336                    isSleeping(), now);
16337            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16338                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16339                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16340                    + (app.nextPssTime-now) + ": " + app);
16341        } else {
16342            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16343                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16344                requestPssLocked(app, app.setProcState);
16345                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16346                        isSleeping(), now);
16347            } else if (false && DEBUG_PSS) {
16348                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16349            }
16350        }
16351        if (app.setProcState != app.curProcState) {
16352            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16353                    "Proc state change of " + app.processName
16354                    + " to " + app.curProcState);
16355            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16356            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16357            if (setImportant && !curImportant) {
16358                // This app is no longer something we consider important enough to allow to
16359                // use arbitrary amounts of battery power.  Note
16360                // its current wake lock time to later know to kill it if
16361                // it is not behaving well.
16362                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16363                synchronized (stats) {
16364                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16365                            app.pid, SystemClock.elapsedRealtime());
16366                }
16367                app.lastCpuTime = app.curCpuTime;
16368
16369            }
16370            app.setProcState = app.curProcState;
16371            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16372                app.notCachedSinceIdle = false;
16373            }
16374            if (!doingAll) {
16375                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16376            } else {
16377                app.procStateChanged = true;
16378            }
16379        }
16380
16381        if (changes != 0) {
16382            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16383            int i = mPendingProcessChanges.size()-1;
16384            ProcessChangeItem item = null;
16385            while (i >= 0) {
16386                item = mPendingProcessChanges.get(i);
16387                if (item.pid == app.pid) {
16388                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16389                    break;
16390                }
16391                i--;
16392            }
16393            if (i < 0) {
16394                // No existing item in pending changes; need a new one.
16395                final int NA = mAvailProcessChanges.size();
16396                if (NA > 0) {
16397                    item = mAvailProcessChanges.remove(NA-1);
16398                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16399                } else {
16400                    item = new ProcessChangeItem();
16401                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16402                }
16403                item.changes = 0;
16404                item.pid = app.pid;
16405                item.uid = app.info.uid;
16406                if (mPendingProcessChanges.size() == 0) {
16407                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16408                            "*** Enqueueing dispatch processes changed!");
16409                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16410                }
16411                mPendingProcessChanges.add(item);
16412            }
16413            item.changes |= changes;
16414            item.processState = app.repProcState;
16415            item.foregroundActivities = app.repForegroundActivities;
16416            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16417                    + Integer.toHexString(System.identityHashCode(item))
16418                    + " " + app.toShortString() + ": changes=" + item.changes
16419                    + " procState=" + item.processState
16420                    + " foreground=" + item.foregroundActivities
16421                    + " type=" + app.adjType + " source=" + app.adjSource
16422                    + " target=" + app.adjTarget);
16423        }
16424
16425        return success;
16426    }
16427
16428    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16429        if (proc.thread != null) {
16430            if (proc.baseProcessTracker != null) {
16431                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16432            }
16433            if (proc.repProcState >= 0) {
16434                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16435                        proc.repProcState);
16436            }
16437        }
16438    }
16439
16440    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16441            ProcessRecord TOP_APP, boolean doingAll, long now) {
16442        if (app.thread == null) {
16443            return false;
16444        }
16445
16446        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16447
16448        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16449    }
16450
16451    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16452            boolean oomAdj) {
16453        if (isForeground != proc.foregroundServices) {
16454            proc.foregroundServices = isForeground;
16455            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16456                    proc.info.uid);
16457            if (isForeground) {
16458                if (curProcs == null) {
16459                    curProcs = new ArrayList<ProcessRecord>();
16460                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16461                }
16462                if (!curProcs.contains(proc)) {
16463                    curProcs.add(proc);
16464                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16465                            proc.info.packageName, proc.info.uid);
16466                }
16467            } else {
16468                if (curProcs != null) {
16469                    if (curProcs.remove(proc)) {
16470                        mBatteryStatsService.noteEvent(
16471                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16472                                proc.info.packageName, proc.info.uid);
16473                        if (curProcs.size() <= 0) {
16474                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16475                        }
16476                    }
16477                }
16478            }
16479            if (oomAdj) {
16480                updateOomAdjLocked();
16481            }
16482        }
16483    }
16484
16485    private final ActivityRecord resumedAppLocked() {
16486        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16487        String pkg;
16488        int uid;
16489        if (act != null) {
16490            pkg = act.packageName;
16491            uid = act.info.applicationInfo.uid;
16492        } else {
16493            pkg = null;
16494            uid = -1;
16495        }
16496        // Has the UID or resumed package name changed?
16497        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16498                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16499            if (mCurResumedPackage != null) {
16500                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16501                        mCurResumedPackage, mCurResumedUid);
16502            }
16503            mCurResumedPackage = pkg;
16504            mCurResumedUid = uid;
16505            if (mCurResumedPackage != null) {
16506                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16507                        mCurResumedPackage, mCurResumedUid);
16508            }
16509        }
16510        return act;
16511    }
16512
16513    final boolean updateOomAdjLocked(ProcessRecord app) {
16514        final ActivityRecord TOP_ACT = resumedAppLocked();
16515        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16516        final boolean wasCached = app.cached;
16517
16518        mAdjSeq++;
16519
16520        // This is the desired cached adjusment we want to tell it to use.
16521        // If our app is currently cached, we know it, and that is it.  Otherwise,
16522        // we don't know it yet, and it needs to now be cached we will then
16523        // need to do a complete oom adj.
16524        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16525                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16526        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16527                SystemClock.uptimeMillis());
16528        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16529            // Changed to/from cached state, so apps after it in the LRU
16530            // list may also be changed.
16531            updateOomAdjLocked();
16532        }
16533        return success;
16534    }
16535
16536    final void updateOomAdjLocked() {
16537        final ActivityRecord TOP_ACT = resumedAppLocked();
16538        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16539        final long now = SystemClock.uptimeMillis();
16540        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16541        final int N = mLruProcesses.size();
16542
16543        if (false) {
16544            RuntimeException e = new RuntimeException();
16545            e.fillInStackTrace();
16546            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16547        }
16548
16549        mAdjSeq++;
16550        mNewNumServiceProcs = 0;
16551        mNewNumAServiceProcs = 0;
16552
16553        final int emptyProcessLimit;
16554        final int cachedProcessLimit;
16555        if (mProcessLimit <= 0) {
16556            emptyProcessLimit = cachedProcessLimit = 0;
16557        } else if (mProcessLimit == 1) {
16558            emptyProcessLimit = 1;
16559            cachedProcessLimit = 0;
16560        } else {
16561            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16562            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16563        }
16564
16565        // Let's determine how many processes we have running vs.
16566        // how many slots we have for background processes; we may want
16567        // to put multiple processes in a slot of there are enough of
16568        // them.
16569        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16570                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16571        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16572        if (numEmptyProcs > cachedProcessLimit) {
16573            // If there are more empty processes than our limit on cached
16574            // processes, then use the cached process limit for the factor.
16575            // This ensures that the really old empty processes get pushed
16576            // down to the bottom, so if we are running low on memory we will
16577            // have a better chance at keeping around more cached processes
16578            // instead of a gazillion empty processes.
16579            numEmptyProcs = cachedProcessLimit;
16580        }
16581        int emptyFactor = numEmptyProcs/numSlots;
16582        if (emptyFactor < 1) emptyFactor = 1;
16583        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16584        if (cachedFactor < 1) cachedFactor = 1;
16585        int stepCached = 0;
16586        int stepEmpty = 0;
16587        int numCached = 0;
16588        int numEmpty = 0;
16589        int numTrimming = 0;
16590
16591        mNumNonCachedProcs = 0;
16592        mNumCachedHiddenProcs = 0;
16593
16594        // First update the OOM adjustment for each of the
16595        // application processes based on their current state.
16596        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16597        int nextCachedAdj = curCachedAdj+1;
16598        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16599        int nextEmptyAdj = curEmptyAdj+2;
16600        for (int i=N-1; i>=0; i--) {
16601            ProcessRecord app = mLruProcesses.get(i);
16602            if (!app.killedByAm && app.thread != null) {
16603                app.procStateChanged = false;
16604                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16605
16606                // If we haven't yet assigned the final cached adj
16607                // to the process, do that now.
16608                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16609                    switch (app.curProcState) {
16610                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16611                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16612                            // This process is a cached process holding activities...
16613                            // assign it the next cached value for that type, and then
16614                            // step that cached level.
16615                            app.curRawAdj = curCachedAdj;
16616                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16617                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16618                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16619                                    + ")");
16620                            if (curCachedAdj != nextCachedAdj) {
16621                                stepCached++;
16622                                if (stepCached >= cachedFactor) {
16623                                    stepCached = 0;
16624                                    curCachedAdj = nextCachedAdj;
16625                                    nextCachedAdj += 2;
16626                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16627                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16628                                    }
16629                                }
16630                            }
16631                            break;
16632                        default:
16633                            // For everything else, assign next empty cached process
16634                            // level and bump that up.  Note that this means that
16635                            // long-running services that have dropped down to the
16636                            // cached level will be treated as empty (since their process
16637                            // state is still as a service), which is what we want.
16638                            app.curRawAdj = curEmptyAdj;
16639                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16640                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16641                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16642                                    + ")");
16643                            if (curEmptyAdj != nextEmptyAdj) {
16644                                stepEmpty++;
16645                                if (stepEmpty >= emptyFactor) {
16646                                    stepEmpty = 0;
16647                                    curEmptyAdj = nextEmptyAdj;
16648                                    nextEmptyAdj += 2;
16649                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16650                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16651                                    }
16652                                }
16653                            }
16654                            break;
16655                    }
16656                }
16657
16658                applyOomAdjLocked(app, TOP_APP, true, now);
16659
16660                // Count the number of process types.
16661                switch (app.curProcState) {
16662                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16663                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16664                        mNumCachedHiddenProcs++;
16665                        numCached++;
16666                        if (numCached > cachedProcessLimit) {
16667                            killUnneededProcessLocked(app, "cached #" + numCached);
16668                        }
16669                        break;
16670                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16671                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16672                                && app.lastActivityTime < oldTime) {
16673                            killUnneededProcessLocked(app, "empty for "
16674                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16675                                    / 1000) + "s");
16676                        } else {
16677                            numEmpty++;
16678                            if (numEmpty > emptyProcessLimit) {
16679                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16680                            }
16681                        }
16682                        break;
16683                    default:
16684                        mNumNonCachedProcs++;
16685                        break;
16686                }
16687
16688                if (app.isolated && app.services.size() <= 0) {
16689                    // If this is an isolated process, and there are no
16690                    // services running in it, then the process is no longer
16691                    // needed.  We agressively kill these because we can by
16692                    // definition not re-use the same process again, and it is
16693                    // good to avoid having whatever code was running in them
16694                    // left sitting around after no longer needed.
16695                    killUnneededProcessLocked(app, "isolated not needed");
16696                }
16697
16698                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16699                        && !app.killedByAm) {
16700                    numTrimming++;
16701                }
16702            }
16703        }
16704
16705        mNumServiceProcs = mNewNumServiceProcs;
16706
16707        // Now determine the memory trimming level of background processes.
16708        // Unfortunately we need to start at the back of the list to do this
16709        // properly.  We only do this if the number of background apps we
16710        // are managing to keep around is less than half the maximum we desire;
16711        // if we are keeping a good number around, we'll let them use whatever
16712        // memory they want.
16713        final int numCachedAndEmpty = numCached + numEmpty;
16714        int memFactor;
16715        if (numCached <= ProcessList.TRIM_CACHED_APPS
16716                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16717            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16718                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16719            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16720                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16721            } else {
16722                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16723            }
16724        } else {
16725            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16726        }
16727        // We always allow the memory level to go up (better).  We only allow it to go
16728        // down if we are in a state where that is allowed, *and* the total number of processes
16729        // has gone down since last time.
16730        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16731                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16732                + " last=" + mLastNumProcesses);
16733        if (memFactor > mLastMemoryLevel) {
16734            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16735                memFactor = mLastMemoryLevel;
16736                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16737            }
16738        }
16739        mLastMemoryLevel = memFactor;
16740        mLastNumProcesses = mLruProcesses.size();
16741        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16742        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16743        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16744            if (mLowRamStartTime == 0) {
16745                mLowRamStartTime = now;
16746            }
16747            int step = 0;
16748            int fgTrimLevel;
16749            switch (memFactor) {
16750                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16751                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16752                    break;
16753                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16754                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16755                    break;
16756                default:
16757                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16758                    break;
16759            }
16760            int factor = numTrimming/3;
16761            int minFactor = 2;
16762            if (mHomeProcess != null) minFactor++;
16763            if (mPreviousProcess != null) minFactor++;
16764            if (factor < minFactor) factor = minFactor;
16765            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16766            for (int i=N-1; i>=0; i--) {
16767                ProcessRecord app = mLruProcesses.get(i);
16768                if (allChanged || app.procStateChanged) {
16769                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16770                    app.procStateChanged = false;
16771                }
16772                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16773                        && !app.killedByAm) {
16774                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16775                        try {
16776                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16777                                    "Trimming memory of " + app.processName
16778                                    + " to " + curLevel);
16779                            app.thread.scheduleTrimMemory(curLevel);
16780                        } catch (RemoteException e) {
16781                        }
16782                        if (false) {
16783                            // For now we won't do this; our memory trimming seems
16784                            // to be good enough at this point that destroying
16785                            // activities causes more harm than good.
16786                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16787                                    && app != mHomeProcess && app != mPreviousProcess) {
16788                                // Need to do this on its own message because the stack may not
16789                                // be in a consistent state at this point.
16790                                // For these apps we will also finish their activities
16791                                // to help them free memory.
16792                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16793                            }
16794                        }
16795                    }
16796                    app.trimMemoryLevel = curLevel;
16797                    step++;
16798                    if (step >= factor) {
16799                        step = 0;
16800                        switch (curLevel) {
16801                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16802                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16803                                break;
16804                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16805                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16806                                break;
16807                        }
16808                    }
16809                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16810                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16811                            && app.thread != null) {
16812                        try {
16813                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16814                                    "Trimming memory of heavy-weight " + app.processName
16815                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16816                            app.thread.scheduleTrimMemory(
16817                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16818                        } catch (RemoteException e) {
16819                        }
16820                    }
16821                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16822                } else {
16823                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16824                            || app.systemNoUi) && app.pendingUiClean) {
16825                        // If this application is now in the background and it
16826                        // had done UI, then give it the special trim level to
16827                        // have it free UI resources.
16828                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16829                        if (app.trimMemoryLevel < level && app.thread != null) {
16830                            try {
16831                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16832                                        "Trimming memory of bg-ui " + app.processName
16833                                        + " to " + level);
16834                                app.thread.scheduleTrimMemory(level);
16835                            } catch (RemoteException e) {
16836                            }
16837                        }
16838                        app.pendingUiClean = false;
16839                    }
16840                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16841                        try {
16842                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16843                                    "Trimming memory of fg " + app.processName
16844                                    + " to " + fgTrimLevel);
16845                            app.thread.scheduleTrimMemory(fgTrimLevel);
16846                        } catch (RemoteException e) {
16847                        }
16848                    }
16849                    app.trimMemoryLevel = fgTrimLevel;
16850                }
16851            }
16852        } else {
16853            if (mLowRamStartTime != 0) {
16854                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16855                mLowRamStartTime = 0;
16856            }
16857            for (int i=N-1; i>=0; i--) {
16858                ProcessRecord app = mLruProcesses.get(i);
16859                if (allChanged || app.procStateChanged) {
16860                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16861                    app.procStateChanged = false;
16862                }
16863                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16864                        || app.systemNoUi) && app.pendingUiClean) {
16865                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16866                            && app.thread != null) {
16867                        try {
16868                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16869                                    "Trimming memory of ui hidden " + app.processName
16870                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16871                            app.thread.scheduleTrimMemory(
16872                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16873                        } catch (RemoteException e) {
16874                        }
16875                    }
16876                    app.pendingUiClean = false;
16877                }
16878                app.trimMemoryLevel = 0;
16879            }
16880        }
16881
16882        if (mAlwaysFinishActivities) {
16883            // Need to do this on its own message because the stack may not
16884            // be in a consistent state at this point.
16885            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16886        }
16887
16888        if (allChanged) {
16889            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16890        }
16891
16892        if (mProcessStats.shouldWriteNowLocked(now)) {
16893            mHandler.post(new Runnable() {
16894                @Override public void run() {
16895                    synchronized (ActivityManagerService.this) {
16896                        mProcessStats.writeStateAsyncLocked();
16897                    }
16898                }
16899            });
16900        }
16901
16902        if (DEBUG_OOM_ADJ) {
16903            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16904        }
16905    }
16906
16907    final void trimApplications() {
16908        synchronized (this) {
16909            int i;
16910
16911            // First remove any unused application processes whose package
16912            // has been removed.
16913            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16914                final ProcessRecord app = mRemovedProcesses.get(i);
16915                if (app.activities.size() == 0
16916                        && app.curReceiver == null && app.services.size() == 0) {
16917                    Slog.i(
16918                        TAG, "Exiting empty application process "
16919                        + app.processName + " ("
16920                        + (app.thread != null ? app.thread.asBinder() : null)
16921                        + ")\n");
16922                    if (app.pid > 0 && app.pid != MY_PID) {
16923                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16924                                app.processName, app.setAdj, "empty");
16925                        app.killedByAm = true;
16926                        Process.killProcessQuiet(app.pid);
16927                        Process.killProcessGroup(app.info.uid, app.pid);
16928                    } else {
16929                        try {
16930                            app.thread.scheduleExit();
16931                        } catch (Exception e) {
16932                            // Ignore exceptions.
16933                        }
16934                    }
16935                    cleanUpApplicationRecordLocked(app, false, true, -1);
16936                    mRemovedProcesses.remove(i);
16937
16938                    if (app.persistent) {
16939                        addAppLocked(app.info, false, null /* ABI override */);
16940                    }
16941                }
16942            }
16943
16944            // Now update the oom adj for all processes.
16945            updateOomAdjLocked();
16946        }
16947    }
16948
16949    /** This method sends the specified signal to each of the persistent apps */
16950    public void signalPersistentProcesses(int sig) throws RemoteException {
16951        if (sig != Process.SIGNAL_USR1) {
16952            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16953        }
16954
16955        synchronized (this) {
16956            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16957                    != PackageManager.PERMISSION_GRANTED) {
16958                throw new SecurityException("Requires permission "
16959                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16960            }
16961
16962            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16963                ProcessRecord r = mLruProcesses.get(i);
16964                if (r.thread != null && r.persistent) {
16965                    Process.sendSignal(r.pid, sig);
16966                }
16967            }
16968        }
16969    }
16970
16971    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16972        if (proc == null || proc == mProfileProc) {
16973            proc = mProfileProc;
16974            path = mProfileFile;
16975            profileType = mProfileType;
16976            clearProfilerLocked();
16977        }
16978        if (proc == null) {
16979            return;
16980        }
16981        try {
16982            proc.thread.profilerControl(false, path, null, profileType);
16983        } catch (RemoteException e) {
16984            throw new IllegalStateException("Process disappeared");
16985        }
16986    }
16987
16988    private void clearProfilerLocked() {
16989        if (mProfileFd != null) {
16990            try {
16991                mProfileFd.close();
16992            } catch (IOException e) {
16993            }
16994        }
16995        mProfileApp = null;
16996        mProfileProc = null;
16997        mProfileFile = null;
16998        mProfileType = 0;
16999        mAutoStopProfiler = false;
17000    }
17001
17002    public boolean profileControl(String process, int userId, boolean start,
17003            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
17004
17005        try {
17006            synchronized (this) {
17007                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17008                // its own permission.
17009                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17010                        != PackageManager.PERMISSION_GRANTED) {
17011                    throw new SecurityException("Requires permission "
17012                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17013                }
17014
17015                if (start && fd == null) {
17016                    throw new IllegalArgumentException("null fd");
17017                }
17018
17019                ProcessRecord proc = null;
17020                if (process != null) {
17021                    proc = findProcessLocked(process, userId, "profileControl");
17022                }
17023
17024                if (start && (proc == null || proc.thread == null)) {
17025                    throw new IllegalArgumentException("Unknown process: " + process);
17026                }
17027
17028                if (start) {
17029                    stopProfilerLocked(null, null, 0);
17030                    setProfileApp(proc.info, proc.processName, path, fd, false);
17031                    mProfileProc = proc;
17032                    mProfileType = profileType;
17033                    try {
17034                        fd = fd.dup();
17035                    } catch (IOException e) {
17036                        fd = null;
17037                    }
17038                    proc.thread.profilerControl(start, path, fd, profileType);
17039                    fd = null;
17040                    mProfileFd = null;
17041                } else {
17042                    stopProfilerLocked(proc, path, profileType);
17043                    if (fd != null) {
17044                        try {
17045                            fd.close();
17046                        } catch (IOException e) {
17047                        }
17048                    }
17049                }
17050
17051                return true;
17052            }
17053        } catch (RemoteException e) {
17054            throw new IllegalStateException("Process disappeared");
17055        } finally {
17056            if (fd != null) {
17057                try {
17058                    fd.close();
17059                } catch (IOException e) {
17060                }
17061            }
17062        }
17063    }
17064
17065    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17066        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17067                userId, true, ALLOW_FULL_ONLY, callName, null);
17068        ProcessRecord proc = null;
17069        try {
17070            int pid = Integer.parseInt(process);
17071            synchronized (mPidsSelfLocked) {
17072                proc = mPidsSelfLocked.get(pid);
17073            }
17074        } catch (NumberFormatException e) {
17075        }
17076
17077        if (proc == null) {
17078            ArrayMap<String, SparseArray<ProcessRecord>> all
17079                    = mProcessNames.getMap();
17080            SparseArray<ProcessRecord> procs = all.get(process);
17081            if (procs != null && procs.size() > 0) {
17082                proc = procs.valueAt(0);
17083                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17084                    for (int i=1; i<procs.size(); i++) {
17085                        ProcessRecord thisProc = procs.valueAt(i);
17086                        if (thisProc.userId == userId) {
17087                            proc = thisProc;
17088                            break;
17089                        }
17090                    }
17091                }
17092            }
17093        }
17094
17095        return proc;
17096    }
17097
17098    public boolean dumpHeap(String process, int userId, boolean managed,
17099            String path, ParcelFileDescriptor fd) throws RemoteException {
17100
17101        try {
17102            synchronized (this) {
17103                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17104                // its own permission (same as profileControl).
17105                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17106                        != PackageManager.PERMISSION_GRANTED) {
17107                    throw new SecurityException("Requires permission "
17108                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17109                }
17110
17111                if (fd == null) {
17112                    throw new IllegalArgumentException("null fd");
17113                }
17114
17115                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17116                if (proc == null || proc.thread == null) {
17117                    throw new IllegalArgumentException("Unknown process: " + process);
17118                }
17119
17120                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17121                if (!isDebuggable) {
17122                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17123                        throw new SecurityException("Process not debuggable: " + proc);
17124                    }
17125                }
17126
17127                proc.thread.dumpHeap(managed, path, fd);
17128                fd = null;
17129                return true;
17130            }
17131        } catch (RemoteException e) {
17132            throw new IllegalStateException("Process disappeared");
17133        } finally {
17134            if (fd != null) {
17135                try {
17136                    fd.close();
17137                } catch (IOException e) {
17138                }
17139            }
17140        }
17141    }
17142
17143    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17144    public void monitor() {
17145        synchronized (this) { }
17146    }
17147
17148    void onCoreSettingsChange(Bundle settings) {
17149        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17150            ProcessRecord processRecord = mLruProcesses.get(i);
17151            try {
17152                if (processRecord.thread != null) {
17153                    processRecord.thread.setCoreSettings(settings);
17154                }
17155            } catch (RemoteException re) {
17156                /* ignore */
17157            }
17158        }
17159    }
17160
17161    // Multi-user methods
17162
17163    /**
17164     * Start user, if its not already running, but don't bring it to foreground.
17165     */
17166    @Override
17167    public boolean startUserInBackground(final int userId) {
17168        return startUser(userId, /* foreground */ false);
17169    }
17170
17171    /**
17172     * Refreshes the list of users related to the current user when either a
17173     * user switch happens or when a new related user is started in the
17174     * background.
17175     */
17176    private void updateCurrentProfileIdsLocked() {
17177        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17178                mCurrentUserId, false /* enabledOnly */);
17179        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17180        for (int i = 0; i < currentProfileIds.length; i++) {
17181            currentProfileIds[i] = profiles.get(i).id;
17182        }
17183        mCurrentProfileIds = currentProfileIds;
17184
17185        synchronized (mUserProfileGroupIdsSelfLocked) {
17186            mUserProfileGroupIdsSelfLocked.clear();
17187            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17188            for (int i = 0; i < users.size(); i++) {
17189                UserInfo user = users.get(i);
17190                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17191                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17192                }
17193            }
17194        }
17195    }
17196
17197    private Set getProfileIdsLocked(int userId) {
17198        Set userIds = new HashSet<Integer>();
17199        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17200                userId, false /* enabledOnly */);
17201        for (UserInfo user : profiles) {
17202            userIds.add(Integer.valueOf(user.id));
17203        }
17204        return userIds;
17205    }
17206
17207    @Override
17208    public boolean switchUser(final int userId) {
17209        return startUser(userId, /* foregound */ true);
17210    }
17211
17212    private boolean startUser(final int userId, boolean foreground) {
17213        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17214                != PackageManager.PERMISSION_GRANTED) {
17215            String msg = "Permission Denial: switchUser() from pid="
17216                    + Binder.getCallingPid()
17217                    + ", uid=" + Binder.getCallingUid()
17218                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17219            Slog.w(TAG, msg);
17220            throw new SecurityException(msg);
17221        }
17222
17223        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17224
17225        final long ident = Binder.clearCallingIdentity();
17226        try {
17227            synchronized (this) {
17228                final int oldUserId = mCurrentUserId;
17229                if (oldUserId == userId) {
17230                    return true;
17231                }
17232
17233                mStackSupervisor.setLockTaskModeLocked(null, false);
17234
17235                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17236                if (userInfo == null) {
17237                    Slog.w(TAG, "No user info for user #" + userId);
17238                    return false;
17239                }
17240
17241                if (foreground) {
17242                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17243                            R.anim.screen_user_enter);
17244                }
17245
17246                boolean needStart = false;
17247
17248                // If the user we are switching to is not currently started, then
17249                // we need to start it now.
17250                if (mStartedUsers.get(userId) == null) {
17251                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17252                    updateStartedUserArrayLocked();
17253                    needStart = true;
17254                }
17255
17256                final Integer userIdInt = Integer.valueOf(userId);
17257                mUserLru.remove(userIdInt);
17258                mUserLru.add(userIdInt);
17259
17260                if (foreground) {
17261                    mCurrentUserId = userId;
17262                    updateCurrentProfileIdsLocked();
17263                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17264                    // Once the internal notion of the active user has switched, we lock the device
17265                    // with the option to show the user switcher on the keyguard.
17266                    mWindowManager.lockNow(null);
17267                } else {
17268                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17269                    updateCurrentProfileIdsLocked();
17270                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17271                    mUserLru.remove(currentUserIdInt);
17272                    mUserLru.add(currentUserIdInt);
17273                }
17274
17275                final UserStartedState uss = mStartedUsers.get(userId);
17276
17277                // Make sure user is in the started state.  If it is currently
17278                // stopping, we need to knock that off.
17279                if (uss.mState == UserStartedState.STATE_STOPPING) {
17280                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17281                    // so we can just fairly silently bring the user back from
17282                    // the almost-dead.
17283                    uss.mState = UserStartedState.STATE_RUNNING;
17284                    updateStartedUserArrayLocked();
17285                    needStart = true;
17286                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17287                    // This means ACTION_SHUTDOWN has been sent, so we will
17288                    // need to treat this as a new boot of the user.
17289                    uss.mState = UserStartedState.STATE_BOOTING;
17290                    updateStartedUserArrayLocked();
17291                    needStart = true;
17292                }
17293
17294                if (uss.mState == UserStartedState.STATE_BOOTING) {
17295                    // Booting up a new user, need to tell system services about it.
17296                    // Note that this is on the same handler as scheduling of broadcasts,
17297                    // which is important because it needs to go first.
17298                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
17299                }
17300
17301                if (foreground) {
17302                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17303                            oldUserId));
17304                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17305                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17306                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17307                            oldUserId, userId, uss));
17308                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17309                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17310                }
17311
17312                if (needStart) {
17313                    // Send USER_STARTED broadcast
17314                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17315                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17316                            | Intent.FLAG_RECEIVER_FOREGROUND);
17317                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17318                    broadcastIntentLocked(null, null, intent,
17319                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17320                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17321                }
17322
17323                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17324                    if (userId != UserHandle.USER_OWNER) {
17325                        // Send PRE_BOOT_COMPLETED broadcasts for this new user
17326                        final ArrayList<ComponentName> doneReceivers
17327                                = new ArrayList<ComponentName>();
17328                        deliverPreBootCompleted(null, doneReceivers, userId);
17329
17330                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17331                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17332                        broadcastIntentLocked(null, null, intent, null,
17333                                new IIntentReceiver.Stub() {
17334                                    public void performReceive(Intent intent, int resultCode,
17335                                            String data, Bundle extras, boolean ordered,
17336                                            boolean sticky, int sendingUser) {
17337                                        userInitialized(uss, userId);
17338                                    }
17339                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17340                                true, false, MY_PID, Process.SYSTEM_UID,
17341                                userId);
17342                        uss.initializing = true;
17343                    } else {
17344                        getUserManagerLocked().makeInitialized(userInfo.id);
17345                    }
17346                }
17347
17348                if (foreground) {
17349                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17350                    if (homeInFront) {
17351                        startHomeActivityLocked(userId);
17352                    } else {
17353                        mStackSupervisor.resumeTopActivitiesLocked();
17354                    }
17355                    EventLogTags.writeAmSwitchUser(userId);
17356                    getUserManagerLocked().userForeground(userId);
17357                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17358                } else {
17359                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17360                }
17361
17362                if (needStart) {
17363                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17364                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17365                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17366                    broadcastIntentLocked(null, null, intent,
17367                            null, new IIntentReceiver.Stub() {
17368                                @Override
17369                                public void performReceive(Intent intent, int resultCode, String data,
17370                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17371                                        throws RemoteException {
17372                                }
17373                            }, 0, null, null,
17374                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17375                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17376                }
17377            }
17378        } finally {
17379            Binder.restoreCallingIdentity(ident);
17380        }
17381
17382        return true;
17383    }
17384
17385    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17386        long ident = Binder.clearCallingIdentity();
17387        try {
17388            Intent intent;
17389            if (oldUserId >= 0) {
17390                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17391                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17392                int count = profiles.size();
17393                for (int i = 0; i < count; i++) {
17394                    int profileUserId = profiles.get(i).id;
17395                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17396                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17397                            | Intent.FLAG_RECEIVER_FOREGROUND);
17398                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17399                    broadcastIntentLocked(null, null, intent,
17400                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17401                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17402                }
17403            }
17404            if (newUserId >= 0) {
17405                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17406                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17407                int count = profiles.size();
17408                for (int i = 0; i < count; i++) {
17409                    int profileUserId = profiles.get(i).id;
17410                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17411                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17412                            | Intent.FLAG_RECEIVER_FOREGROUND);
17413                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17414                    broadcastIntentLocked(null, null, intent,
17415                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17416                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17417                }
17418                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17419                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17420                        | Intent.FLAG_RECEIVER_FOREGROUND);
17421                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17422                broadcastIntentLocked(null, null, intent,
17423                        null, null, 0, null, null,
17424                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17425                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17426            }
17427        } finally {
17428            Binder.restoreCallingIdentity(ident);
17429        }
17430    }
17431
17432    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17433            final int newUserId) {
17434        final int N = mUserSwitchObservers.beginBroadcast();
17435        if (N > 0) {
17436            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17437                int mCount = 0;
17438                @Override
17439                public void sendResult(Bundle data) throws RemoteException {
17440                    synchronized (ActivityManagerService.this) {
17441                        if (mCurUserSwitchCallback == this) {
17442                            mCount++;
17443                            if (mCount == N) {
17444                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17445                            }
17446                        }
17447                    }
17448                }
17449            };
17450            synchronized (this) {
17451                uss.switching = true;
17452                mCurUserSwitchCallback = callback;
17453            }
17454            for (int i=0; i<N; i++) {
17455                try {
17456                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17457                            newUserId, callback);
17458                } catch (RemoteException e) {
17459                }
17460            }
17461        } else {
17462            synchronized (this) {
17463                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17464            }
17465        }
17466        mUserSwitchObservers.finishBroadcast();
17467    }
17468
17469    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17470        synchronized (this) {
17471            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17472            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17473        }
17474    }
17475
17476    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17477        mCurUserSwitchCallback = null;
17478        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17479        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17480                oldUserId, newUserId, uss));
17481    }
17482
17483    void userInitialized(UserStartedState uss, int newUserId) {
17484        completeSwitchAndInitalize(uss, newUserId, true, false);
17485    }
17486
17487    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17488        completeSwitchAndInitalize(uss, newUserId, false, true);
17489    }
17490
17491    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17492            boolean clearInitializing, boolean clearSwitching) {
17493        boolean unfrozen = false;
17494        synchronized (this) {
17495            if (clearInitializing) {
17496                uss.initializing = false;
17497                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17498            }
17499            if (clearSwitching) {
17500                uss.switching = false;
17501            }
17502            if (!uss.switching && !uss.initializing) {
17503                mWindowManager.stopFreezingScreen();
17504                unfrozen = true;
17505            }
17506        }
17507        if (unfrozen) {
17508            final int N = mUserSwitchObservers.beginBroadcast();
17509            for (int i=0; i<N; i++) {
17510                try {
17511                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17512                } catch (RemoteException e) {
17513                }
17514            }
17515            mUserSwitchObservers.finishBroadcast();
17516        }
17517    }
17518
17519    void scheduleStartProfilesLocked() {
17520        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17521            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17522                    DateUtils.SECOND_IN_MILLIS);
17523        }
17524    }
17525
17526    void startProfilesLocked() {
17527        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17528        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17529                mCurrentUserId, false /* enabledOnly */);
17530        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17531        for (UserInfo user : profiles) {
17532            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17533                    && user.id != mCurrentUserId) {
17534                toStart.add(user);
17535            }
17536        }
17537        final int n = toStart.size();
17538        int i = 0;
17539        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17540            startUserInBackground(toStart.get(i).id);
17541        }
17542        if (i < n) {
17543            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17544        }
17545    }
17546
17547    void finishUserBoot(UserStartedState uss) {
17548        synchronized (this) {
17549            if (uss.mState == UserStartedState.STATE_BOOTING
17550                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17551                uss.mState = UserStartedState.STATE_RUNNING;
17552                final int userId = uss.mHandle.getIdentifier();
17553                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17554                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17555                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17556                broadcastIntentLocked(null, null, intent,
17557                        null, null, 0, null, null,
17558                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17559                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17560            }
17561        }
17562    }
17563
17564    void finishUserSwitch(UserStartedState uss) {
17565        synchronized (this) {
17566            finishUserBoot(uss);
17567
17568            startProfilesLocked();
17569
17570            int num = mUserLru.size();
17571            int i = 0;
17572            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17573                Integer oldUserId = mUserLru.get(i);
17574                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17575                if (oldUss == null) {
17576                    // Shouldn't happen, but be sane if it does.
17577                    mUserLru.remove(i);
17578                    num--;
17579                    continue;
17580                }
17581                if (oldUss.mState == UserStartedState.STATE_STOPPING
17582                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17583                    // This user is already stopping, doesn't count.
17584                    num--;
17585                    i++;
17586                    continue;
17587                }
17588                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17589                    // Owner and current can't be stopped, but count as running.
17590                    i++;
17591                    continue;
17592                }
17593                // This is a user to be stopped.
17594                stopUserLocked(oldUserId, null);
17595                num--;
17596                i++;
17597            }
17598        }
17599    }
17600
17601    @Override
17602    public int stopUser(final int userId, final IStopUserCallback callback) {
17603        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17604                != PackageManager.PERMISSION_GRANTED) {
17605            String msg = "Permission Denial: switchUser() from pid="
17606                    + Binder.getCallingPid()
17607                    + ", uid=" + Binder.getCallingUid()
17608                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17609            Slog.w(TAG, msg);
17610            throw new SecurityException(msg);
17611        }
17612        if (userId <= 0) {
17613            throw new IllegalArgumentException("Can't stop primary user " + userId);
17614        }
17615        synchronized (this) {
17616            return stopUserLocked(userId, callback);
17617        }
17618    }
17619
17620    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17621        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17622        if (mCurrentUserId == userId) {
17623            return ActivityManager.USER_OP_IS_CURRENT;
17624        }
17625
17626        final UserStartedState uss = mStartedUsers.get(userId);
17627        if (uss == null) {
17628            // User is not started, nothing to do...  but we do need to
17629            // callback if requested.
17630            if (callback != null) {
17631                mHandler.post(new Runnable() {
17632                    @Override
17633                    public void run() {
17634                        try {
17635                            callback.userStopped(userId);
17636                        } catch (RemoteException e) {
17637                        }
17638                    }
17639                });
17640            }
17641            return ActivityManager.USER_OP_SUCCESS;
17642        }
17643
17644        if (callback != null) {
17645            uss.mStopCallbacks.add(callback);
17646        }
17647
17648        if (uss.mState != UserStartedState.STATE_STOPPING
17649                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17650            uss.mState = UserStartedState.STATE_STOPPING;
17651            updateStartedUserArrayLocked();
17652
17653            long ident = Binder.clearCallingIdentity();
17654            try {
17655                // We are going to broadcast ACTION_USER_STOPPING and then
17656                // once that is done send a final ACTION_SHUTDOWN and then
17657                // stop the user.
17658                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17659                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17660                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17661                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17662                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17663                // This is the result receiver for the final shutdown broadcast.
17664                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17665                    @Override
17666                    public void performReceive(Intent intent, int resultCode, String data,
17667                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17668                        finishUserStop(uss);
17669                    }
17670                };
17671                // This is the result receiver for the initial stopping broadcast.
17672                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17673                    @Override
17674                    public void performReceive(Intent intent, int resultCode, String data,
17675                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17676                        // On to the next.
17677                        synchronized (ActivityManagerService.this) {
17678                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17679                                // Whoops, we are being started back up.  Abort, abort!
17680                                return;
17681                            }
17682                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17683                        }
17684                        mBatteryStatsService.noteEvent(
17685                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17686                                Integer.toString(userId), userId);
17687                        mSystemServiceManager.stopUser(userId);
17688                        broadcastIntentLocked(null, null, shutdownIntent,
17689                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17690                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17691                    }
17692                };
17693                // Kick things off.
17694                broadcastIntentLocked(null, null, stoppingIntent,
17695                        null, stoppingReceiver, 0, null, null,
17696                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17697                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17698            } finally {
17699                Binder.restoreCallingIdentity(ident);
17700            }
17701        }
17702
17703        return ActivityManager.USER_OP_SUCCESS;
17704    }
17705
17706    void finishUserStop(UserStartedState uss) {
17707        final int userId = uss.mHandle.getIdentifier();
17708        boolean stopped;
17709        ArrayList<IStopUserCallback> callbacks;
17710        synchronized (this) {
17711            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17712            if (mStartedUsers.get(userId) != uss) {
17713                stopped = false;
17714            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17715                stopped = false;
17716            } else {
17717                stopped = true;
17718                // User can no longer run.
17719                mStartedUsers.remove(userId);
17720                mUserLru.remove(Integer.valueOf(userId));
17721                updateStartedUserArrayLocked();
17722
17723                // Clean up all state and processes associated with the user.
17724                // Kill all the processes for the user.
17725                forceStopUserLocked(userId, "finish user");
17726            }
17727        }
17728
17729        // Explicitly remove the old information in mRecentTasks.
17730        removeRecentTasksForUser(userId);
17731
17732        for (int i=0; i<callbacks.size(); i++) {
17733            try {
17734                if (stopped) callbacks.get(i).userStopped(userId);
17735                else callbacks.get(i).userStopAborted(userId);
17736            } catch (RemoteException e) {
17737            }
17738        }
17739
17740        if (stopped) {
17741            mSystemServiceManager.cleanupUser(userId);
17742            synchronized (this) {
17743                mStackSupervisor.removeUserLocked(userId);
17744            }
17745        }
17746    }
17747
17748    @Override
17749    public UserInfo getCurrentUser() {
17750        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17751                != PackageManager.PERMISSION_GRANTED) && (
17752                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17753                != PackageManager.PERMISSION_GRANTED)) {
17754            String msg = "Permission Denial: getCurrentUser() from pid="
17755                    + Binder.getCallingPid()
17756                    + ", uid=" + Binder.getCallingUid()
17757                    + " requires " + INTERACT_ACROSS_USERS;
17758            Slog.w(TAG, msg);
17759            throw new SecurityException(msg);
17760        }
17761        synchronized (this) {
17762            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17763        }
17764    }
17765
17766    int getCurrentUserIdLocked() {
17767        return mCurrentUserId;
17768    }
17769
17770    @Override
17771    public boolean isUserRunning(int userId, boolean orStopped) {
17772        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17773                != PackageManager.PERMISSION_GRANTED) {
17774            String msg = "Permission Denial: isUserRunning() from pid="
17775                    + Binder.getCallingPid()
17776                    + ", uid=" + Binder.getCallingUid()
17777                    + " requires " + INTERACT_ACROSS_USERS;
17778            Slog.w(TAG, msg);
17779            throw new SecurityException(msg);
17780        }
17781        synchronized (this) {
17782            return isUserRunningLocked(userId, orStopped);
17783        }
17784    }
17785
17786    boolean isUserRunningLocked(int userId, boolean orStopped) {
17787        UserStartedState state = mStartedUsers.get(userId);
17788        if (state == null) {
17789            return false;
17790        }
17791        if (orStopped) {
17792            return true;
17793        }
17794        return state.mState != UserStartedState.STATE_STOPPING
17795                && state.mState != UserStartedState.STATE_SHUTDOWN;
17796    }
17797
17798    @Override
17799    public int[] getRunningUserIds() {
17800        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17801                != PackageManager.PERMISSION_GRANTED) {
17802            String msg = "Permission Denial: isUserRunning() from pid="
17803                    + Binder.getCallingPid()
17804                    + ", uid=" + Binder.getCallingUid()
17805                    + " requires " + INTERACT_ACROSS_USERS;
17806            Slog.w(TAG, msg);
17807            throw new SecurityException(msg);
17808        }
17809        synchronized (this) {
17810            return mStartedUserArray;
17811        }
17812    }
17813
17814    private void updateStartedUserArrayLocked() {
17815        int num = 0;
17816        for (int i=0; i<mStartedUsers.size();  i++) {
17817            UserStartedState uss = mStartedUsers.valueAt(i);
17818            // This list does not include stopping users.
17819            if (uss.mState != UserStartedState.STATE_STOPPING
17820                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17821                num++;
17822            }
17823        }
17824        mStartedUserArray = new int[num];
17825        num = 0;
17826        for (int i=0; i<mStartedUsers.size();  i++) {
17827            UserStartedState uss = mStartedUsers.valueAt(i);
17828            if (uss.mState != UserStartedState.STATE_STOPPING
17829                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17830                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17831                num++;
17832            }
17833        }
17834    }
17835
17836    @Override
17837    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17838        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17839                != PackageManager.PERMISSION_GRANTED) {
17840            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17841                    + Binder.getCallingPid()
17842                    + ", uid=" + Binder.getCallingUid()
17843                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17844            Slog.w(TAG, msg);
17845            throw new SecurityException(msg);
17846        }
17847
17848        mUserSwitchObservers.register(observer);
17849    }
17850
17851    @Override
17852    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17853        mUserSwitchObservers.unregister(observer);
17854    }
17855
17856    private boolean userExists(int userId) {
17857        if (userId == 0) {
17858            return true;
17859        }
17860        UserManagerService ums = getUserManagerLocked();
17861        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17862    }
17863
17864    int[] getUsersLocked() {
17865        UserManagerService ums = getUserManagerLocked();
17866        return ums != null ? ums.getUserIds() : new int[] { 0 };
17867    }
17868
17869    UserManagerService getUserManagerLocked() {
17870        if (mUserManager == null) {
17871            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17872            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17873        }
17874        return mUserManager;
17875    }
17876
17877    private int applyUserId(int uid, int userId) {
17878        return UserHandle.getUid(userId, uid);
17879    }
17880
17881    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17882        if (info == null) return null;
17883        ApplicationInfo newInfo = new ApplicationInfo(info);
17884        newInfo.uid = applyUserId(info.uid, userId);
17885        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17886                + info.packageName;
17887        return newInfo;
17888    }
17889
17890    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17891        if (aInfo == null
17892                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17893            return aInfo;
17894        }
17895
17896        ActivityInfo info = new ActivityInfo(aInfo);
17897        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17898        return info;
17899    }
17900
17901    private final class LocalService extends ActivityManagerInternal {
17902        @Override
17903        public void goingToSleep() {
17904            ActivityManagerService.this.goingToSleep();
17905        }
17906
17907        @Override
17908        public void wakingUp() {
17909            ActivityManagerService.this.wakingUp();
17910        }
17911
17912        @Override
17913        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
17914                String processName, String abiOverride, int uid, Runnable crashHandler) {
17915            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
17916                    processName, abiOverride, uid, crashHandler);
17917        }
17918    }
17919
17920    /**
17921     * An implementation of IAppTask, that allows an app to manage its own tasks via
17922     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17923     * only the process that calls getAppTasks() can call the AppTask methods.
17924     */
17925    class AppTaskImpl extends IAppTask.Stub {
17926        private int mTaskId;
17927        private int mCallingUid;
17928
17929        public AppTaskImpl(int taskId, int callingUid) {
17930            mTaskId = taskId;
17931            mCallingUid = callingUid;
17932        }
17933
17934        @Override
17935        public void finishAndRemoveTask() {
17936            // Ensure that we are called from the same process that created this AppTask
17937            if (mCallingUid != Binder.getCallingUid()) {
17938                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17939                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17940                return;
17941            }
17942
17943            synchronized (ActivityManagerService.this) {
17944                long origId = Binder.clearCallingIdentity();
17945                try {
17946                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17947                    if (tr != null) {
17948                        // Only kill the process if we are not a new document
17949                        int flags = tr.getBaseIntent().getFlags();
17950                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17951                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17952                        removeTaskByIdLocked(mTaskId,
17953                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17954                    }
17955                } finally {
17956                    Binder.restoreCallingIdentity(origId);
17957                }
17958            }
17959        }
17960
17961        @Override
17962        public ActivityManager.RecentTaskInfo getTaskInfo() {
17963            // Ensure that we are called from the same process that created this AppTask
17964            if (mCallingUid != Binder.getCallingUid()) {
17965                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17966                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17967                return null;
17968            }
17969
17970            synchronized (ActivityManagerService.this) {
17971                long origId = Binder.clearCallingIdentity();
17972                try {
17973                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17974                    if (tr != null) {
17975                        return createRecentTaskInfoFromTaskRecord(tr);
17976                    }
17977                } finally {
17978                    Binder.restoreCallingIdentity(origId);
17979                }
17980                return null;
17981            }
17982        }
17983    }
17984}
17985