ActivityManagerService.java revision d1c99b1fe85ed03261a77a14ae52e7fa3a6e523a
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
1163    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1164    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1165    static final int FIRST_COMPAT_MODE_MSG = 300;
1166    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1167
1168    AlertDialog mUidAlert;
1169    CompatModeDialog mCompatModeDialog;
1170    long mLastMemUsageReportTime = 0;
1171
1172    private LockToAppRequestDialog mLockToAppRequest;
1173
1174    /**
1175     * Flag whether the current user is a "monkey", i.e. whether
1176     * the UI is driven by a UI automation tool.
1177     */
1178    private boolean mUserIsMonkey;
1179
1180    /** Flag whether the device has a recents UI */
1181    final boolean mHasRecents;
1182
1183    final ServiceThread mHandlerThread;
1184    final MainHandler mHandler;
1185
1186    final class MainHandler extends Handler {
1187        public MainHandler(Looper looper) {
1188            super(looper, null, true);
1189        }
1190
1191        @Override
1192        public void handleMessage(Message msg) {
1193            switch (msg.what) {
1194            case SHOW_ERROR_MSG: {
1195                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1196                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1197                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1198                synchronized (ActivityManagerService.this) {
1199                    ProcessRecord proc = (ProcessRecord)data.get("app");
1200                    AppErrorResult res = (AppErrorResult) data.get("result");
1201                    if (proc != null && proc.crashDialog != null) {
1202                        Slog.e(TAG, "App already has crash dialog: " + proc);
1203                        if (res != null) {
1204                            res.set(0);
1205                        }
1206                        return;
1207                    }
1208                    if (!showBackground && UserHandle.getAppId(proc.uid)
1209                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1210                            && proc.pid != MY_PID) {
1211                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1212                        if (res != null) {
1213                            res.set(0);
1214                        }
1215                        return;
1216                    }
1217                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1218                        Dialog d = new AppErrorDialog(mContext,
1219                                ActivityManagerService.this, res, proc);
1220                        d.show();
1221                        proc.crashDialog = d;
1222                    } else {
1223                        // The device is asleep, so just pretend that the user
1224                        // saw a crash dialog and hit "force quit".
1225                        if (res != null) {
1226                            res.set(0);
1227                        }
1228                    }
1229                }
1230
1231                ensureBootCompleted();
1232            } break;
1233            case SHOW_NOT_RESPONDING_MSG: {
1234                synchronized (ActivityManagerService.this) {
1235                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1236                    ProcessRecord proc = (ProcessRecord)data.get("app");
1237                    if (proc != null && proc.anrDialog != null) {
1238                        Slog.e(TAG, "App already has anr dialog: " + proc);
1239                        return;
1240                    }
1241
1242                    Intent intent = new Intent("android.intent.action.ANR");
1243                    if (!mProcessesReady) {
1244                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1245                                | Intent.FLAG_RECEIVER_FOREGROUND);
1246                    }
1247                    broadcastIntentLocked(null, null, intent,
1248                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1249                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1250
1251                    if (mShowDialogs) {
1252                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1253                                mContext, proc, (ActivityRecord)data.get("activity"),
1254                                msg.arg1 != 0);
1255                        d.show();
1256                        proc.anrDialog = d;
1257                    } else {
1258                        // Just kill the app if there is no dialog to be shown.
1259                        killAppAtUsersRequest(proc, null);
1260                    }
1261                }
1262
1263                ensureBootCompleted();
1264            } break;
1265            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1266                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1267                synchronized (ActivityManagerService.this) {
1268                    ProcessRecord proc = (ProcessRecord) data.get("app");
1269                    if (proc == null) {
1270                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1271                        break;
1272                    }
1273                    if (proc.crashDialog != null) {
1274                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1275                        return;
1276                    }
1277                    AppErrorResult res = (AppErrorResult) data.get("result");
1278                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1279                        Dialog d = new StrictModeViolationDialog(mContext,
1280                                ActivityManagerService.this, res, proc);
1281                        d.show();
1282                        proc.crashDialog = d;
1283                    } else {
1284                        // The device is asleep, so just pretend that the user
1285                        // saw a crash dialog and hit "force quit".
1286                        res.set(0);
1287                    }
1288                }
1289                ensureBootCompleted();
1290            } break;
1291            case SHOW_FACTORY_ERROR_MSG: {
1292                Dialog d = new FactoryErrorDialog(
1293                    mContext, msg.getData().getCharSequence("msg"));
1294                d.show();
1295                ensureBootCompleted();
1296            } break;
1297            case UPDATE_CONFIGURATION_MSG: {
1298                final ContentResolver resolver = mContext.getContentResolver();
1299                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1300            } break;
1301            case GC_BACKGROUND_PROCESSES_MSG: {
1302                synchronized (ActivityManagerService.this) {
1303                    performAppGcsIfAppropriateLocked();
1304                }
1305            } break;
1306            case WAIT_FOR_DEBUGGER_MSG: {
1307                synchronized (ActivityManagerService.this) {
1308                    ProcessRecord app = (ProcessRecord)msg.obj;
1309                    if (msg.arg1 != 0) {
1310                        if (!app.waitedForDebugger) {
1311                            Dialog d = new AppWaitingForDebuggerDialog(
1312                                    ActivityManagerService.this,
1313                                    mContext, app);
1314                            app.waitDialog = d;
1315                            app.waitedForDebugger = true;
1316                            d.show();
1317                        }
1318                    } else {
1319                        if (app.waitDialog != null) {
1320                            app.waitDialog.dismiss();
1321                            app.waitDialog = null;
1322                        }
1323                    }
1324                }
1325            } break;
1326            case SERVICE_TIMEOUT_MSG: {
1327                if (mDidDexOpt) {
1328                    mDidDexOpt = false;
1329                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1330                    nmsg.obj = msg.obj;
1331                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1332                    return;
1333                }
1334                mServices.serviceTimeout((ProcessRecord)msg.obj);
1335            } break;
1336            case UPDATE_TIME_ZONE: {
1337                synchronized (ActivityManagerService.this) {
1338                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1339                        ProcessRecord r = mLruProcesses.get(i);
1340                        if (r.thread != null) {
1341                            try {
1342                                r.thread.updateTimeZone();
1343                            } catch (RemoteException ex) {
1344                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1345                            }
1346                        }
1347                    }
1348                }
1349            } break;
1350            case CLEAR_DNS_CACHE_MSG: {
1351                synchronized (ActivityManagerService.this) {
1352                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1353                        ProcessRecord r = mLruProcesses.get(i);
1354                        if (r.thread != null) {
1355                            try {
1356                                r.thread.clearDnsCache();
1357                            } catch (RemoteException ex) {
1358                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1359                            }
1360                        }
1361                    }
1362                }
1363            } break;
1364            case UPDATE_HTTP_PROXY_MSG: {
1365                ProxyInfo proxy = (ProxyInfo)msg.obj;
1366                String host = "";
1367                String port = "";
1368                String exclList = "";
1369                Uri pacFileUrl = Uri.EMPTY;
1370                if (proxy != null) {
1371                    host = proxy.getHost();
1372                    port = Integer.toString(proxy.getPort());
1373                    exclList = proxy.getExclusionListAsString();
1374                    pacFileUrl = proxy.getPacFileUrl();
1375                }
1376                synchronized (ActivityManagerService.this) {
1377                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1378                        ProcessRecord r = mLruProcesses.get(i);
1379                        if (r.thread != null) {
1380                            try {
1381                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1382                            } catch (RemoteException ex) {
1383                                Slog.w(TAG, "Failed to update http proxy for: " +
1384                                        r.info.processName);
1385                            }
1386                        }
1387                    }
1388                }
1389            } break;
1390            case SHOW_UID_ERROR_MSG: {
1391                String title = "System UIDs Inconsistent";
1392                String text = "UIDs on the system are inconsistent, you need to wipe your"
1393                        + " data partition or your device will be unstable.";
1394                Log.e(TAG, title + ": " + text);
1395                if (mShowDialogs) {
1396                    // XXX This is a temporary dialog, no need to localize.
1397                    AlertDialog d = new BaseErrorDialog(mContext);
1398                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1399                    d.setCancelable(false);
1400                    d.setTitle(title);
1401                    d.setMessage(text);
1402                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1403                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1404                    mUidAlert = d;
1405                    d.show();
1406                }
1407            } break;
1408            case IM_FEELING_LUCKY_MSG: {
1409                if (mUidAlert != null) {
1410                    mUidAlert.dismiss();
1411                    mUidAlert = null;
1412                }
1413            } break;
1414            case PROC_START_TIMEOUT_MSG: {
1415                if (mDidDexOpt) {
1416                    mDidDexOpt = false;
1417                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1418                    nmsg.obj = msg.obj;
1419                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1420                    return;
1421                }
1422                ProcessRecord app = (ProcessRecord)msg.obj;
1423                synchronized (ActivityManagerService.this) {
1424                    processStartTimedOutLocked(app);
1425                }
1426            } break;
1427            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1428                synchronized (ActivityManagerService.this) {
1429                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1430                }
1431            } break;
1432            case KILL_APPLICATION_MSG: {
1433                synchronized (ActivityManagerService.this) {
1434                    int appid = msg.arg1;
1435                    boolean restart = (msg.arg2 == 1);
1436                    Bundle bundle = (Bundle)msg.obj;
1437                    String pkg = bundle.getString("pkg");
1438                    String reason = bundle.getString("reason");
1439                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1440                            false, UserHandle.USER_ALL, reason);
1441                }
1442            } break;
1443            case FINALIZE_PENDING_INTENT_MSG: {
1444                ((PendingIntentRecord)msg.obj).completeFinalize();
1445            } break;
1446            case POST_HEAVY_NOTIFICATION_MSG: {
1447                INotificationManager inm = NotificationManager.getService();
1448                if (inm == null) {
1449                    return;
1450                }
1451
1452                ActivityRecord root = (ActivityRecord)msg.obj;
1453                ProcessRecord process = root.app;
1454                if (process == null) {
1455                    return;
1456                }
1457
1458                try {
1459                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1460                    String text = mContext.getString(R.string.heavy_weight_notification,
1461                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1462                    Notification notification = new Notification();
1463                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1464                    notification.when = 0;
1465                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1466                    notification.tickerText = text;
1467                    notification.defaults = 0; // please be quiet
1468                    notification.sound = null;
1469                    notification.vibrate = null;
1470                    notification.setLatestEventInfo(context, text,
1471                            mContext.getText(R.string.heavy_weight_notification_detail),
1472                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1473                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1474                                    new UserHandle(root.userId)));
1475
1476                    try {
1477                        int[] outId = new int[1];
1478                        inm.enqueueNotificationWithTag("android", "android", null,
1479                                R.string.heavy_weight_notification,
1480                                notification, outId, root.userId);
1481                    } catch (RuntimeException e) {
1482                        Slog.w(ActivityManagerService.TAG,
1483                                "Error showing notification for heavy-weight app", e);
1484                    } catch (RemoteException e) {
1485                    }
1486                } catch (NameNotFoundException e) {
1487                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1488                }
1489            } break;
1490            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1491                INotificationManager inm = NotificationManager.getService();
1492                if (inm == null) {
1493                    return;
1494                }
1495                try {
1496                    inm.cancelNotificationWithTag("android", null,
1497                            R.string.heavy_weight_notification,  msg.arg1);
1498                } catch (RuntimeException e) {
1499                    Slog.w(ActivityManagerService.TAG,
1500                            "Error canceling notification for service", e);
1501                } catch (RemoteException e) {
1502                }
1503            } break;
1504            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1505                synchronized (ActivityManagerService.this) {
1506                    checkExcessivePowerUsageLocked(true);
1507                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1508                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1509                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1510                }
1511            } break;
1512            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1513                synchronized (ActivityManagerService.this) {
1514                    ActivityRecord ar = (ActivityRecord)msg.obj;
1515                    if (mCompatModeDialog != null) {
1516                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1517                                ar.info.applicationInfo.packageName)) {
1518                            return;
1519                        }
1520                        mCompatModeDialog.dismiss();
1521                        mCompatModeDialog = null;
1522                    }
1523                    if (ar != null && false) {
1524                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1525                                ar.packageName)) {
1526                            int mode = mCompatModePackages.computeCompatModeLocked(
1527                                    ar.info.applicationInfo);
1528                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1529                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1530                                mCompatModeDialog = new CompatModeDialog(
1531                                        ActivityManagerService.this, mContext,
1532                                        ar.info.applicationInfo);
1533                                mCompatModeDialog.show();
1534                            }
1535                        }
1536                    }
1537                }
1538                break;
1539            }
1540            case DISPATCH_PROCESSES_CHANGED: {
1541                dispatchProcessesChanged();
1542                break;
1543            }
1544            case DISPATCH_PROCESS_DIED: {
1545                final int pid = msg.arg1;
1546                final int uid = msg.arg2;
1547                dispatchProcessDied(pid, uid);
1548                break;
1549            }
1550            case REPORT_MEM_USAGE_MSG: {
1551                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1552                Thread thread = new Thread() {
1553                    @Override public void run() {
1554                        final SparseArray<ProcessMemInfo> infoMap
1555                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1556                        for (int i=0, N=memInfos.size(); i<N; i++) {
1557                            ProcessMemInfo mi = memInfos.get(i);
1558                            infoMap.put(mi.pid, mi);
1559                        }
1560                        updateCpuStatsNow();
1561                        synchronized (mProcessCpuThread) {
1562                            final int N = mProcessCpuTracker.countStats();
1563                            for (int i=0; i<N; i++) {
1564                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1565                                if (st.vsize > 0) {
1566                                    long pss = Debug.getPss(st.pid, null);
1567                                    if (pss > 0) {
1568                                        if (infoMap.indexOfKey(st.pid) < 0) {
1569                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1570                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1571                                            mi.pss = pss;
1572                                            memInfos.add(mi);
1573                                        }
1574                                    }
1575                                }
1576                            }
1577                        }
1578
1579                        long totalPss = 0;
1580                        for (int i=0, N=memInfos.size(); i<N; i++) {
1581                            ProcessMemInfo mi = memInfos.get(i);
1582                            if (mi.pss == 0) {
1583                                mi.pss = Debug.getPss(mi.pid, null);
1584                            }
1585                            totalPss += mi.pss;
1586                        }
1587                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1588                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1589                                if (lhs.oomAdj != rhs.oomAdj) {
1590                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1591                                }
1592                                if (lhs.pss != rhs.pss) {
1593                                    return lhs.pss < rhs.pss ? 1 : -1;
1594                                }
1595                                return 0;
1596                            }
1597                        });
1598
1599                        StringBuilder tag = new StringBuilder(128);
1600                        StringBuilder stack = new StringBuilder(128);
1601                        tag.append("Low on memory -- ");
1602                        appendMemBucket(tag, totalPss, "total", false);
1603                        appendMemBucket(stack, totalPss, "total", true);
1604
1605                        StringBuilder logBuilder = new StringBuilder(1024);
1606                        logBuilder.append("Low on memory:\n");
1607
1608                        boolean firstLine = true;
1609                        int lastOomAdj = Integer.MIN_VALUE;
1610                        for (int i=0, N=memInfos.size(); i<N; i++) {
1611                            ProcessMemInfo mi = memInfos.get(i);
1612
1613                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1614                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1615                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1616                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1617                                if (lastOomAdj != mi.oomAdj) {
1618                                    lastOomAdj = mi.oomAdj;
1619                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1620                                        tag.append(" / ");
1621                                    }
1622                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1623                                        if (firstLine) {
1624                                            stack.append(":");
1625                                            firstLine = false;
1626                                        }
1627                                        stack.append("\n\t at ");
1628                                    } else {
1629                                        stack.append("$");
1630                                    }
1631                                } else {
1632                                    tag.append(" ");
1633                                    stack.append("$");
1634                                }
1635                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1636                                    appendMemBucket(tag, mi.pss, mi.name, false);
1637                                }
1638                                appendMemBucket(stack, mi.pss, mi.name, true);
1639                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1640                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1641                                    stack.append("(");
1642                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1643                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1644                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1645                                            stack.append(":");
1646                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1647                                        }
1648                                    }
1649                                    stack.append(")");
1650                                }
1651                            }
1652
1653                            logBuilder.append("  ");
1654                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1655                            logBuilder.append(' ');
1656                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1657                            logBuilder.append(' ');
1658                            ProcessList.appendRamKb(logBuilder, mi.pss);
1659                            logBuilder.append(" kB: ");
1660                            logBuilder.append(mi.name);
1661                            logBuilder.append(" (");
1662                            logBuilder.append(mi.pid);
1663                            logBuilder.append(") ");
1664                            logBuilder.append(mi.adjType);
1665                            logBuilder.append('\n');
1666                            if (mi.adjReason != null) {
1667                                logBuilder.append("                      ");
1668                                logBuilder.append(mi.adjReason);
1669                                logBuilder.append('\n');
1670                            }
1671                        }
1672
1673                        logBuilder.append("           ");
1674                        ProcessList.appendRamKb(logBuilder, totalPss);
1675                        logBuilder.append(" kB: TOTAL\n");
1676
1677                        long[] infos = new long[Debug.MEMINFO_COUNT];
1678                        Debug.getMemInfo(infos);
1679                        logBuilder.append("  MemInfo: ");
1680                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1681                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1682                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1683                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1684                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1685                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1686                            logBuilder.append("  ZRAM: ");
1687                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1688                            logBuilder.append(" kB RAM, ");
1689                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1690                            logBuilder.append(" kB swap total, ");
1691                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1692                            logBuilder.append(" kB swap free\n");
1693                        }
1694                        Slog.i(TAG, logBuilder.toString());
1695
1696                        StringBuilder dropBuilder = new StringBuilder(1024);
1697                        /*
1698                        StringWriter oomSw = new StringWriter();
1699                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1700                        StringWriter catSw = new StringWriter();
1701                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1702                        String[] emptyArgs = new String[] { };
1703                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1704                        oomPw.flush();
1705                        String oomString = oomSw.toString();
1706                        */
1707                        dropBuilder.append(stack);
1708                        dropBuilder.append('\n');
1709                        dropBuilder.append('\n');
1710                        dropBuilder.append(logBuilder);
1711                        dropBuilder.append('\n');
1712                        /*
1713                        dropBuilder.append(oomString);
1714                        dropBuilder.append('\n');
1715                        */
1716                        StringWriter catSw = new StringWriter();
1717                        synchronized (ActivityManagerService.this) {
1718                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1719                            String[] emptyArgs = new String[] { };
1720                            catPw.println();
1721                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1722                            catPw.println();
1723                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1724                                    false, false, null);
1725                            catPw.println();
1726                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1727                            catPw.flush();
1728                        }
1729                        dropBuilder.append(catSw.toString());
1730                        addErrorToDropBox("lowmem", null, "system_server", null,
1731                                null, tag.toString(), dropBuilder.toString(), null, null);
1732                        //Slog.i(TAG, "Sent to dropbox:");
1733                        //Slog.i(TAG, dropBuilder.toString());
1734                        synchronized (ActivityManagerService.this) {
1735                            long now = SystemClock.uptimeMillis();
1736                            if (mLastMemUsageReportTime < now) {
1737                                mLastMemUsageReportTime = now;
1738                            }
1739                        }
1740                    }
1741                };
1742                thread.start();
1743                break;
1744            }
1745            case REPORT_USER_SWITCH_MSG: {
1746                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1747                break;
1748            }
1749            case CONTINUE_USER_SWITCH_MSG: {
1750                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1751                break;
1752            }
1753            case USER_SWITCH_TIMEOUT_MSG: {
1754                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1755                break;
1756            }
1757            case IMMERSIVE_MODE_LOCK_MSG: {
1758                final boolean nextState = (msg.arg1 != 0);
1759                if (mUpdateLock.isHeld() != nextState) {
1760                    if (DEBUG_IMMERSIVE) {
1761                        final ActivityRecord r = (ActivityRecord) msg.obj;
1762                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1763                    }
1764                    if (nextState) {
1765                        mUpdateLock.acquire();
1766                    } else {
1767                        mUpdateLock.release();
1768                    }
1769                }
1770                break;
1771            }
1772            case PERSIST_URI_GRANTS_MSG: {
1773                writeGrantedUriPermissions();
1774                break;
1775            }
1776            case REQUEST_ALL_PSS_MSG: {
1777                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1778                break;
1779            }
1780            case START_PROFILES_MSG: {
1781                synchronized (ActivityManagerService.this) {
1782                    startProfilesLocked();
1783                }
1784                break;
1785            }
1786            case UPDATE_TIME: {
1787                synchronized (ActivityManagerService.this) {
1788                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1789                        ProcessRecord r = mLruProcesses.get(i);
1790                        if (r.thread != null) {
1791                            try {
1792                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1793                            } catch (RemoteException ex) {
1794                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1795                            }
1796                        }
1797                    }
1798                }
1799                break;
1800            }
1801            case SYSTEM_USER_START_MSG: {
1802                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1803                        Integer.toString(msg.arg1), msg.arg1);
1804                mSystemServiceManager.startUser(msg.arg1);
1805                break;
1806            }
1807            case SYSTEM_USER_CURRENT_MSG: {
1808                mBatteryStatsService.noteEvent(
1809                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1810                        Integer.toString(msg.arg2), msg.arg2);
1811                mBatteryStatsService.noteEvent(
1812                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1813                        Integer.toString(msg.arg1), msg.arg1);
1814                mSystemServiceManager.switchUser(msg.arg1);
1815                break;
1816            }
1817            case ENTER_ANIMATION_COMPLETE_MSG: {
1818                synchronized (ActivityManagerService.this) {
1819                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1820                    if (r != null && r.app != null && r.app.thread != null) {
1821                        try {
1822                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1823                        } catch (RemoteException e) {
1824                        }
1825                    }
1826                }
1827                break;
1828            }
1829            }
1830        }
1831    };
1832
1833    static final int COLLECT_PSS_BG_MSG = 1;
1834
1835    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1836        @Override
1837        public void handleMessage(Message msg) {
1838            switch (msg.what) {
1839            case COLLECT_PSS_BG_MSG: {
1840                long start = SystemClock.uptimeMillis();
1841                MemInfoReader memInfo = null;
1842                synchronized (ActivityManagerService.this) {
1843                    if (mFullPssPending) {
1844                        mFullPssPending = false;
1845                        memInfo = new MemInfoReader();
1846                    }
1847                }
1848                if (memInfo != null) {
1849                    updateCpuStatsNow();
1850                    long nativeTotalPss = 0;
1851                    synchronized (mProcessCpuThread) {
1852                        final int N = mProcessCpuTracker.countStats();
1853                        for (int j=0; j<N; j++) {
1854                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1855                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1856                                // This is definitely an application process; skip it.
1857                                continue;
1858                            }
1859                            synchronized (mPidsSelfLocked) {
1860                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1861                                    // This is one of our own processes; skip it.
1862                                    continue;
1863                                }
1864                            }
1865                            nativeTotalPss += Debug.getPss(st.pid, null);
1866                        }
1867                    }
1868                    memInfo.readMemInfo();
1869                    synchronized (this) {
1870                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1871                                + (SystemClock.uptimeMillis()-start) + "ms");
1872                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1873                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1874                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1875                                        +memInfo.getSlabSizeKb(),
1876                                nativeTotalPss);
1877                    }
1878                }
1879
1880                int i=0, num=0;
1881                long[] tmp = new long[1];
1882                do {
1883                    ProcessRecord proc;
1884                    int procState;
1885                    int pid;
1886                    synchronized (ActivityManagerService.this) {
1887                        if (i >= mPendingPssProcesses.size()) {
1888                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1889                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1890                            mPendingPssProcesses.clear();
1891                            return;
1892                        }
1893                        proc = mPendingPssProcesses.get(i);
1894                        procState = proc.pssProcState;
1895                        if (proc.thread != null && procState == proc.setProcState) {
1896                            pid = proc.pid;
1897                        } else {
1898                            proc = null;
1899                            pid = 0;
1900                        }
1901                        i++;
1902                    }
1903                    if (proc != null) {
1904                        long pss = Debug.getPss(pid, tmp);
1905                        synchronized (ActivityManagerService.this) {
1906                            if (proc.thread != null && proc.setProcState == procState
1907                                    && proc.pid == pid) {
1908                                num++;
1909                                proc.lastPssTime = SystemClock.uptimeMillis();
1910                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1911                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1912                                        + ": " + pss + " lastPss=" + proc.lastPss
1913                                        + " state=" + ProcessList.makeProcStateString(procState));
1914                                if (proc.initialIdlePss == 0) {
1915                                    proc.initialIdlePss = pss;
1916                                }
1917                                proc.lastPss = pss;
1918                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1919                                    proc.lastCachedPss = pss;
1920                                }
1921                            }
1922                        }
1923                    }
1924                } while (true);
1925            }
1926            }
1927        }
1928    };
1929
1930    /**
1931     * Monitor for package changes and update our internal state.
1932     */
1933    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1934        @Override
1935        public void onPackageRemoved(String packageName, int uid) {
1936            // Remove all tasks with activities in the specified package from the list of recent tasks
1937            synchronized (ActivityManagerService.this) {
1938                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1939                    TaskRecord tr = mRecentTasks.get(i);
1940                    ComponentName cn = tr.intent.getComponent();
1941                    if (cn != null && cn.getPackageName().equals(packageName)) {
1942                        // If the package name matches, remove the task and kill the process
1943                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1944                    }
1945                }
1946            }
1947        }
1948
1949        @Override
1950        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1951            onPackageModified(packageName);
1952            return true;
1953        }
1954
1955        @Override
1956        public void onPackageModified(String packageName) {
1957            final PackageManager pm = mContext.getPackageManager();
1958            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1959                    new ArrayList<Pair<Intent, Integer>>();
1960            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1961            // Copy the list of recent tasks so that we don't hold onto the lock on
1962            // ActivityManagerService for long periods while checking if components exist.
1963            synchronized (ActivityManagerService.this) {
1964                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1965                    TaskRecord tr = mRecentTasks.get(i);
1966                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1967                }
1968            }
1969            // Check the recent tasks and filter out all tasks with components that no longer exist.
1970            Intent tmpI = new Intent();
1971            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1972                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1973                ComponentName cn = p.first.getComponent();
1974                if (cn != null && cn.getPackageName().equals(packageName)) {
1975                    try {
1976                        // Add the task to the list to remove if the component no longer exists
1977                        tmpI.setComponent(cn);
1978                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1979                            tasksToRemove.add(p.second);
1980                        }
1981                    } catch (Exception e) {}
1982                }
1983            }
1984            // Prune all the tasks with removed components from the list of recent tasks
1985            synchronized (ActivityManagerService.this) {
1986                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1987                    // Remove the task but don't kill the process (since other components in that
1988                    // package may still be running and in the background)
1989                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1990                }
1991            }
1992        }
1993
1994        @Override
1995        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1996            // Force stop the specified packages
1997            if (packages != null) {
1998                for (String pkg : packages) {
1999                    synchronized (ActivityManagerService.this) {
2000                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2001                                "finished booting")) {
2002                            return true;
2003                        }
2004                    }
2005                }
2006            }
2007            return false;
2008        }
2009    };
2010
2011    public void setSystemProcess() {
2012        try {
2013            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2014            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2015            ServiceManager.addService("meminfo", new MemBinder(this));
2016            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2017            ServiceManager.addService("dbinfo", new DbBinder(this));
2018            if (MONITOR_CPU_USAGE) {
2019                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2020            }
2021            ServiceManager.addService("permission", new PermissionController(this));
2022
2023            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2024                    "android", STOCK_PM_FLAGS);
2025            mSystemThread.installSystemApplicationInfo(info);
2026
2027            synchronized (this) {
2028                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2029                app.persistent = true;
2030                app.pid = MY_PID;
2031                app.maxAdj = ProcessList.SYSTEM_ADJ;
2032                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2033                mProcessNames.put(app.processName, app.uid, app);
2034                synchronized (mPidsSelfLocked) {
2035                    mPidsSelfLocked.put(app.pid, app);
2036                }
2037                updateLruProcessLocked(app, false, null);
2038                updateOomAdjLocked();
2039            }
2040        } catch (PackageManager.NameNotFoundException e) {
2041            throw new RuntimeException(
2042                    "Unable to find android system package", e);
2043        }
2044    }
2045
2046    public void setWindowManager(WindowManagerService wm) {
2047        mWindowManager = wm;
2048        mStackSupervisor.setWindowManager(wm);
2049    }
2050
2051    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2052        mUsageStatsService = usageStatsManager;
2053    }
2054
2055    public void startObservingNativeCrashes() {
2056        final NativeCrashListener ncl = new NativeCrashListener(this);
2057        ncl.start();
2058    }
2059
2060    public IAppOpsService getAppOpsService() {
2061        return mAppOpsService;
2062    }
2063
2064    static class MemBinder extends Binder {
2065        ActivityManagerService mActivityManagerService;
2066        MemBinder(ActivityManagerService activityManagerService) {
2067            mActivityManagerService = activityManagerService;
2068        }
2069
2070        @Override
2071        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2072            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2073                    != PackageManager.PERMISSION_GRANTED) {
2074                pw.println("Permission Denial: can't dump meminfo from from pid="
2075                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2076                        + " without permission " + android.Manifest.permission.DUMP);
2077                return;
2078            }
2079
2080            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2081        }
2082    }
2083
2084    static class GraphicsBinder extends Binder {
2085        ActivityManagerService mActivityManagerService;
2086        GraphicsBinder(ActivityManagerService activityManagerService) {
2087            mActivityManagerService = activityManagerService;
2088        }
2089
2090        @Override
2091        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2092            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2093                    != PackageManager.PERMISSION_GRANTED) {
2094                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2095                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2096                        + " without permission " + android.Manifest.permission.DUMP);
2097                return;
2098            }
2099
2100            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2101        }
2102    }
2103
2104    static class DbBinder extends Binder {
2105        ActivityManagerService mActivityManagerService;
2106        DbBinder(ActivityManagerService activityManagerService) {
2107            mActivityManagerService = activityManagerService;
2108        }
2109
2110        @Override
2111        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2112            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2113                    != PackageManager.PERMISSION_GRANTED) {
2114                pw.println("Permission Denial: can't dump dbinfo from from pid="
2115                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2116                        + " without permission " + android.Manifest.permission.DUMP);
2117                return;
2118            }
2119
2120            mActivityManagerService.dumpDbInfo(fd, pw, args);
2121        }
2122    }
2123
2124    static class CpuBinder extends Binder {
2125        ActivityManagerService mActivityManagerService;
2126        CpuBinder(ActivityManagerService activityManagerService) {
2127            mActivityManagerService = activityManagerService;
2128        }
2129
2130        @Override
2131        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2132            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2133                    != PackageManager.PERMISSION_GRANTED) {
2134                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2135                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2136                        + " without permission " + android.Manifest.permission.DUMP);
2137                return;
2138            }
2139
2140            synchronized (mActivityManagerService.mProcessCpuThread) {
2141                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2142                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2143                        SystemClock.uptimeMillis()));
2144            }
2145        }
2146    }
2147
2148    public static final class Lifecycle extends SystemService {
2149        private final ActivityManagerService mService;
2150
2151        public Lifecycle(Context context) {
2152            super(context);
2153            mService = new ActivityManagerService(context);
2154        }
2155
2156        @Override
2157        public void onStart() {
2158            mService.start();
2159        }
2160
2161        public ActivityManagerService getService() {
2162            return mService;
2163        }
2164    }
2165
2166    // Note: This method is invoked on the main thread but may need to attach various
2167    // handlers to other threads.  So take care to be explicit about the looper.
2168    public ActivityManagerService(Context systemContext) {
2169        mContext = systemContext;
2170        mFactoryTest = FactoryTest.getMode();
2171        mSystemThread = ActivityThread.currentActivityThread();
2172
2173        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2174
2175        mHandlerThread = new ServiceThread(TAG,
2176                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2177        mHandlerThread.start();
2178        mHandler = new MainHandler(mHandlerThread.getLooper());
2179
2180        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2181                "foreground", BROADCAST_FG_TIMEOUT, false);
2182        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2183                "background", BROADCAST_BG_TIMEOUT, true);
2184        mBroadcastQueues[0] = mFgBroadcastQueue;
2185        mBroadcastQueues[1] = mBgBroadcastQueue;
2186
2187        mServices = new ActiveServices(this);
2188        mProviderMap = new ProviderMap(this);
2189
2190        // TODO: Move creation of battery stats service outside of activity manager service.
2191        File dataDir = Environment.getDataDirectory();
2192        File systemDir = new File(dataDir, "system");
2193        systemDir.mkdirs();
2194        mBatteryStatsService = new BatteryStatsService(new File(
2195                systemDir, "batterystats.bin").toString(), mHandler);
2196        mBatteryStatsService.getActiveStatistics().readLocked();
2197        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2198        mOnBattery = DEBUG_POWER ? true
2199                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2200        mBatteryStatsService.getActiveStatistics().setCallback(this);
2201
2202        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2203
2204        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2205
2206        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2207
2208        // User 0 is the first and only user that runs at boot.
2209        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2210        mUserLru.add(Integer.valueOf(0));
2211        updateStartedUserArrayLocked();
2212
2213        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2214            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2215
2216        mConfiguration.setToDefaults();
2217        mConfiguration.setLocale(Locale.getDefault());
2218
2219        mConfigurationSeq = mConfiguration.seq = 1;
2220        mProcessCpuTracker.init();
2221
2222        mHasRecents = mContext.getResources().getBoolean(
2223                com.android.internal.R.bool.config_hasRecents);
2224
2225        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2226        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2227        mStackSupervisor = new ActivityStackSupervisor(this);
2228        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2229
2230        mProcessCpuThread = new Thread("CpuTracker") {
2231            @Override
2232            public void run() {
2233                while (true) {
2234                    try {
2235                        try {
2236                            synchronized(this) {
2237                                final long now = SystemClock.uptimeMillis();
2238                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2239                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2240                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2241                                //        + ", write delay=" + nextWriteDelay);
2242                                if (nextWriteDelay < nextCpuDelay) {
2243                                    nextCpuDelay = nextWriteDelay;
2244                                }
2245                                if (nextCpuDelay > 0) {
2246                                    mProcessCpuMutexFree.set(true);
2247                                    this.wait(nextCpuDelay);
2248                                }
2249                            }
2250                        } catch (InterruptedException e) {
2251                        }
2252                        updateCpuStatsNow();
2253                    } catch (Exception e) {
2254                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2255                    }
2256                }
2257            }
2258        };
2259
2260        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2261
2262        Watchdog.getInstance().addMonitor(this);
2263        Watchdog.getInstance().addThread(mHandler);
2264    }
2265
2266    public void setSystemServiceManager(SystemServiceManager mgr) {
2267        mSystemServiceManager = mgr;
2268    }
2269
2270    private void start() {
2271        Process.removeAllProcessGroups();
2272        mProcessCpuThread.start();
2273
2274        mBatteryStatsService.publish(mContext);
2275        mAppOpsService.publish(mContext);
2276        Slog.d("AppOps", "AppOpsService published");
2277        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2278    }
2279
2280    public void initPowerManagement() {
2281        mStackSupervisor.initPowerManagement();
2282        mBatteryStatsService.initPowerManagement();
2283    }
2284
2285    @Override
2286    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2287            throws RemoteException {
2288        if (code == SYSPROPS_TRANSACTION) {
2289            // We need to tell all apps about the system property change.
2290            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2291            synchronized(this) {
2292                final int NP = mProcessNames.getMap().size();
2293                for (int ip=0; ip<NP; ip++) {
2294                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2295                    final int NA = apps.size();
2296                    for (int ia=0; ia<NA; ia++) {
2297                        ProcessRecord app = apps.valueAt(ia);
2298                        if (app.thread != null) {
2299                            procs.add(app.thread.asBinder());
2300                        }
2301                    }
2302                }
2303            }
2304
2305            int N = procs.size();
2306            for (int i=0; i<N; i++) {
2307                Parcel data2 = Parcel.obtain();
2308                try {
2309                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2310                } catch (RemoteException e) {
2311                }
2312                data2.recycle();
2313            }
2314        }
2315        try {
2316            return super.onTransact(code, data, reply, flags);
2317        } catch (RuntimeException e) {
2318            // The activity manager only throws security exceptions, so let's
2319            // log all others.
2320            if (!(e instanceof SecurityException)) {
2321                Slog.wtf(TAG, "Activity Manager Crash", e);
2322            }
2323            throw e;
2324        }
2325    }
2326
2327    void updateCpuStats() {
2328        final long now = SystemClock.uptimeMillis();
2329        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2330            return;
2331        }
2332        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2333            synchronized (mProcessCpuThread) {
2334                mProcessCpuThread.notify();
2335            }
2336        }
2337    }
2338
2339    void updateCpuStatsNow() {
2340        synchronized (mProcessCpuThread) {
2341            mProcessCpuMutexFree.set(false);
2342            final long now = SystemClock.uptimeMillis();
2343            boolean haveNewCpuStats = false;
2344
2345            if (MONITOR_CPU_USAGE &&
2346                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2347                mLastCpuTime.set(now);
2348                haveNewCpuStats = true;
2349                mProcessCpuTracker.update();
2350                //Slog.i(TAG, mProcessCpu.printCurrentState());
2351                //Slog.i(TAG, "Total CPU usage: "
2352                //        + mProcessCpu.getTotalCpuPercent() + "%");
2353
2354                // Slog the cpu usage if the property is set.
2355                if ("true".equals(SystemProperties.get("events.cpu"))) {
2356                    int user = mProcessCpuTracker.getLastUserTime();
2357                    int system = mProcessCpuTracker.getLastSystemTime();
2358                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2359                    int irq = mProcessCpuTracker.getLastIrqTime();
2360                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2361                    int idle = mProcessCpuTracker.getLastIdleTime();
2362
2363                    int total = user + system + iowait + irq + softIrq + idle;
2364                    if (total == 0) total = 1;
2365
2366                    EventLog.writeEvent(EventLogTags.CPU,
2367                            ((user+system+iowait+irq+softIrq) * 100) / total,
2368                            (user * 100) / total,
2369                            (system * 100) / total,
2370                            (iowait * 100) / total,
2371                            (irq * 100) / total,
2372                            (softIrq * 100) / total);
2373                }
2374            }
2375
2376            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2377            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2378            synchronized(bstats) {
2379                synchronized(mPidsSelfLocked) {
2380                    if (haveNewCpuStats) {
2381                        if (mOnBattery) {
2382                            int perc = bstats.startAddingCpuLocked();
2383                            int totalUTime = 0;
2384                            int totalSTime = 0;
2385                            final int N = mProcessCpuTracker.countStats();
2386                            for (int i=0; i<N; i++) {
2387                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2388                                if (!st.working) {
2389                                    continue;
2390                                }
2391                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2392                                int otherUTime = (st.rel_utime*perc)/100;
2393                                int otherSTime = (st.rel_stime*perc)/100;
2394                                totalUTime += otherUTime;
2395                                totalSTime += otherSTime;
2396                                if (pr != null) {
2397                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2398                                    if (ps == null || !ps.isActive()) {
2399                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2400                                                pr.info.uid, pr.processName);
2401                                    }
2402                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2403                                            st.rel_stime-otherSTime);
2404                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2405                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2406                                } else {
2407                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2408                                    if (ps == null || !ps.isActive()) {
2409                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2410                                                bstats.mapUid(st.uid), st.name);
2411                                    }
2412                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2413                                            st.rel_stime-otherSTime);
2414                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2415                                }
2416                            }
2417                            bstats.finishAddingCpuLocked(perc, totalUTime,
2418                                    totalSTime, cpuSpeedTimes);
2419                        }
2420                    }
2421                }
2422
2423                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2424                    mLastWriteTime = now;
2425                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2426                }
2427            }
2428        }
2429    }
2430
2431    @Override
2432    public void batteryNeedsCpuUpdate() {
2433        updateCpuStatsNow();
2434    }
2435
2436    @Override
2437    public void batteryPowerChanged(boolean onBattery) {
2438        // When plugging in, update the CPU stats first before changing
2439        // the plug state.
2440        updateCpuStatsNow();
2441        synchronized (this) {
2442            synchronized(mPidsSelfLocked) {
2443                mOnBattery = DEBUG_POWER ? true : onBattery;
2444            }
2445        }
2446    }
2447
2448    /**
2449     * Initialize the application bind args. These are passed to each
2450     * process when the bindApplication() IPC is sent to the process. They're
2451     * lazily setup to make sure the services are running when they're asked for.
2452     */
2453    private HashMap<String, IBinder> getCommonServicesLocked() {
2454        if (mAppBindArgs == null) {
2455            mAppBindArgs = new HashMap<String, IBinder>();
2456
2457            // Setup the application init args
2458            mAppBindArgs.put("package", ServiceManager.getService("package"));
2459            mAppBindArgs.put("window", ServiceManager.getService("window"));
2460            mAppBindArgs.put(Context.ALARM_SERVICE,
2461                    ServiceManager.getService(Context.ALARM_SERVICE));
2462        }
2463        return mAppBindArgs;
2464    }
2465
2466    final void setFocusedActivityLocked(ActivityRecord r) {
2467        if (mFocusedActivity != r) {
2468            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2469            mFocusedActivity = r;
2470            if (r.task != null && r.task.voiceInteractor != null) {
2471                startRunningVoiceLocked();
2472            } else {
2473                finishRunningVoiceLocked();
2474            }
2475            mStackSupervisor.setFocusedStack(r);
2476            if (r != null) {
2477                mWindowManager.setFocusedApp(r.appToken, true);
2478            }
2479            applyUpdateLockStateLocked(r);
2480        }
2481    }
2482
2483    final void clearFocusedActivity(ActivityRecord r) {
2484        if (mFocusedActivity == r) {
2485            mFocusedActivity = null;
2486        }
2487    }
2488
2489    @Override
2490    public void setFocusedStack(int stackId) {
2491        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2492        synchronized (ActivityManagerService.this) {
2493            ActivityStack stack = mStackSupervisor.getStack(stackId);
2494            if (stack != null) {
2495                ActivityRecord r = stack.topRunningActivityLocked(null);
2496                if (r != null) {
2497                    setFocusedActivityLocked(r);
2498                }
2499            }
2500        }
2501    }
2502
2503    @Override
2504    public void notifyActivityDrawn(IBinder token) {
2505        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2506        synchronized (this) {
2507            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2508            if (r != null) {
2509                r.task.stack.notifyActivityDrawnLocked(r);
2510            }
2511        }
2512    }
2513
2514    final void applyUpdateLockStateLocked(ActivityRecord r) {
2515        // Modifications to the UpdateLock state are done on our handler, outside
2516        // the activity manager's locks.  The new state is determined based on the
2517        // state *now* of the relevant activity record.  The object is passed to
2518        // the handler solely for logging detail, not to be consulted/modified.
2519        final boolean nextState = r != null && r.immersive;
2520        mHandler.sendMessage(
2521                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2522    }
2523
2524    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2525        Message msg = Message.obtain();
2526        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2527        msg.obj = r.task.askedCompatMode ? null : r;
2528        mHandler.sendMessage(msg);
2529    }
2530
2531    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2532            String what, Object obj, ProcessRecord srcApp) {
2533        app.lastActivityTime = now;
2534
2535        if (app.activities.size() > 0) {
2536            // Don't want to touch dependent processes that are hosting activities.
2537            return index;
2538        }
2539
2540        int lrui = mLruProcesses.lastIndexOf(app);
2541        if (lrui < 0) {
2542            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2543                    + what + " " + obj + " from " + srcApp);
2544            return index;
2545        }
2546
2547        if (lrui >= index) {
2548            // Don't want to cause this to move dependent processes *back* in the
2549            // list as if they were less frequently used.
2550            return index;
2551        }
2552
2553        if (lrui >= mLruProcessActivityStart) {
2554            // Don't want to touch dependent processes that are hosting activities.
2555            return index;
2556        }
2557
2558        mLruProcesses.remove(lrui);
2559        if (index > 0) {
2560            index--;
2561        }
2562        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2563                + " in LRU list: " + app);
2564        mLruProcesses.add(index, app);
2565        return index;
2566    }
2567
2568    final void removeLruProcessLocked(ProcessRecord app) {
2569        int lrui = mLruProcesses.lastIndexOf(app);
2570        if (lrui >= 0) {
2571            if (lrui <= mLruProcessActivityStart) {
2572                mLruProcessActivityStart--;
2573            }
2574            if (lrui <= mLruProcessServiceStart) {
2575                mLruProcessServiceStart--;
2576            }
2577            mLruProcesses.remove(lrui);
2578        }
2579    }
2580
2581    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2582            ProcessRecord client) {
2583        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2584                || app.treatLikeActivity;
2585        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2586        if (!activityChange && hasActivity) {
2587            // The process has activities, so we are only allowing activity-based adjustments
2588            // to move it.  It should be kept in the front of the list with other
2589            // processes that have activities, and we don't want those to change their
2590            // order except due to activity operations.
2591            return;
2592        }
2593
2594        mLruSeq++;
2595        final long now = SystemClock.uptimeMillis();
2596        app.lastActivityTime = now;
2597
2598        // First a quick reject: if the app is already at the position we will
2599        // put it, then there is nothing to do.
2600        if (hasActivity) {
2601            final int N = mLruProcesses.size();
2602            if (N > 0 && mLruProcesses.get(N-1) == app) {
2603                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2604                return;
2605            }
2606        } else {
2607            if (mLruProcessServiceStart > 0
2608                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2609                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2610                return;
2611            }
2612        }
2613
2614        int lrui = mLruProcesses.lastIndexOf(app);
2615
2616        if (app.persistent && lrui >= 0) {
2617            // We don't care about the position of persistent processes, as long as
2618            // they are in the list.
2619            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2620            return;
2621        }
2622
2623        /* In progress: compute new position first, so we can avoid doing work
2624           if the process is not actually going to move.  Not yet working.
2625        int addIndex;
2626        int nextIndex;
2627        boolean inActivity = false, inService = false;
2628        if (hasActivity) {
2629            // Process has activities, put it at the very tipsy-top.
2630            addIndex = mLruProcesses.size();
2631            nextIndex = mLruProcessServiceStart;
2632            inActivity = true;
2633        } else if (hasService) {
2634            // Process has services, put it at the top of the service list.
2635            addIndex = mLruProcessActivityStart;
2636            nextIndex = mLruProcessServiceStart;
2637            inActivity = true;
2638            inService = true;
2639        } else  {
2640            // Process not otherwise of interest, it goes to the top of the non-service area.
2641            addIndex = mLruProcessServiceStart;
2642            if (client != null) {
2643                int clientIndex = mLruProcesses.lastIndexOf(client);
2644                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2645                        + app);
2646                if (clientIndex >= 0 && addIndex > clientIndex) {
2647                    addIndex = clientIndex;
2648                }
2649            }
2650            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2651        }
2652
2653        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2654                + mLruProcessActivityStart + "): " + app);
2655        */
2656
2657        if (lrui >= 0) {
2658            if (lrui < mLruProcessActivityStart) {
2659                mLruProcessActivityStart--;
2660            }
2661            if (lrui < mLruProcessServiceStart) {
2662                mLruProcessServiceStart--;
2663            }
2664            /*
2665            if (addIndex > lrui) {
2666                addIndex--;
2667            }
2668            if (nextIndex > lrui) {
2669                nextIndex--;
2670            }
2671            */
2672            mLruProcesses.remove(lrui);
2673        }
2674
2675        /*
2676        mLruProcesses.add(addIndex, app);
2677        if (inActivity) {
2678            mLruProcessActivityStart++;
2679        }
2680        if (inService) {
2681            mLruProcessActivityStart++;
2682        }
2683        */
2684
2685        int nextIndex;
2686        if (hasActivity) {
2687            final int N = mLruProcesses.size();
2688            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2689                // Process doesn't have activities, but has clients with
2690                // activities...  move it up, but one below the top (the top
2691                // should always have a real activity).
2692                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2693                mLruProcesses.add(N-1, app);
2694                // To keep it from spamming the LRU list (by making a bunch of clients),
2695                // we will push down any other entries owned by the app.
2696                final int uid = app.info.uid;
2697                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2698                    ProcessRecord subProc = mLruProcesses.get(i);
2699                    if (subProc.info.uid == uid) {
2700                        // We want to push this one down the list.  If the process after
2701                        // it is for the same uid, however, don't do so, because we don't
2702                        // want them internally to be re-ordered.
2703                        if (mLruProcesses.get(i-1).info.uid != uid) {
2704                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2705                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2706                            ProcessRecord tmp = mLruProcesses.get(i);
2707                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2708                            mLruProcesses.set(i-1, tmp);
2709                            i--;
2710                        }
2711                    } else {
2712                        // A gap, we can stop here.
2713                        break;
2714                    }
2715                }
2716            } else {
2717                // Process has activities, put it at the very tipsy-top.
2718                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2719                mLruProcesses.add(app);
2720            }
2721            nextIndex = mLruProcessServiceStart;
2722        } else if (hasService) {
2723            // Process has services, put it at the top of the service list.
2724            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2725            mLruProcesses.add(mLruProcessActivityStart, app);
2726            nextIndex = mLruProcessServiceStart;
2727            mLruProcessActivityStart++;
2728        } else  {
2729            // Process not otherwise of interest, it goes to the top of the non-service area.
2730            int index = mLruProcessServiceStart;
2731            if (client != null) {
2732                // If there is a client, don't allow the process to be moved up higher
2733                // in the list than that client.
2734                int clientIndex = mLruProcesses.lastIndexOf(client);
2735                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2736                        + " when updating " + app);
2737                if (clientIndex <= lrui) {
2738                    // Don't allow the client index restriction to push it down farther in the
2739                    // list than it already is.
2740                    clientIndex = lrui;
2741                }
2742                if (clientIndex >= 0 && index > clientIndex) {
2743                    index = clientIndex;
2744                }
2745            }
2746            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2747            mLruProcesses.add(index, app);
2748            nextIndex = index-1;
2749            mLruProcessActivityStart++;
2750            mLruProcessServiceStart++;
2751        }
2752
2753        // If the app is currently using a content provider or service,
2754        // bump those processes as well.
2755        for (int j=app.connections.size()-1; j>=0; j--) {
2756            ConnectionRecord cr = app.connections.valueAt(j);
2757            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2758                    && cr.binding.service.app != null
2759                    && cr.binding.service.app.lruSeq != mLruSeq
2760                    && !cr.binding.service.app.persistent) {
2761                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2762                        "service connection", cr, app);
2763            }
2764        }
2765        for (int j=app.conProviders.size()-1; j>=0; j--) {
2766            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2767            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2768                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2769                        "provider reference", cpr, app);
2770            }
2771        }
2772    }
2773
2774    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2775        if (uid == Process.SYSTEM_UID) {
2776            // The system gets to run in any process.  If there are multiple
2777            // processes with the same uid, just pick the first (this
2778            // should never happen).
2779            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2780            if (procs == null) return null;
2781            final int N = procs.size();
2782            for (int i = 0; i < N; i++) {
2783                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2784            }
2785        }
2786        ProcessRecord proc = mProcessNames.get(processName, uid);
2787        if (false && proc != null && !keepIfLarge
2788                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2789                && proc.lastCachedPss >= 4000) {
2790            // Turn this condition on to cause killing to happen regularly, for testing.
2791            if (proc.baseProcessTracker != null) {
2792                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2793            }
2794            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2795                    + "k from cached");
2796        } else if (proc != null && !keepIfLarge
2797                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2798                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2799            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2800            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2801                if (proc.baseProcessTracker != null) {
2802                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2803                }
2804                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2805                        + "k from cached");
2806            }
2807        }
2808        return proc;
2809    }
2810
2811    void ensurePackageDexOpt(String packageName) {
2812        IPackageManager pm = AppGlobals.getPackageManager();
2813        try {
2814            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2815                mDidDexOpt = true;
2816            }
2817        } catch (RemoteException e) {
2818        }
2819    }
2820
2821    boolean isNextTransitionForward() {
2822        int transit = mWindowManager.getPendingAppTransition();
2823        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2824                || transit == AppTransition.TRANSIT_TASK_OPEN
2825                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2826    }
2827
2828    final ProcessRecord startProcessLocked(String processName,
2829            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2830            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2831            boolean isolated, boolean keepIfLarge) {
2832        ProcessRecord app;
2833        if (!isolated) {
2834            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2835        } else {
2836            // If this is an isolated process, it can't re-use an existing process.
2837            app = null;
2838        }
2839        // We don't have to do anything more if:
2840        // (1) There is an existing application record; and
2841        // (2) The caller doesn't think it is dead, OR there is no thread
2842        //     object attached to it so we know it couldn't have crashed; and
2843        // (3) There is a pid assigned to it, so it is either starting or
2844        //     already running.
2845        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2846                + " app=" + app + " knownToBeDead=" + knownToBeDead
2847                + " thread=" + (app != null ? app.thread : null)
2848                + " pid=" + (app != null ? app.pid : -1));
2849        if (app != null && app.pid > 0) {
2850            if (!knownToBeDead || app.thread == null) {
2851                // We already have the app running, or are waiting for it to
2852                // come up (we have a pid but not yet its thread), so keep it.
2853                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2854                // If this is a new package in the process, add the package to the list
2855                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2856                return app;
2857            }
2858
2859            // An application record is attached to a previous process,
2860            // clean it up now.
2861            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2862            Process.killProcessGroup(app.info.uid, app.pid);
2863            handleAppDiedLocked(app, true, true);
2864        }
2865
2866        String hostingNameStr = hostingName != null
2867                ? hostingName.flattenToShortString() : null;
2868
2869        if (!isolated) {
2870            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2871                // If we are in the background, then check to see if this process
2872                // is bad.  If so, we will just silently fail.
2873                if (mBadProcesses.get(info.processName, info.uid) != null) {
2874                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2875                            + "/" + info.processName);
2876                    return null;
2877                }
2878            } else {
2879                // When the user is explicitly starting a process, then clear its
2880                // crash count so that we won't make it bad until they see at
2881                // least one crash dialog again, and make the process good again
2882                // if it had been bad.
2883                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2884                        + "/" + info.processName);
2885                mProcessCrashTimes.remove(info.processName, info.uid);
2886                if (mBadProcesses.get(info.processName, info.uid) != null) {
2887                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2888                            UserHandle.getUserId(info.uid), info.uid,
2889                            info.processName);
2890                    mBadProcesses.remove(info.processName, info.uid);
2891                    if (app != null) {
2892                        app.bad = false;
2893                    }
2894                }
2895            }
2896        }
2897
2898        if (app == null) {
2899            app = newProcessRecordLocked(info, processName, isolated);
2900            if (app == null) {
2901                Slog.w(TAG, "Failed making new process record for "
2902                        + processName + "/" + info.uid + " isolated=" + isolated);
2903                return null;
2904            }
2905            mProcessNames.put(processName, app.uid, app);
2906            if (isolated) {
2907                mIsolatedProcesses.put(app.uid, app);
2908            }
2909        } else {
2910            // If this is a new package in the process, add the package to the list
2911            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2912        }
2913
2914        // If the system is not ready yet, then hold off on starting this
2915        // process until it is.
2916        if (!mProcessesReady
2917                && !isAllowedWhileBooting(info)
2918                && !allowWhileBooting) {
2919            if (!mProcessesOnHold.contains(app)) {
2920                mProcessesOnHold.add(app);
2921            }
2922            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2923            return app;
2924        }
2925
2926        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2927        return (app.pid != 0) ? app : null;
2928    }
2929
2930    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2931        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2932    }
2933
2934    private final void startProcessLocked(ProcessRecord app,
2935            String hostingType, String hostingNameStr, String abiOverride) {
2936        if (app.pid > 0 && app.pid != MY_PID) {
2937            synchronized (mPidsSelfLocked) {
2938                mPidsSelfLocked.remove(app.pid);
2939                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2940            }
2941            app.setPid(0);
2942        }
2943
2944        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2945                "startProcessLocked removing on hold: " + app);
2946        mProcessesOnHold.remove(app);
2947
2948        updateCpuStats();
2949
2950        try {
2951            int uid = app.uid;
2952
2953            int[] gids = null;
2954            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2955            if (!app.isolated) {
2956                int[] permGids = null;
2957                try {
2958                    final PackageManager pm = mContext.getPackageManager();
2959                    permGids = pm.getPackageGids(app.info.packageName);
2960
2961                    if (Environment.isExternalStorageEmulated()) {
2962                        if (pm.checkPermission(
2963                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2964                                app.info.packageName) == PERMISSION_GRANTED) {
2965                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2966                        } else {
2967                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2968                        }
2969                    }
2970                } catch (PackageManager.NameNotFoundException e) {
2971                    Slog.w(TAG, "Unable to retrieve gids", e);
2972                }
2973
2974                /*
2975                 * Add shared application and profile GIDs so applications can share some
2976                 * resources like shared libraries and access user-wide resources
2977                 */
2978                if (permGids == null) {
2979                    gids = new int[2];
2980                } else {
2981                    gids = new int[permGids.length + 2];
2982                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2983                }
2984                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2985                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2986            }
2987            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2988                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2989                        && mTopComponent != null
2990                        && app.processName.equals(mTopComponent.getPackageName())) {
2991                    uid = 0;
2992                }
2993                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2994                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2995                    uid = 0;
2996                }
2997            }
2998            int debugFlags = 0;
2999            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3000                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3001                // Also turn on CheckJNI for debuggable apps. It's quite
3002                // awkward to turn on otherwise.
3003                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3004            }
3005            // Run the app in safe mode if its manifest requests so or the
3006            // system is booted in safe mode.
3007            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3008                mSafeMode == true) {
3009                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3010            }
3011            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3012                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3013            }
3014            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3015                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3016            }
3017            if ("1".equals(SystemProperties.get("debug.assert"))) {
3018                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3019            }
3020
3021            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3022            if (requiredAbi == null) {
3023                requiredAbi = Build.SUPPORTED_ABIS[0];
3024            }
3025
3026            // Start the process.  It will either succeed and return a result containing
3027            // the PID of the new process, or else throw a RuntimeException.
3028            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
3029                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3030                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
3031
3032            if (app.isolated) {
3033                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3034            }
3035            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3036
3037            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3038                    UserHandle.getUserId(uid), startResult.pid, uid,
3039                    app.processName, hostingType,
3040                    hostingNameStr != null ? hostingNameStr : "");
3041
3042            if (app.persistent) {
3043                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3044            }
3045
3046            StringBuilder buf = mStringBuilder;
3047            buf.setLength(0);
3048            buf.append("Start proc ");
3049            buf.append(app.processName);
3050            buf.append(" for ");
3051            buf.append(hostingType);
3052            if (hostingNameStr != null) {
3053                buf.append(" ");
3054                buf.append(hostingNameStr);
3055            }
3056            buf.append(": pid=");
3057            buf.append(startResult.pid);
3058            buf.append(" uid=");
3059            buf.append(uid);
3060            buf.append(" gids={");
3061            if (gids != null) {
3062                for (int gi=0; gi<gids.length; gi++) {
3063                    if (gi != 0) buf.append(", ");
3064                    buf.append(gids[gi]);
3065
3066                }
3067            }
3068            buf.append("}");
3069            if (requiredAbi != null) {
3070                buf.append(" abi=");
3071                buf.append(requiredAbi);
3072            }
3073            Slog.i(TAG, buf.toString());
3074            app.setPid(startResult.pid);
3075            app.usingWrapper = startResult.usingWrapper;
3076            app.removed = false;
3077            app.killedByAm = false;
3078            synchronized (mPidsSelfLocked) {
3079                this.mPidsSelfLocked.put(startResult.pid, app);
3080                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3081                msg.obj = app;
3082                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3083                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3084            }
3085        } catch (RuntimeException e) {
3086            // XXX do better error recovery.
3087            app.setPid(0);
3088            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3089            if (app.isolated) {
3090                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3091            }
3092            Slog.e(TAG, "Failure starting process " + app.processName, e);
3093        }
3094    }
3095
3096    void updateUsageStats(ActivityRecord component, boolean resumed) {
3097        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3098        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3099        if (resumed) {
3100            if (mUsageStatsService != null) {
3101                mUsageStatsService.reportEvent(component.realActivity, System.currentTimeMillis(),
3102                        UsageStats.Event.MOVE_TO_FOREGROUND);
3103            }
3104            synchronized (stats) {
3105                stats.noteActivityResumedLocked(component.app.uid);
3106            }
3107        } else {
3108            if (mUsageStatsService != null) {
3109                mUsageStatsService.reportEvent(component.realActivity, System.currentTimeMillis(),
3110                        UsageStats.Event.MOVE_TO_BACKGROUND);
3111            }
3112            synchronized (stats) {
3113                stats.noteActivityPausedLocked(component.app.uid);
3114            }
3115        }
3116    }
3117
3118    Intent getHomeIntent() {
3119        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3120        intent.setComponent(mTopComponent);
3121        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3122            intent.addCategory(Intent.CATEGORY_HOME);
3123        }
3124        return intent;
3125    }
3126
3127    boolean startHomeActivityLocked(int userId) {
3128        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3129                && mTopAction == null) {
3130            // We are running in factory test mode, but unable to find
3131            // the factory test app, so just sit around displaying the
3132            // error message and don't try to start anything.
3133            return false;
3134        }
3135        Intent intent = getHomeIntent();
3136        ActivityInfo aInfo =
3137            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3138        if (aInfo != null) {
3139            intent.setComponent(new ComponentName(
3140                    aInfo.applicationInfo.packageName, aInfo.name));
3141            // Don't do this if the home app is currently being
3142            // instrumented.
3143            aInfo = new ActivityInfo(aInfo);
3144            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3145            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3146                    aInfo.applicationInfo.uid, true);
3147            if (app == null || app.instrumentationClass == null) {
3148                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3149                mStackSupervisor.startHomeActivity(intent, aInfo);
3150            }
3151        }
3152
3153        return true;
3154    }
3155
3156    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3157        ActivityInfo ai = null;
3158        ComponentName comp = intent.getComponent();
3159        try {
3160            if (comp != null) {
3161                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3162            } else {
3163                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3164                        intent,
3165                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3166                            flags, userId);
3167
3168                if (info != null) {
3169                    ai = info.activityInfo;
3170                }
3171            }
3172        } catch (RemoteException e) {
3173            // ignore
3174        }
3175
3176        return ai;
3177    }
3178
3179    /**
3180     * Starts the "new version setup screen" if appropriate.
3181     */
3182    void startSetupActivityLocked() {
3183        // Only do this once per boot.
3184        if (mCheckedForSetup) {
3185            return;
3186        }
3187
3188        // We will show this screen if the current one is a different
3189        // version than the last one shown, and we are not running in
3190        // low-level factory test mode.
3191        final ContentResolver resolver = mContext.getContentResolver();
3192        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3193                Settings.Global.getInt(resolver,
3194                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3195            mCheckedForSetup = true;
3196
3197            // See if we should be showing the platform update setup UI.
3198            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3199            List<ResolveInfo> ris = mContext.getPackageManager()
3200                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3201
3202            // We don't allow third party apps to replace this.
3203            ResolveInfo ri = null;
3204            for (int i=0; ris != null && i<ris.size(); i++) {
3205                if ((ris.get(i).activityInfo.applicationInfo.flags
3206                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3207                    ri = ris.get(i);
3208                    break;
3209                }
3210            }
3211
3212            if (ri != null) {
3213                String vers = ri.activityInfo.metaData != null
3214                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3215                        : null;
3216                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3217                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3218                            Intent.METADATA_SETUP_VERSION);
3219                }
3220                String lastVers = Settings.Secure.getString(
3221                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3222                if (vers != null && !vers.equals(lastVers)) {
3223                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3224                    intent.setComponent(new ComponentName(
3225                            ri.activityInfo.packageName, ri.activityInfo.name));
3226                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3227                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3228                }
3229            }
3230        }
3231    }
3232
3233    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3234        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3235    }
3236
3237    void enforceNotIsolatedCaller(String caller) {
3238        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3239            throw new SecurityException("Isolated process not allowed to call " + caller);
3240        }
3241    }
3242
3243    @Override
3244    public int getFrontActivityScreenCompatMode() {
3245        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3246        synchronized (this) {
3247            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3248        }
3249    }
3250
3251    @Override
3252    public void setFrontActivityScreenCompatMode(int mode) {
3253        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3254                "setFrontActivityScreenCompatMode");
3255        synchronized (this) {
3256            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3257        }
3258    }
3259
3260    @Override
3261    public int getPackageScreenCompatMode(String packageName) {
3262        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3263        synchronized (this) {
3264            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3265        }
3266    }
3267
3268    @Override
3269    public void setPackageScreenCompatMode(String packageName, int mode) {
3270        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3271                "setPackageScreenCompatMode");
3272        synchronized (this) {
3273            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3274        }
3275    }
3276
3277    @Override
3278    public boolean getPackageAskScreenCompat(String packageName) {
3279        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3280        synchronized (this) {
3281            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3282        }
3283    }
3284
3285    @Override
3286    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3287        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3288                "setPackageAskScreenCompat");
3289        synchronized (this) {
3290            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3291        }
3292    }
3293
3294    private void dispatchProcessesChanged() {
3295        int N;
3296        synchronized (this) {
3297            N = mPendingProcessChanges.size();
3298            if (mActiveProcessChanges.length < N) {
3299                mActiveProcessChanges = new ProcessChangeItem[N];
3300            }
3301            mPendingProcessChanges.toArray(mActiveProcessChanges);
3302            mAvailProcessChanges.addAll(mPendingProcessChanges);
3303            mPendingProcessChanges.clear();
3304            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3305        }
3306
3307        int i = mProcessObservers.beginBroadcast();
3308        while (i > 0) {
3309            i--;
3310            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3311            if (observer != null) {
3312                try {
3313                    for (int j=0; j<N; j++) {
3314                        ProcessChangeItem item = mActiveProcessChanges[j];
3315                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3316                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3317                                    + item.pid + " uid=" + item.uid + ": "
3318                                    + item.foregroundActivities);
3319                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3320                                    item.foregroundActivities);
3321                        }
3322                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3323                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3324                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3325                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3326                        }
3327                    }
3328                } catch (RemoteException e) {
3329                }
3330            }
3331        }
3332        mProcessObservers.finishBroadcast();
3333    }
3334
3335    private void dispatchProcessDied(int pid, int uid) {
3336        int i = mProcessObservers.beginBroadcast();
3337        while (i > 0) {
3338            i--;
3339            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3340            if (observer != null) {
3341                try {
3342                    observer.onProcessDied(pid, uid);
3343                } catch (RemoteException e) {
3344                }
3345            }
3346        }
3347        mProcessObservers.finishBroadcast();
3348    }
3349
3350    @Override
3351    public final int startActivity(IApplicationThread caller, String callingPackage,
3352            Intent intent, String resolvedType, IBinder resultTo,
3353            String resultWho, int requestCode, int startFlags,
3354            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3355        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3356                resultWho, requestCode,
3357                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3358    }
3359
3360    @Override
3361    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3362            Intent intent, String resolvedType, IBinder resultTo,
3363            String resultWho, int requestCode, int startFlags,
3364            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3365        enforceNotIsolatedCaller("startActivity");
3366        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3367                false, ALLOW_FULL_ONLY, "startActivity", null);
3368        // TODO: Switch to user app stacks here.
3369        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3370                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3371                null, null, options, userId, null);
3372    }
3373
3374    @Override
3375    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3376            Intent intent, String resolvedType, IBinder resultTo,
3377            String resultWho, int requestCode, int startFlags, String profileFile,
3378            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3379        enforceNotIsolatedCaller("startActivityAndWait");
3380        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3381                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3382        WaitResult res = new WaitResult();
3383        // TODO: Switch to user app stacks here.
3384        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3385                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3386                res, null, options, userId, null);
3387        return res;
3388    }
3389
3390    @Override
3391    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3392            Intent intent, String resolvedType, IBinder resultTo,
3393            String resultWho, int requestCode, int startFlags, Configuration config,
3394            Bundle options, int userId) {
3395        enforceNotIsolatedCaller("startActivityWithConfig");
3396        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3397                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3398        // TODO: Switch to user app stacks here.
3399        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3400                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3401                null, null, null, config, options, userId, null);
3402        return ret;
3403    }
3404
3405    @Override
3406    public int startActivityIntentSender(IApplicationThread caller,
3407            IntentSender intent, Intent fillInIntent, String resolvedType,
3408            IBinder resultTo, String resultWho, int requestCode,
3409            int flagsMask, int flagsValues, Bundle options) {
3410        enforceNotIsolatedCaller("startActivityIntentSender");
3411        // Refuse possible leaked file descriptors
3412        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3413            throw new IllegalArgumentException("File descriptors passed in Intent");
3414        }
3415
3416        IIntentSender sender = intent.getTarget();
3417        if (!(sender instanceof PendingIntentRecord)) {
3418            throw new IllegalArgumentException("Bad PendingIntent object");
3419        }
3420
3421        PendingIntentRecord pir = (PendingIntentRecord)sender;
3422
3423        synchronized (this) {
3424            // If this is coming from the currently resumed activity, it is
3425            // effectively saying that app switches are allowed at this point.
3426            final ActivityStack stack = getFocusedStack();
3427            if (stack.mResumedActivity != null &&
3428                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3429                mAppSwitchesAllowedTime = 0;
3430            }
3431        }
3432        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3433                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3434        return ret;
3435    }
3436
3437    @Override
3438    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3439            Intent intent, String resolvedType, IVoiceInteractionSession session,
3440            IVoiceInteractor interactor, int startFlags, String profileFile,
3441            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3442        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3443                != PackageManager.PERMISSION_GRANTED) {
3444            String msg = "Permission Denial: startVoiceActivity() from pid="
3445                    + Binder.getCallingPid()
3446                    + ", uid=" + Binder.getCallingUid()
3447                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3448            Slog.w(TAG, msg);
3449            throw new SecurityException(msg);
3450        }
3451        if (session == null || interactor == null) {
3452            throw new NullPointerException("null session or interactor");
3453        }
3454        userId = handleIncomingUser(callingPid, callingUid, userId,
3455                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3456        // TODO: Switch to user app stacks here.
3457        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3458                resolvedType, session, interactor, null, null, 0, startFlags,
3459                profileFile, profileFd, null, null, options, userId, null);
3460    }
3461
3462    @Override
3463    public boolean startNextMatchingActivity(IBinder callingActivity,
3464            Intent intent, Bundle options) {
3465        // Refuse possible leaked file descriptors
3466        if (intent != null && intent.hasFileDescriptors() == true) {
3467            throw new IllegalArgumentException("File descriptors passed in Intent");
3468        }
3469
3470        synchronized (this) {
3471            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3472            if (r == null) {
3473                ActivityOptions.abort(options);
3474                return false;
3475            }
3476            if (r.app == null || r.app.thread == null) {
3477                // The caller is not running...  d'oh!
3478                ActivityOptions.abort(options);
3479                return false;
3480            }
3481            intent = new Intent(intent);
3482            // The caller is not allowed to change the data.
3483            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3484            // And we are resetting to find the next component...
3485            intent.setComponent(null);
3486
3487            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3488
3489            ActivityInfo aInfo = null;
3490            try {
3491                List<ResolveInfo> resolves =
3492                    AppGlobals.getPackageManager().queryIntentActivities(
3493                            intent, r.resolvedType,
3494                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3495                            UserHandle.getCallingUserId());
3496
3497                // Look for the original activity in the list...
3498                final int N = resolves != null ? resolves.size() : 0;
3499                for (int i=0; i<N; i++) {
3500                    ResolveInfo rInfo = resolves.get(i);
3501                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3502                            && rInfo.activityInfo.name.equals(r.info.name)) {
3503                        // We found the current one...  the next matching is
3504                        // after it.
3505                        i++;
3506                        if (i<N) {
3507                            aInfo = resolves.get(i).activityInfo;
3508                        }
3509                        if (debug) {
3510                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3511                                    + "/" + r.info.name);
3512                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3513                                    + "/" + aInfo.name);
3514                        }
3515                        break;
3516                    }
3517                }
3518            } catch (RemoteException e) {
3519            }
3520
3521            if (aInfo == null) {
3522                // Nobody who is next!
3523                ActivityOptions.abort(options);
3524                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3525                return false;
3526            }
3527
3528            intent.setComponent(new ComponentName(
3529                    aInfo.applicationInfo.packageName, aInfo.name));
3530            intent.setFlags(intent.getFlags()&~(
3531                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3532                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3533                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3534                    Intent.FLAG_ACTIVITY_NEW_TASK));
3535
3536            // Okay now we need to start the new activity, replacing the
3537            // currently running activity.  This is a little tricky because
3538            // we want to start the new one as if the current one is finished,
3539            // but not finish the current one first so that there is no flicker.
3540            // And thus...
3541            final boolean wasFinishing = r.finishing;
3542            r.finishing = true;
3543
3544            // Propagate reply information over to the new activity.
3545            final ActivityRecord resultTo = r.resultTo;
3546            final String resultWho = r.resultWho;
3547            final int requestCode = r.requestCode;
3548            r.resultTo = null;
3549            if (resultTo != null) {
3550                resultTo.removeResultsLocked(r, resultWho, requestCode);
3551            }
3552
3553            final long origId = Binder.clearCallingIdentity();
3554            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3555                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3556                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3557                    options, false, null, null);
3558            Binder.restoreCallingIdentity(origId);
3559
3560            r.finishing = wasFinishing;
3561            if (res != ActivityManager.START_SUCCESS) {
3562                return false;
3563            }
3564            return true;
3565        }
3566    }
3567
3568    @Override
3569    public final int startActivityFromRecents(int taskId, Bundle options) {
3570        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3571            String msg = "Permission Denial: startActivityFromRecents called without " +
3572                    START_TASKS_FROM_RECENTS;
3573            Slog.w(TAG, msg);
3574            throw new SecurityException(msg);
3575        }
3576        final int callingUid;
3577        final String callingPackage;
3578        final Intent intent;
3579        final int userId;
3580        synchronized (this) {
3581            final TaskRecord task = recentTaskForIdLocked(taskId);
3582            if (task == null) {
3583                throw new ActivityNotFoundException("Task " + taskId + " not found.");
3584            }
3585            callingUid = task.mCallingUid;
3586            callingPackage = task.mCallingPackage;
3587            intent = task.intent;
3588            userId = task.userId;
3589        }
3590        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3591                options, userId, null);
3592    }
3593
3594    final int startActivityInPackage(int uid, String callingPackage,
3595            Intent intent, String resolvedType, IBinder resultTo,
3596            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3597                    IActivityContainer container) {
3598
3599        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3600                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3601
3602        // TODO: Switch to user app stacks here.
3603        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3604                null, null, resultTo, resultWho, requestCode, startFlags,
3605                null, null, null, null, options, userId, container);
3606        return ret;
3607    }
3608
3609    @Override
3610    public final int startActivities(IApplicationThread caller, String callingPackage,
3611            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3612            int userId) {
3613        enforceNotIsolatedCaller("startActivities");
3614        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3615                false, ALLOW_FULL_ONLY, "startActivity", null);
3616        // TODO: Switch to user app stacks here.
3617        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3618                resolvedTypes, resultTo, options, userId);
3619        return ret;
3620    }
3621
3622    final int startActivitiesInPackage(int uid, String callingPackage,
3623            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3624            Bundle options, int userId) {
3625
3626        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3627                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3628        // TODO: Switch to user app stacks here.
3629        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3630                resultTo, options, userId);
3631        return ret;
3632    }
3633
3634    final void addRecentTaskLocked(TaskRecord task) {
3635        int N = mRecentTasks.size();
3636        // Quick case: check if the top-most recent task is the same.
3637        if (N > 0 && mRecentTasks.get(0) == task) {
3638            return;
3639        }
3640        // Another quick case: never add voice sessions.
3641        if (task.voiceSession != null) {
3642            return;
3643        }
3644        // Remove any existing entries that are the same kind of task.
3645        final Intent intent = task.intent;
3646        final boolean document = intent != null && intent.isDocument();
3647        final ComponentName comp = intent.getComponent();
3648
3649        int maxRecents = task.maxRecents - 1;
3650        for (int i=0; i<N; i++) {
3651            final TaskRecord tr = mRecentTasks.get(i);
3652            if (task != tr) {
3653                if (task.userId != tr.userId) {
3654                    continue;
3655                }
3656                if (i > MAX_RECENT_BITMAPS) {
3657                    tr.freeLastThumbnail();
3658                }
3659                final Intent trIntent = tr.intent;
3660                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3661                    (intent == null || !intent.filterEquals(trIntent))) {
3662                    continue;
3663                }
3664                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3665                if (document && trIsDocument) {
3666                    // These are the same document activity (not necessarily the same doc).
3667                    if (maxRecents > 0) {
3668                        --maxRecents;
3669                        continue;
3670                    }
3671                    // Hit the maximum number of documents for this task. Fall through
3672                    // and remove this document from recents.
3673                } else if (document || trIsDocument) {
3674                    // Only one of these is a document. Not the droid we're looking for.
3675                    continue;
3676                }
3677            }
3678
3679            // Either task and tr are the same or, their affinities match or their intents match
3680            // and neither of them is a document, or they are documents using the same activity
3681            // and their maxRecents has been reached.
3682            tr.disposeThumbnail();
3683            mRecentTasks.remove(i);
3684            if (task != tr) {
3685                tr.closeRecentsChain();
3686            }
3687            i--;
3688            N--;
3689            if (task.intent == null) {
3690                // If the new recent task we are adding is not fully
3691                // specified, then replace it with the existing recent task.
3692                task = tr;
3693            }
3694            mTaskPersister.notify(tr, false);
3695        }
3696        if (N >= MAX_RECENT_TASKS) {
3697            final TaskRecord tr = mRecentTasks.remove(N - 1);
3698            tr.disposeThumbnail();
3699            tr.closeRecentsChain();
3700        }
3701        mRecentTasks.add(0, task);
3702    }
3703
3704    @Override
3705    public void reportActivityFullyDrawn(IBinder token) {
3706        synchronized (this) {
3707            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3708            if (r == null) {
3709                return;
3710            }
3711            r.reportFullyDrawnLocked();
3712        }
3713    }
3714
3715    @Override
3716    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3717        synchronized (this) {
3718            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3719            if (r == null) {
3720                return;
3721            }
3722            final long origId = Binder.clearCallingIdentity();
3723            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3724            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3725                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3726            if (config != null) {
3727                r.frozenBeforeDestroy = true;
3728                if (!updateConfigurationLocked(config, r, false, false)) {
3729                    mStackSupervisor.resumeTopActivitiesLocked();
3730                }
3731            }
3732            Binder.restoreCallingIdentity(origId);
3733        }
3734    }
3735
3736    @Override
3737    public int getRequestedOrientation(IBinder token) {
3738        synchronized (this) {
3739            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3740            if (r == null) {
3741                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3742            }
3743            return mWindowManager.getAppOrientation(r.appToken);
3744        }
3745    }
3746
3747    /**
3748     * This is the internal entry point for handling Activity.finish().
3749     *
3750     * @param token The Binder token referencing the Activity we want to finish.
3751     * @param resultCode Result code, if any, from this Activity.
3752     * @param resultData Result data (Intent), if any, from this Activity.
3753     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3754     *            the root Activity in the task.
3755     *
3756     * @return Returns true if the activity successfully finished, or false if it is still running.
3757     */
3758    @Override
3759    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3760            boolean finishTask) {
3761        // Refuse possible leaked file descriptors
3762        if (resultData != null && resultData.hasFileDescriptors() == true) {
3763            throw new IllegalArgumentException("File descriptors passed in Intent");
3764        }
3765
3766        synchronized(this) {
3767            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3768            if (r == null) {
3769                return true;
3770            }
3771            // Keep track of the root activity of the task before we finish it
3772            TaskRecord tr = r.task;
3773            ActivityRecord rootR = tr.getRootActivity();
3774            // Do not allow task to finish in Lock Task mode.
3775            if (tr == mStackSupervisor.mLockTaskModeTask) {
3776                if (rootR == r) {
3777                    mStackSupervisor.showLockTaskToast();
3778                    return false;
3779                }
3780            }
3781            if (mController != null) {
3782                // Find the first activity that is not finishing.
3783                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3784                if (next != null) {
3785                    // ask watcher if this is allowed
3786                    boolean resumeOK = true;
3787                    try {
3788                        resumeOK = mController.activityResuming(next.packageName);
3789                    } catch (RemoteException e) {
3790                        mController = null;
3791                        Watchdog.getInstance().setActivityController(null);
3792                    }
3793
3794                    if (!resumeOK) {
3795                        return false;
3796                    }
3797                }
3798            }
3799            final long origId = Binder.clearCallingIdentity();
3800            try {
3801                boolean res;
3802                if (finishTask && r == rootR) {
3803                    // If requested, remove the task that is associated to this activity only if it
3804                    // was the root activity in the task.  The result code and data is ignored because
3805                    // we don't support returning them across task boundaries.
3806                    res = removeTaskByIdLocked(tr.taskId, 0);
3807                } else {
3808                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3809                            resultData, "app-request", true);
3810                }
3811                return res;
3812            } finally {
3813                Binder.restoreCallingIdentity(origId);
3814            }
3815        }
3816    }
3817
3818    @Override
3819    public final void finishHeavyWeightApp() {
3820        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3821                != PackageManager.PERMISSION_GRANTED) {
3822            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3823                    + Binder.getCallingPid()
3824                    + ", uid=" + Binder.getCallingUid()
3825                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3826            Slog.w(TAG, msg);
3827            throw new SecurityException(msg);
3828        }
3829
3830        synchronized(this) {
3831            if (mHeavyWeightProcess == null) {
3832                return;
3833            }
3834
3835            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3836                    mHeavyWeightProcess.activities);
3837            for (int i=0; i<activities.size(); i++) {
3838                ActivityRecord r = activities.get(i);
3839                if (!r.finishing) {
3840                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3841                            null, "finish-heavy", true);
3842                }
3843            }
3844
3845            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3846                    mHeavyWeightProcess.userId, 0));
3847            mHeavyWeightProcess = null;
3848        }
3849    }
3850
3851    @Override
3852    public void crashApplication(int uid, int initialPid, String packageName,
3853            String message) {
3854        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3855                != PackageManager.PERMISSION_GRANTED) {
3856            String msg = "Permission Denial: crashApplication() from pid="
3857                    + Binder.getCallingPid()
3858                    + ", uid=" + Binder.getCallingUid()
3859                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3860            Slog.w(TAG, msg);
3861            throw new SecurityException(msg);
3862        }
3863
3864        synchronized(this) {
3865            ProcessRecord proc = null;
3866
3867            // Figure out which process to kill.  We don't trust that initialPid
3868            // still has any relation to current pids, so must scan through the
3869            // list.
3870            synchronized (mPidsSelfLocked) {
3871                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3872                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3873                    if (p.uid != uid) {
3874                        continue;
3875                    }
3876                    if (p.pid == initialPid) {
3877                        proc = p;
3878                        break;
3879                    }
3880                    if (p.pkgList.containsKey(packageName)) {
3881                        proc = p;
3882                    }
3883                }
3884            }
3885
3886            if (proc == null) {
3887                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3888                        + " initialPid=" + initialPid
3889                        + " packageName=" + packageName);
3890                return;
3891            }
3892
3893            if (proc.thread != null) {
3894                if (proc.pid == Process.myPid()) {
3895                    Log.w(TAG, "crashApplication: trying to crash self!");
3896                    return;
3897                }
3898                long ident = Binder.clearCallingIdentity();
3899                try {
3900                    proc.thread.scheduleCrash(message);
3901                } catch (RemoteException e) {
3902                }
3903                Binder.restoreCallingIdentity(ident);
3904            }
3905        }
3906    }
3907
3908    @Override
3909    public final void finishSubActivity(IBinder token, String resultWho,
3910            int requestCode) {
3911        synchronized(this) {
3912            final long origId = Binder.clearCallingIdentity();
3913            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3914            if (r != null) {
3915                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3916            }
3917            Binder.restoreCallingIdentity(origId);
3918        }
3919    }
3920
3921    @Override
3922    public boolean finishActivityAffinity(IBinder token) {
3923        synchronized(this) {
3924            final long origId = Binder.clearCallingIdentity();
3925            try {
3926                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3927
3928                ActivityRecord rootR = r.task.getRootActivity();
3929                // Do not allow task to finish in Lock Task mode.
3930                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3931                    if (rootR == r) {
3932                        mStackSupervisor.showLockTaskToast();
3933                        return false;
3934                    }
3935                }
3936                boolean res = false;
3937                if (r != null) {
3938                    res = r.task.stack.finishActivityAffinityLocked(r);
3939                }
3940                return res;
3941            } finally {
3942                Binder.restoreCallingIdentity(origId);
3943            }
3944        }
3945    }
3946
3947    @Override
3948    public void finishVoiceTask(IVoiceInteractionSession session) {
3949        synchronized(this) {
3950            final long origId = Binder.clearCallingIdentity();
3951            try {
3952                mStackSupervisor.finishVoiceTask(session);
3953            } finally {
3954                Binder.restoreCallingIdentity(origId);
3955            }
3956        }
3957
3958    }
3959
3960    @Override
3961    public boolean willActivityBeVisible(IBinder token) {
3962        synchronized(this) {
3963            ActivityStack stack = ActivityRecord.getStackLocked(token);
3964            if (stack != null) {
3965                return stack.willActivityBeVisibleLocked(token);
3966            }
3967            return false;
3968        }
3969    }
3970
3971    @Override
3972    public void overridePendingTransition(IBinder token, String packageName,
3973            int enterAnim, int exitAnim) {
3974        synchronized(this) {
3975            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3976            if (self == null) {
3977                return;
3978            }
3979
3980            final long origId = Binder.clearCallingIdentity();
3981
3982            if (self.state == ActivityState.RESUMED
3983                    || self.state == ActivityState.PAUSING) {
3984                mWindowManager.overridePendingAppTransition(packageName,
3985                        enterAnim, exitAnim, null);
3986            }
3987
3988            Binder.restoreCallingIdentity(origId);
3989        }
3990    }
3991
3992    /**
3993     * Main function for removing an existing process from the activity manager
3994     * as a result of that process going away.  Clears out all connections
3995     * to the process.
3996     */
3997    private final void handleAppDiedLocked(ProcessRecord app,
3998            boolean restarting, boolean allowRestart) {
3999        int pid = app.pid;
4000        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4001        if (!restarting) {
4002            removeLruProcessLocked(app);
4003            if (pid > 0) {
4004                ProcessList.remove(pid);
4005            }
4006        }
4007
4008        if (mProfileProc == app) {
4009            clearProfilerLocked();
4010        }
4011
4012        // Remove this application's activities from active lists.
4013        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4014
4015        app.activities.clear();
4016
4017        if (app.instrumentationClass != null) {
4018            Slog.w(TAG, "Crash of app " + app.processName
4019                  + " running instrumentation " + app.instrumentationClass);
4020            Bundle info = new Bundle();
4021            info.putString("shortMsg", "Process crashed.");
4022            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4023        }
4024
4025        if (!restarting) {
4026            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4027                // If there was nothing to resume, and we are not already
4028                // restarting this process, but there is a visible activity that
4029                // is hosted by the process...  then make sure all visible
4030                // activities are running, taking care of restarting this
4031                // process.
4032                if (hasVisibleActivities) {
4033                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4034                }
4035            }
4036        }
4037    }
4038
4039    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4040        IBinder threadBinder = thread.asBinder();
4041        // Find the application record.
4042        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4043            ProcessRecord rec = mLruProcesses.get(i);
4044            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4045                return i;
4046            }
4047        }
4048        return -1;
4049    }
4050
4051    final ProcessRecord getRecordForAppLocked(
4052            IApplicationThread thread) {
4053        if (thread == null) {
4054            return null;
4055        }
4056
4057        int appIndex = getLRURecordIndexForAppLocked(thread);
4058        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4059    }
4060
4061    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4062        // If there are no longer any background processes running,
4063        // and the app that died was not running instrumentation,
4064        // then tell everyone we are now low on memory.
4065        boolean haveBg = false;
4066        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4067            ProcessRecord rec = mLruProcesses.get(i);
4068            if (rec.thread != null
4069                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4070                haveBg = true;
4071                break;
4072            }
4073        }
4074
4075        if (!haveBg) {
4076            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4077            if (doReport) {
4078                long now = SystemClock.uptimeMillis();
4079                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4080                    doReport = false;
4081                } else {
4082                    mLastMemUsageReportTime = now;
4083                }
4084            }
4085            final ArrayList<ProcessMemInfo> memInfos
4086                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4087            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4088            long now = SystemClock.uptimeMillis();
4089            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4090                ProcessRecord rec = mLruProcesses.get(i);
4091                if (rec == dyingProc || rec.thread == null) {
4092                    continue;
4093                }
4094                if (doReport) {
4095                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4096                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4097                }
4098                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4099                    // The low memory report is overriding any current
4100                    // state for a GC request.  Make sure to do
4101                    // heavy/important/visible/foreground processes first.
4102                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4103                        rec.lastRequestedGc = 0;
4104                    } else {
4105                        rec.lastRequestedGc = rec.lastLowMemory;
4106                    }
4107                    rec.reportLowMemory = true;
4108                    rec.lastLowMemory = now;
4109                    mProcessesToGc.remove(rec);
4110                    addProcessToGcListLocked(rec);
4111                }
4112            }
4113            if (doReport) {
4114                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4115                mHandler.sendMessage(msg);
4116            }
4117            scheduleAppGcsLocked();
4118        }
4119    }
4120
4121    final void appDiedLocked(ProcessRecord app, int pid,
4122            IApplicationThread thread) {
4123
4124        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4125        synchronized (stats) {
4126            stats.noteProcessDiedLocked(app.info.uid, pid);
4127        }
4128
4129        Process.killProcessGroup(app.info.uid, pid);
4130
4131        // Clean up already done if the process has been re-started.
4132        if (app.pid == pid && app.thread != null &&
4133                app.thread.asBinder() == thread.asBinder()) {
4134            boolean doLowMem = app.instrumentationClass == null;
4135            boolean doOomAdj = doLowMem;
4136            if (!app.killedByAm) {
4137                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4138                        + ") has died.");
4139                mAllowLowerMemLevel = true;
4140            } else {
4141                // Note that we always want to do oom adj to update our state with the
4142                // new number of procs.
4143                mAllowLowerMemLevel = false;
4144                doLowMem = false;
4145            }
4146            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4147            if (DEBUG_CLEANUP) Slog.v(
4148                TAG, "Dying app: " + app + ", pid: " + pid
4149                + ", thread: " + thread.asBinder());
4150            handleAppDiedLocked(app, false, true);
4151
4152            if (doOomAdj) {
4153                updateOomAdjLocked();
4154            }
4155            if (doLowMem) {
4156                doLowMemReportIfNeededLocked(app);
4157            }
4158        } else if (app.pid != pid) {
4159            // A new process has already been started.
4160            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4161                    + ") has died and restarted (pid " + app.pid + ").");
4162            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4163        } else if (DEBUG_PROCESSES) {
4164            Slog.d(TAG, "Received spurious death notification for thread "
4165                    + thread.asBinder());
4166        }
4167    }
4168
4169    /**
4170     * If a stack trace dump file is configured, dump process stack traces.
4171     * @param clearTraces causes the dump file to be erased prior to the new
4172     *    traces being written, if true; when false, the new traces will be
4173     *    appended to any existing file content.
4174     * @param firstPids of dalvik VM processes to dump stack traces for first
4175     * @param lastPids of dalvik VM processes to dump stack traces for last
4176     * @param nativeProcs optional list of native process names to dump stack crawls
4177     * @return file containing stack traces, or null if no dump file is configured
4178     */
4179    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4180            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4181        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4182        if (tracesPath == null || tracesPath.length() == 0) {
4183            return null;
4184        }
4185
4186        File tracesFile = new File(tracesPath);
4187        try {
4188            File tracesDir = tracesFile.getParentFile();
4189            if (!tracesDir.exists()) {
4190                tracesFile.mkdirs();
4191                if (!SELinux.restorecon(tracesDir)) {
4192                    return null;
4193                }
4194            }
4195            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4196
4197            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4198            tracesFile.createNewFile();
4199            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4200        } catch (IOException e) {
4201            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4202            return null;
4203        }
4204
4205        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4206        return tracesFile;
4207    }
4208
4209    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4210            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4211        // Use a FileObserver to detect when traces finish writing.
4212        // The order of traces is considered important to maintain for legibility.
4213        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4214            @Override
4215            public synchronized void onEvent(int event, String path) { notify(); }
4216        };
4217
4218        try {
4219            observer.startWatching();
4220
4221            // First collect all of the stacks of the most important pids.
4222            if (firstPids != null) {
4223                try {
4224                    int num = firstPids.size();
4225                    for (int i = 0; i < num; i++) {
4226                        synchronized (observer) {
4227                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4228                            observer.wait(200);  // Wait for write-close, give up after 200msec
4229                        }
4230                    }
4231                } catch (InterruptedException e) {
4232                    Log.wtf(TAG, e);
4233                }
4234            }
4235
4236            // Next collect the stacks of the native pids
4237            if (nativeProcs != null) {
4238                int[] pids = Process.getPidsForCommands(nativeProcs);
4239                if (pids != null) {
4240                    for (int pid : pids) {
4241                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4242                    }
4243                }
4244            }
4245
4246            // Lastly, measure CPU usage.
4247            if (processCpuTracker != null) {
4248                processCpuTracker.init();
4249                System.gc();
4250                processCpuTracker.update();
4251                try {
4252                    synchronized (processCpuTracker) {
4253                        processCpuTracker.wait(500); // measure over 1/2 second.
4254                    }
4255                } catch (InterruptedException e) {
4256                }
4257                processCpuTracker.update();
4258
4259                // We'll take the stack crawls of just the top apps using CPU.
4260                final int N = processCpuTracker.countWorkingStats();
4261                int numProcs = 0;
4262                for (int i=0; i<N && numProcs<5; i++) {
4263                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4264                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4265                        numProcs++;
4266                        try {
4267                            synchronized (observer) {
4268                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4269                                observer.wait(200);  // Wait for write-close, give up after 200msec
4270                            }
4271                        } catch (InterruptedException e) {
4272                            Log.wtf(TAG, e);
4273                        }
4274
4275                    }
4276                }
4277            }
4278        } finally {
4279            observer.stopWatching();
4280        }
4281    }
4282
4283    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4284        if (true || IS_USER_BUILD) {
4285            return;
4286        }
4287        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4288        if (tracesPath == null || tracesPath.length() == 0) {
4289            return;
4290        }
4291
4292        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4293        StrictMode.allowThreadDiskWrites();
4294        try {
4295            final File tracesFile = new File(tracesPath);
4296            final File tracesDir = tracesFile.getParentFile();
4297            final File tracesTmp = new File(tracesDir, "__tmp__");
4298            try {
4299                if (!tracesDir.exists()) {
4300                    tracesFile.mkdirs();
4301                    if (!SELinux.restorecon(tracesDir.getPath())) {
4302                        return;
4303                    }
4304                }
4305                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4306
4307                if (tracesFile.exists()) {
4308                    tracesTmp.delete();
4309                    tracesFile.renameTo(tracesTmp);
4310                }
4311                StringBuilder sb = new StringBuilder();
4312                Time tobj = new Time();
4313                tobj.set(System.currentTimeMillis());
4314                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4315                sb.append(": ");
4316                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4317                sb.append(" since ");
4318                sb.append(msg);
4319                FileOutputStream fos = new FileOutputStream(tracesFile);
4320                fos.write(sb.toString().getBytes());
4321                if (app == null) {
4322                    fos.write("\n*** No application process!".getBytes());
4323                }
4324                fos.close();
4325                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4326            } catch (IOException e) {
4327                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4328                return;
4329            }
4330
4331            if (app != null) {
4332                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4333                firstPids.add(app.pid);
4334                dumpStackTraces(tracesPath, firstPids, null, null, null);
4335            }
4336
4337            File lastTracesFile = null;
4338            File curTracesFile = null;
4339            for (int i=9; i>=0; i--) {
4340                String name = String.format(Locale.US, "slow%02d.txt", i);
4341                curTracesFile = new File(tracesDir, name);
4342                if (curTracesFile.exists()) {
4343                    if (lastTracesFile != null) {
4344                        curTracesFile.renameTo(lastTracesFile);
4345                    } else {
4346                        curTracesFile.delete();
4347                    }
4348                }
4349                lastTracesFile = curTracesFile;
4350            }
4351            tracesFile.renameTo(curTracesFile);
4352            if (tracesTmp.exists()) {
4353                tracesTmp.renameTo(tracesFile);
4354            }
4355        } finally {
4356            StrictMode.setThreadPolicy(oldPolicy);
4357        }
4358    }
4359
4360    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4361            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4362        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4363        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4364
4365        if (mController != null) {
4366            try {
4367                // 0 == continue, -1 = kill process immediately
4368                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4369                if (res < 0 && app.pid != MY_PID) {
4370                    Process.killProcess(app.pid);
4371                    Process.killProcessGroup(app.info.uid, app.pid);
4372                }
4373            } catch (RemoteException e) {
4374                mController = null;
4375                Watchdog.getInstance().setActivityController(null);
4376            }
4377        }
4378
4379        long anrTime = SystemClock.uptimeMillis();
4380        if (MONITOR_CPU_USAGE) {
4381            updateCpuStatsNow();
4382        }
4383
4384        synchronized (this) {
4385            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4386            if (mShuttingDown) {
4387                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4388                return;
4389            } else if (app.notResponding) {
4390                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4391                return;
4392            } else if (app.crashing) {
4393                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4394                return;
4395            }
4396
4397            // In case we come through here for the same app before completing
4398            // this one, mark as anring now so we will bail out.
4399            app.notResponding = true;
4400
4401            // Log the ANR to the event log.
4402            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4403                    app.processName, app.info.flags, annotation);
4404
4405            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4406            firstPids.add(app.pid);
4407
4408            int parentPid = app.pid;
4409            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4410            if (parentPid != app.pid) firstPids.add(parentPid);
4411
4412            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4413
4414            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4415                ProcessRecord r = mLruProcesses.get(i);
4416                if (r != null && r.thread != null) {
4417                    int pid = r.pid;
4418                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4419                        if (r.persistent) {
4420                            firstPids.add(pid);
4421                        } else {
4422                            lastPids.put(pid, Boolean.TRUE);
4423                        }
4424                    }
4425                }
4426            }
4427        }
4428
4429        // Log the ANR to the main log.
4430        StringBuilder info = new StringBuilder();
4431        info.setLength(0);
4432        info.append("ANR in ").append(app.processName);
4433        if (activity != null && activity.shortComponentName != null) {
4434            info.append(" (").append(activity.shortComponentName).append(")");
4435        }
4436        info.append("\n");
4437        info.append("PID: ").append(app.pid).append("\n");
4438        if (annotation != null) {
4439            info.append("Reason: ").append(annotation).append("\n");
4440        }
4441        if (parent != null && parent != activity) {
4442            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4443        }
4444
4445        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4446
4447        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4448                NATIVE_STACKS_OF_INTEREST);
4449
4450        String cpuInfo = null;
4451        if (MONITOR_CPU_USAGE) {
4452            updateCpuStatsNow();
4453            synchronized (mProcessCpuThread) {
4454                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4455            }
4456            info.append(processCpuTracker.printCurrentLoad());
4457            info.append(cpuInfo);
4458        }
4459
4460        info.append(processCpuTracker.printCurrentState(anrTime));
4461
4462        Slog.e(TAG, info.toString());
4463        if (tracesFile == null) {
4464            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4465            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4466        }
4467
4468        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4469                cpuInfo, tracesFile, null);
4470
4471        if (mController != null) {
4472            try {
4473                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4474                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4475                if (res != 0) {
4476                    if (res < 0 && app.pid != MY_PID) {
4477                        Process.killProcess(app.pid);
4478                        Process.killProcessGroup(app.info.uid, app.pid);
4479                    } else {
4480                        synchronized (this) {
4481                            mServices.scheduleServiceTimeoutLocked(app);
4482                        }
4483                    }
4484                    return;
4485                }
4486            } catch (RemoteException e) {
4487                mController = null;
4488                Watchdog.getInstance().setActivityController(null);
4489            }
4490        }
4491
4492        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4493        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4494                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4495
4496        synchronized (this) {
4497            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4498                killUnneededProcessLocked(app, "background ANR");
4499                return;
4500            }
4501
4502            // Set the app's notResponding state, and look up the errorReportReceiver
4503            makeAppNotRespondingLocked(app,
4504                    activity != null ? activity.shortComponentName : null,
4505                    annotation != null ? "ANR " + annotation : "ANR",
4506                    info.toString());
4507
4508            // Bring up the infamous App Not Responding dialog
4509            Message msg = Message.obtain();
4510            HashMap<String, Object> map = new HashMap<String, Object>();
4511            msg.what = SHOW_NOT_RESPONDING_MSG;
4512            msg.obj = map;
4513            msg.arg1 = aboveSystem ? 1 : 0;
4514            map.put("app", app);
4515            if (activity != null) {
4516                map.put("activity", activity);
4517            }
4518
4519            mHandler.sendMessage(msg);
4520        }
4521    }
4522
4523    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4524        if (!mLaunchWarningShown) {
4525            mLaunchWarningShown = true;
4526            mHandler.post(new Runnable() {
4527                @Override
4528                public void run() {
4529                    synchronized (ActivityManagerService.this) {
4530                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4531                        d.show();
4532                        mHandler.postDelayed(new Runnable() {
4533                            @Override
4534                            public void run() {
4535                                synchronized (ActivityManagerService.this) {
4536                                    d.dismiss();
4537                                    mLaunchWarningShown = false;
4538                                }
4539                            }
4540                        }, 4000);
4541                    }
4542                }
4543            });
4544        }
4545    }
4546
4547    @Override
4548    public boolean clearApplicationUserData(final String packageName,
4549            final IPackageDataObserver observer, int userId) {
4550        enforceNotIsolatedCaller("clearApplicationUserData");
4551        int uid = Binder.getCallingUid();
4552        int pid = Binder.getCallingPid();
4553        userId = handleIncomingUser(pid, uid,
4554                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4555        long callingId = Binder.clearCallingIdentity();
4556        try {
4557            IPackageManager pm = AppGlobals.getPackageManager();
4558            int pkgUid = -1;
4559            synchronized(this) {
4560                try {
4561                    pkgUid = pm.getPackageUid(packageName, userId);
4562                } catch (RemoteException e) {
4563                }
4564                if (pkgUid == -1) {
4565                    Slog.w(TAG, "Invalid packageName: " + packageName);
4566                    if (observer != null) {
4567                        try {
4568                            observer.onRemoveCompleted(packageName, false);
4569                        } catch (RemoteException e) {
4570                            Slog.i(TAG, "Observer no longer exists.");
4571                        }
4572                    }
4573                    return false;
4574                }
4575                if (uid == pkgUid || checkComponentPermission(
4576                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4577                        pid, uid, -1, true)
4578                        == PackageManager.PERMISSION_GRANTED) {
4579                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4580                } else {
4581                    throw new SecurityException("PID " + pid + " does not have permission "
4582                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4583                                    + " of package " + packageName);
4584                }
4585            }
4586
4587            try {
4588                // Clear application user data
4589                pm.clearApplicationUserData(packageName, observer, userId);
4590
4591                // Remove all permissions granted from/to this package
4592                removeUriPermissionsForPackageLocked(packageName, userId, true);
4593
4594                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4595                        Uri.fromParts("package", packageName, null));
4596                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4597                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4598                        null, null, 0, null, null, null, false, false, userId);
4599            } catch (RemoteException e) {
4600            }
4601        } finally {
4602            Binder.restoreCallingIdentity(callingId);
4603        }
4604        return true;
4605    }
4606
4607    @Override
4608    public void killBackgroundProcesses(final String packageName, int userId) {
4609        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4610                != PackageManager.PERMISSION_GRANTED &&
4611                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4612                        != PackageManager.PERMISSION_GRANTED) {
4613            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4614                    + Binder.getCallingPid()
4615                    + ", uid=" + Binder.getCallingUid()
4616                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4617            Slog.w(TAG, msg);
4618            throw new SecurityException(msg);
4619        }
4620
4621        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4622                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4623        long callingId = Binder.clearCallingIdentity();
4624        try {
4625            IPackageManager pm = AppGlobals.getPackageManager();
4626            synchronized(this) {
4627                int appId = -1;
4628                try {
4629                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4630                } catch (RemoteException e) {
4631                }
4632                if (appId == -1) {
4633                    Slog.w(TAG, "Invalid packageName: " + packageName);
4634                    return;
4635                }
4636                killPackageProcessesLocked(packageName, appId, userId,
4637                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4638            }
4639        } finally {
4640            Binder.restoreCallingIdentity(callingId);
4641        }
4642    }
4643
4644    @Override
4645    public void killAllBackgroundProcesses() {
4646        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4647                != PackageManager.PERMISSION_GRANTED) {
4648            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4649                    + Binder.getCallingPid()
4650                    + ", uid=" + Binder.getCallingUid()
4651                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4652            Slog.w(TAG, msg);
4653            throw new SecurityException(msg);
4654        }
4655
4656        long callingId = Binder.clearCallingIdentity();
4657        try {
4658            synchronized(this) {
4659                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4660                final int NP = mProcessNames.getMap().size();
4661                for (int ip=0; ip<NP; ip++) {
4662                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4663                    final int NA = apps.size();
4664                    for (int ia=0; ia<NA; ia++) {
4665                        ProcessRecord app = apps.valueAt(ia);
4666                        if (app.persistent) {
4667                            // we don't kill persistent processes
4668                            continue;
4669                        }
4670                        if (app.removed) {
4671                            procs.add(app);
4672                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4673                            app.removed = true;
4674                            procs.add(app);
4675                        }
4676                    }
4677                }
4678
4679                int N = procs.size();
4680                for (int i=0; i<N; i++) {
4681                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4682                }
4683                mAllowLowerMemLevel = true;
4684                updateOomAdjLocked();
4685                doLowMemReportIfNeededLocked(null);
4686            }
4687        } finally {
4688            Binder.restoreCallingIdentity(callingId);
4689        }
4690    }
4691
4692    @Override
4693    public void forceStopPackage(final String packageName, int userId) {
4694        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4695                != PackageManager.PERMISSION_GRANTED) {
4696            String msg = "Permission Denial: forceStopPackage() from pid="
4697                    + Binder.getCallingPid()
4698                    + ", uid=" + Binder.getCallingUid()
4699                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4700            Slog.w(TAG, msg);
4701            throw new SecurityException(msg);
4702        }
4703        final int callingPid = Binder.getCallingPid();
4704        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4705                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4706        long callingId = Binder.clearCallingIdentity();
4707        try {
4708            IPackageManager pm = AppGlobals.getPackageManager();
4709            synchronized(this) {
4710                int[] users = userId == UserHandle.USER_ALL
4711                        ? getUsersLocked() : new int[] { userId };
4712                for (int user : users) {
4713                    int pkgUid = -1;
4714                    try {
4715                        pkgUid = pm.getPackageUid(packageName, user);
4716                    } catch (RemoteException e) {
4717                    }
4718                    if (pkgUid == -1) {
4719                        Slog.w(TAG, "Invalid packageName: " + packageName);
4720                        continue;
4721                    }
4722                    try {
4723                        pm.setPackageStoppedState(packageName, true, user);
4724                    } catch (RemoteException e) {
4725                    } catch (IllegalArgumentException e) {
4726                        Slog.w(TAG, "Failed trying to unstop package "
4727                                + packageName + ": " + e);
4728                    }
4729                    if (isUserRunningLocked(user, false)) {
4730                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4731                    }
4732                }
4733            }
4734        } finally {
4735            Binder.restoreCallingIdentity(callingId);
4736        }
4737    }
4738
4739    @Override
4740    public void addPackageDependency(String packageName) {
4741        synchronized (this) {
4742            int callingPid = Binder.getCallingPid();
4743            if (callingPid == Process.myPid()) {
4744                //  Yeah, um, no.
4745                Slog.w(TAG, "Can't addPackageDependency on system process");
4746                return;
4747            }
4748            ProcessRecord proc;
4749            synchronized (mPidsSelfLocked) {
4750                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4751            }
4752            if (proc != null) {
4753                if (proc.pkgDeps == null) {
4754                    proc.pkgDeps = new ArraySet<String>(1);
4755                }
4756                proc.pkgDeps.add(packageName);
4757            }
4758        }
4759    }
4760
4761    /*
4762     * The pkg name and app id have to be specified.
4763     */
4764    @Override
4765    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4766        if (pkg == null) {
4767            return;
4768        }
4769        // Make sure the uid is valid.
4770        if (appid < 0) {
4771            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4772            return;
4773        }
4774        int callerUid = Binder.getCallingUid();
4775        // Only the system server can kill an application
4776        if (callerUid == Process.SYSTEM_UID) {
4777            // Post an aysnc message to kill the application
4778            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4779            msg.arg1 = appid;
4780            msg.arg2 = 0;
4781            Bundle bundle = new Bundle();
4782            bundle.putString("pkg", pkg);
4783            bundle.putString("reason", reason);
4784            msg.obj = bundle;
4785            mHandler.sendMessage(msg);
4786        } else {
4787            throw new SecurityException(callerUid + " cannot kill pkg: " +
4788                    pkg);
4789        }
4790    }
4791
4792    @Override
4793    public void closeSystemDialogs(String reason) {
4794        enforceNotIsolatedCaller("closeSystemDialogs");
4795
4796        final int pid = Binder.getCallingPid();
4797        final int uid = Binder.getCallingUid();
4798        final long origId = Binder.clearCallingIdentity();
4799        try {
4800            synchronized (this) {
4801                // Only allow this from foreground processes, so that background
4802                // applications can't abuse it to prevent system UI from being shown.
4803                if (uid >= Process.FIRST_APPLICATION_UID) {
4804                    ProcessRecord proc;
4805                    synchronized (mPidsSelfLocked) {
4806                        proc = mPidsSelfLocked.get(pid);
4807                    }
4808                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4809                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4810                                + " from background process " + proc);
4811                        return;
4812                    }
4813                }
4814                closeSystemDialogsLocked(reason);
4815            }
4816        } finally {
4817            Binder.restoreCallingIdentity(origId);
4818        }
4819    }
4820
4821    void closeSystemDialogsLocked(String reason) {
4822        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4823        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4824                | Intent.FLAG_RECEIVER_FOREGROUND);
4825        if (reason != null) {
4826            intent.putExtra("reason", reason);
4827        }
4828        mWindowManager.closeSystemDialogs(reason);
4829
4830        mStackSupervisor.closeSystemDialogsLocked();
4831
4832        broadcastIntentLocked(null, null, intent, null,
4833                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4834                Process.SYSTEM_UID, UserHandle.USER_ALL);
4835    }
4836
4837    @Override
4838    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4839        enforceNotIsolatedCaller("getProcessMemoryInfo");
4840        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4841        for (int i=pids.length-1; i>=0; i--) {
4842            ProcessRecord proc;
4843            int oomAdj;
4844            synchronized (this) {
4845                synchronized (mPidsSelfLocked) {
4846                    proc = mPidsSelfLocked.get(pids[i]);
4847                    oomAdj = proc != null ? proc.setAdj : 0;
4848                }
4849            }
4850            infos[i] = new Debug.MemoryInfo();
4851            Debug.getMemoryInfo(pids[i], infos[i]);
4852            if (proc != null) {
4853                synchronized (this) {
4854                    if (proc.thread != null && proc.setAdj == oomAdj) {
4855                        // Record this for posterity if the process has been stable.
4856                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4857                                infos[i].getTotalUss(), false, proc.pkgList);
4858                    }
4859                }
4860            }
4861        }
4862        return infos;
4863    }
4864
4865    @Override
4866    public long[] getProcessPss(int[] pids) {
4867        enforceNotIsolatedCaller("getProcessPss");
4868        long[] pss = new long[pids.length];
4869        for (int i=pids.length-1; i>=0; i--) {
4870            ProcessRecord proc;
4871            int oomAdj;
4872            synchronized (this) {
4873                synchronized (mPidsSelfLocked) {
4874                    proc = mPidsSelfLocked.get(pids[i]);
4875                    oomAdj = proc != null ? proc.setAdj : 0;
4876                }
4877            }
4878            long[] tmpUss = new long[1];
4879            pss[i] = Debug.getPss(pids[i], tmpUss);
4880            if (proc != null) {
4881                synchronized (this) {
4882                    if (proc.thread != null && proc.setAdj == oomAdj) {
4883                        // Record this for posterity if the process has been stable.
4884                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4885                    }
4886                }
4887            }
4888        }
4889        return pss;
4890    }
4891
4892    @Override
4893    public void killApplicationProcess(String processName, int uid) {
4894        if (processName == null) {
4895            return;
4896        }
4897
4898        int callerUid = Binder.getCallingUid();
4899        // Only the system server can kill an application
4900        if (callerUid == Process.SYSTEM_UID) {
4901            synchronized (this) {
4902                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4903                if (app != null && app.thread != null) {
4904                    try {
4905                        app.thread.scheduleSuicide();
4906                    } catch (RemoteException e) {
4907                        // If the other end already died, then our work here is done.
4908                    }
4909                } else {
4910                    Slog.w(TAG, "Process/uid not found attempting kill of "
4911                            + processName + " / " + uid);
4912                }
4913            }
4914        } else {
4915            throw new SecurityException(callerUid + " cannot kill app process: " +
4916                    processName);
4917        }
4918    }
4919
4920    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4921        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4922                false, true, false, false, UserHandle.getUserId(uid), reason);
4923        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4924                Uri.fromParts("package", packageName, null));
4925        if (!mProcessesReady) {
4926            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4927                    | Intent.FLAG_RECEIVER_FOREGROUND);
4928        }
4929        intent.putExtra(Intent.EXTRA_UID, uid);
4930        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4931        broadcastIntentLocked(null, null, intent,
4932                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4933                false, false,
4934                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4935    }
4936
4937    private void forceStopUserLocked(int userId, String reason) {
4938        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4939        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4940        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4941                | Intent.FLAG_RECEIVER_FOREGROUND);
4942        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4943        broadcastIntentLocked(null, null, intent,
4944                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4945                false, false,
4946                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4947    }
4948
4949    private final boolean killPackageProcessesLocked(String packageName, int appId,
4950            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4951            boolean doit, boolean evenPersistent, String reason) {
4952        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4953
4954        // Remove all processes this package may have touched: all with the
4955        // same UID (except for the system or root user), and all whose name
4956        // matches the package name.
4957        final int NP = mProcessNames.getMap().size();
4958        for (int ip=0; ip<NP; ip++) {
4959            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4960            final int NA = apps.size();
4961            for (int ia=0; ia<NA; ia++) {
4962                ProcessRecord app = apps.valueAt(ia);
4963                if (app.persistent && !evenPersistent) {
4964                    // we don't kill persistent processes
4965                    continue;
4966                }
4967                if (app.removed) {
4968                    if (doit) {
4969                        procs.add(app);
4970                    }
4971                    continue;
4972                }
4973
4974                // Skip process if it doesn't meet our oom adj requirement.
4975                if (app.setAdj < minOomAdj) {
4976                    continue;
4977                }
4978
4979                // If no package is specified, we call all processes under the
4980                // give user id.
4981                if (packageName == null) {
4982                    if (app.userId != userId) {
4983                        continue;
4984                    }
4985                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4986                        continue;
4987                    }
4988                // Package has been specified, we want to hit all processes
4989                // that match it.  We need to qualify this by the processes
4990                // that are running under the specified app and user ID.
4991                } else {
4992                    final boolean isDep = app.pkgDeps != null
4993                            && app.pkgDeps.contains(packageName);
4994                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
4995                        continue;
4996                    }
4997                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4998                        continue;
4999                    }
5000                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5001                        continue;
5002                    }
5003                }
5004
5005                // Process has passed all conditions, kill it!
5006                if (!doit) {
5007                    return true;
5008                }
5009                app.removed = true;
5010                procs.add(app);
5011            }
5012        }
5013
5014        int N = procs.size();
5015        for (int i=0; i<N; i++) {
5016            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5017        }
5018        updateOomAdjLocked();
5019        return N > 0;
5020    }
5021
5022    private final boolean forceStopPackageLocked(String name, int appId,
5023            boolean callerWillRestart, boolean purgeCache, boolean doit,
5024            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5025        int i;
5026        int N;
5027
5028        if (userId == UserHandle.USER_ALL && name == null) {
5029            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5030        }
5031
5032        if (appId < 0 && name != null) {
5033            try {
5034                appId = UserHandle.getAppId(
5035                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5036            } catch (RemoteException e) {
5037            }
5038        }
5039
5040        if (doit) {
5041            if (name != null) {
5042                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5043                        + " user=" + userId + ": " + reason);
5044            } else {
5045                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5046            }
5047
5048            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5049            for (int ip=pmap.size()-1; ip>=0; ip--) {
5050                SparseArray<Long> ba = pmap.valueAt(ip);
5051                for (i=ba.size()-1; i>=0; i--) {
5052                    boolean remove = false;
5053                    final int entUid = ba.keyAt(i);
5054                    if (name != null) {
5055                        if (userId == UserHandle.USER_ALL) {
5056                            if (UserHandle.getAppId(entUid) == appId) {
5057                                remove = true;
5058                            }
5059                        } else {
5060                            if (entUid == UserHandle.getUid(userId, appId)) {
5061                                remove = true;
5062                            }
5063                        }
5064                    } else if (UserHandle.getUserId(entUid) == userId) {
5065                        remove = true;
5066                    }
5067                    if (remove) {
5068                        ba.removeAt(i);
5069                    }
5070                }
5071                if (ba.size() == 0) {
5072                    pmap.removeAt(ip);
5073                }
5074            }
5075        }
5076
5077        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5078                -100, callerWillRestart, true, doit, evenPersistent,
5079                name == null ? ("stop user " + userId) : ("stop " + name));
5080
5081        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5082            if (!doit) {
5083                return true;
5084            }
5085            didSomething = true;
5086        }
5087
5088        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5089            if (!doit) {
5090                return true;
5091            }
5092            didSomething = true;
5093        }
5094
5095        if (name == null) {
5096            // Remove all sticky broadcasts from this user.
5097            mStickyBroadcasts.remove(userId);
5098        }
5099
5100        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5101        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5102                userId, providers)) {
5103            if (!doit) {
5104                return true;
5105            }
5106            didSomething = true;
5107        }
5108        N = providers.size();
5109        for (i=0; i<N; i++) {
5110            removeDyingProviderLocked(null, providers.get(i), true);
5111        }
5112
5113        // Remove transient permissions granted from/to this package/user
5114        removeUriPermissionsForPackageLocked(name, userId, false);
5115
5116        if (name == null || uninstalling) {
5117            // Remove pending intents.  For now we only do this when force
5118            // stopping users, because we have some problems when doing this
5119            // for packages -- app widgets are not currently cleaned up for
5120            // such packages, so they can be left with bad pending intents.
5121            if (mIntentSenderRecords.size() > 0) {
5122                Iterator<WeakReference<PendingIntentRecord>> it
5123                        = mIntentSenderRecords.values().iterator();
5124                while (it.hasNext()) {
5125                    WeakReference<PendingIntentRecord> wpir = it.next();
5126                    if (wpir == null) {
5127                        it.remove();
5128                        continue;
5129                    }
5130                    PendingIntentRecord pir = wpir.get();
5131                    if (pir == null) {
5132                        it.remove();
5133                        continue;
5134                    }
5135                    if (name == null) {
5136                        // Stopping user, remove all objects for the user.
5137                        if (pir.key.userId != userId) {
5138                            // Not the same user, skip it.
5139                            continue;
5140                        }
5141                    } else {
5142                        if (UserHandle.getAppId(pir.uid) != appId) {
5143                            // Different app id, skip it.
5144                            continue;
5145                        }
5146                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5147                            // Different user, skip it.
5148                            continue;
5149                        }
5150                        if (!pir.key.packageName.equals(name)) {
5151                            // Different package, skip it.
5152                            continue;
5153                        }
5154                    }
5155                    if (!doit) {
5156                        return true;
5157                    }
5158                    didSomething = true;
5159                    it.remove();
5160                    pir.canceled = true;
5161                    if (pir.key.activity != null) {
5162                        pir.key.activity.pendingResults.remove(pir.ref);
5163                    }
5164                }
5165            }
5166        }
5167
5168        if (doit) {
5169            if (purgeCache && name != null) {
5170                AttributeCache ac = AttributeCache.instance();
5171                if (ac != null) {
5172                    ac.removePackage(name);
5173                }
5174            }
5175            if (mBooted) {
5176                mStackSupervisor.resumeTopActivitiesLocked();
5177                mStackSupervisor.scheduleIdleLocked();
5178            }
5179        }
5180
5181        return didSomething;
5182    }
5183
5184    private final boolean removeProcessLocked(ProcessRecord app,
5185            boolean callerWillRestart, boolean allowRestart, String reason) {
5186        final String name = app.processName;
5187        final int uid = app.uid;
5188        if (DEBUG_PROCESSES) Slog.d(
5189            TAG, "Force removing proc " + app.toShortString() + " (" + name
5190            + "/" + uid + ")");
5191
5192        mProcessNames.remove(name, uid);
5193        mIsolatedProcesses.remove(app.uid);
5194        if (mHeavyWeightProcess == app) {
5195            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5196                    mHeavyWeightProcess.userId, 0));
5197            mHeavyWeightProcess = null;
5198        }
5199        boolean needRestart = false;
5200        if (app.pid > 0 && app.pid != MY_PID) {
5201            int pid = app.pid;
5202            synchronized (mPidsSelfLocked) {
5203                mPidsSelfLocked.remove(pid);
5204                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5205            }
5206            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5207            if (app.isolated) {
5208                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5209            }
5210            killUnneededProcessLocked(app, reason);
5211            Process.killProcessGroup(app.info.uid, app.pid);
5212            handleAppDiedLocked(app, true, allowRestart);
5213            removeLruProcessLocked(app);
5214
5215            if (app.persistent && !app.isolated) {
5216                if (!callerWillRestart) {
5217                    addAppLocked(app.info, false, null /* ABI override */);
5218                } else {
5219                    needRestart = true;
5220                }
5221            }
5222        } else {
5223            mRemovedProcesses.add(app);
5224        }
5225
5226        return needRestart;
5227    }
5228
5229    private final void processStartTimedOutLocked(ProcessRecord app) {
5230        final int pid = app.pid;
5231        boolean gone = false;
5232        synchronized (mPidsSelfLocked) {
5233            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5234            if (knownApp != null && knownApp.thread == null) {
5235                mPidsSelfLocked.remove(pid);
5236                gone = true;
5237            }
5238        }
5239
5240        if (gone) {
5241            Slog.w(TAG, "Process " + app + " failed to attach");
5242            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5243                    pid, app.uid, app.processName);
5244            mProcessNames.remove(app.processName, app.uid);
5245            mIsolatedProcesses.remove(app.uid);
5246            if (mHeavyWeightProcess == app) {
5247                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5248                        mHeavyWeightProcess.userId, 0));
5249                mHeavyWeightProcess = null;
5250            }
5251            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5252            if (app.isolated) {
5253                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5254            }
5255            // Take care of any launching providers waiting for this process.
5256            checkAppInLaunchingProvidersLocked(app, true);
5257            // Take care of any services that are waiting for the process.
5258            mServices.processStartTimedOutLocked(app);
5259            killUnneededProcessLocked(app, "start timeout");
5260            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5261                Slog.w(TAG, "Unattached app died before backup, skipping");
5262                try {
5263                    IBackupManager bm = IBackupManager.Stub.asInterface(
5264                            ServiceManager.getService(Context.BACKUP_SERVICE));
5265                    bm.agentDisconnected(app.info.packageName);
5266                } catch (RemoteException e) {
5267                    // Can't happen; the backup manager is local
5268                }
5269            }
5270            if (isPendingBroadcastProcessLocked(pid)) {
5271                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5272                skipPendingBroadcastLocked(pid);
5273            }
5274        } else {
5275            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5276        }
5277    }
5278
5279    private final boolean attachApplicationLocked(IApplicationThread thread,
5280            int pid) {
5281
5282        // Find the application record that is being attached...  either via
5283        // the pid if we are running in multiple processes, or just pull the
5284        // next app record if we are emulating process with anonymous threads.
5285        ProcessRecord app;
5286        if (pid != MY_PID && pid >= 0) {
5287            synchronized (mPidsSelfLocked) {
5288                app = mPidsSelfLocked.get(pid);
5289            }
5290        } else {
5291            app = null;
5292        }
5293
5294        if (app == null) {
5295            Slog.w(TAG, "No pending application record for pid " + pid
5296                    + " (IApplicationThread " + thread + "); dropping process");
5297            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5298            if (pid > 0 && pid != MY_PID) {
5299                Process.killProcessQuiet(pid);
5300                //TODO: Process.killProcessGroup(app.info.uid, pid);
5301            } else {
5302                try {
5303                    thread.scheduleExit();
5304                } catch (Exception e) {
5305                    // Ignore exceptions.
5306                }
5307            }
5308            return false;
5309        }
5310
5311        // If this application record is still attached to a previous
5312        // process, clean it up now.
5313        if (app.thread != null) {
5314            handleAppDiedLocked(app, true, true);
5315        }
5316
5317        // Tell the process all about itself.
5318
5319        if (localLOGV) Slog.v(
5320                TAG, "Binding process pid " + pid + " to record " + app);
5321
5322        final String processName = app.processName;
5323        try {
5324            AppDeathRecipient adr = new AppDeathRecipient(
5325                    app, pid, thread);
5326            thread.asBinder().linkToDeath(adr, 0);
5327            app.deathRecipient = adr;
5328        } catch (RemoteException e) {
5329            app.resetPackageList(mProcessStats);
5330            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5331            return false;
5332        }
5333
5334        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5335
5336        app.makeActive(thread, mProcessStats);
5337        app.curAdj = app.setAdj = -100;
5338        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5339        app.forcingToForeground = null;
5340        updateProcessForegroundLocked(app, false, false);
5341        app.hasShownUi = false;
5342        app.debugging = false;
5343        app.cached = false;
5344
5345        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5346
5347        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5348        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5349
5350        if (!normalMode) {
5351            Slog.i(TAG, "Launching preboot mode app: " + app);
5352        }
5353
5354        if (localLOGV) Slog.v(
5355            TAG, "New app record " + app
5356            + " thread=" + thread.asBinder() + " pid=" + pid);
5357        try {
5358            int testMode = IApplicationThread.DEBUG_OFF;
5359            if (mDebugApp != null && mDebugApp.equals(processName)) {
5360                testMode = mWaitForDebugger
5361                    ? IApplicationThread.DEBUG_WAIT
5362                    : IApplicationThread.DEBUG_ON;
5363                app.debugging = true;
5364                if (mDebugTransient) {
5365                    mDebugApp = mOrigDebugApp;
5366                    mWaitForDebugger = mOrigWaitForDebugger;
5367                }
5368            }
5369            String profileFile = app.instrumentationProfileFile;
5370            ParcelFileDescriptor profileFd = null;
5371            boolean profileAutoStop = false;
5372            if (mProfileApp != null && mProfileApp.equals(processName)) {
5373                mProfileProc = app;
5374                profileFile = mProfileFile;
5375                profileFd = mProfileFd;
5376                profileAutoStop = mAutoStopProfiler;
5377            }
5378            boolean enableOpenGlTrace = false;
5379            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5380                enableOpenGlTrace = true;
5381                mOpenGlTraceApp = null;
5382            }
5383
5384            // If the app is being launched for restore or full backup, set it up specially
5385            boolean isRestrictedBackupMode = false;
5386            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5387                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5388                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5389                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5390            }
5391
5392            ensurePackageDexOpt(app.instrumentationInfo != null
5393                    ? app.instrumentationInfo.packageName
5394                    : app.info.packageName);
5395            if (app.instrumentationClass != null) {
5396                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5397            }
5398            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5399                    + processName + " with config " + mConfiguration);
5400            ApplicationInfo appInfo = app.instrumentationInfo != null
5401                    ? app.instrumentationInfo : app.info;
5402            app.compat = compatibilityInfoForPackageLocked(appInfo);
5403            if (profileFd != null) {
5404                profileFd = profileFd.dup();
5405            }
5406            thread.bindApplication(processName, appInfo, providers,
5407                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5408                    app.instrumentationArguments, app.instrumentationWatcher,
5409                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5410                    isRestrictedBackupMode || !normalMode, app.persistent,
5411                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5412                    mCoreSettingsObserver.getCoreSettingsLocked());
5413            updateLruProcessLocked(app, false, null);
5414            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5415        } catch (Exception e) {
5416            // todo: Yikes!  What should we do?  For now we will try to
5417            // start another process, but that could easily get us in
5418            // an infinite loop of restarting processes...
5419            Slog.w(TAG, "Exception thrown during bind!", e);
5420
5421            app.resetPackageList(mProcessStats);
5422            app.unlinkDeathRecipient();
5423            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5424            return false;
5425        }
5426
5427        // Remove this record from the list of starting applications.
5428        mPersistentStartingProcesses.remove(app);
5429        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5430                "Attach application locked removing on hold: " + app);
5431        mProcessesOnHold.remove(app);
5432
5433        boolean badApp = false;
5434        boolean didSomething = false;
5435
5436        // See if the top visible activity is waiting to run in this process...
5437        if (normalMode) {
5438            try {
5439                if (mStackSupervisor.attachApplicationLocked(app)) {
5440                    didSomething = true;
5441                }
5442            } catch (Exception e) {
5443                badApp = true;
5444            }
5445        }
5446
5447        // Find any services that should be running in this process...
5448        if (!badApp) {
5449            try {
5450                didSomething |= mServices.attachApplicationLocked(app, processName);
5451            } catch (Exception e) {
5452                badApp = true;
5453            }
5454        }
5455
5456        // Check if a next-broadcast receiver is in this process...
5457        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5458            try {
5459                didSomething |= sendPendingBroadcastsLocked(app);
5460            } catch (Exception e) {
5461                // If the app died trying to launch the receiver we declare it 'bad'
5462                badApp = true;
5463            }
5464        }
5465
5466        // Check whether the next backup agent is in this process...
5467        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5468            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5469            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5470            try {
5471                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5472                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5473                        mBackupTarget.backupMode);
5474            } catch (Exception e) {
5475                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5476                e.printStackTrace();
5477            }
5478        }
5479
5480        if (badApp) {
5481            // todo: Also need to kill application to deal with all
5482            // kinds of exceptions.
5483            handleAppDiedLocked(app, false, true);
5484            return false;
5485        }
5486
5487        if (!didSomething) {
5488            updateOomAdjLocked();
5489        }
5490
5491        return true;
5492    }
5493
5494    @Override
5495    public final void attachApplication(IApplicationThread thread) {
5496        synchronized (this) {
5497            int callingPid = Binder.getCallingPid();
5498            final long origId = Binder.clearCallingIdentity();
5499            attachApplicationLocked(thread, callingPid);
5500            Binder.restoreCallingIdentity(origId);
5501        }
5502    }
5503
5504    @Override
5505    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5506        final long origId = Binder.clearCallingIdentity();
5507        synchronized (this) {
5508            ActivityStack stack = ActivityRecord.getStackLocked(token);
5509            if (stack != null) {
5510                ActivityRecord r =
5511                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5512                if (stopProfiling) {
5513                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5514                        try {
5515                            mProfileFd.close();
5516                        } catch (IOException e) {
5517                        }
5518                        clearProfilerLocked();
5519                    }
5520                }
5521            }
5522        }
5523        Binder.restoreCallingIdentity(origId);
5524    }
5525
5526    void enableScreenAfterBoot() {
5527        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5528                SystemClock.uptimeMillis());
5529        mWindowManager.enableScreenAfterBoot();
5530
5531        synchronized (this) {
5532            updateEventDispatchingLocked();
5533        }
5534    }
5535
5536    @Override
5537    public void showBootMessage(final CharSequence msg, final boolean always) {
5538        enforceNotIsolatedCaller("showBootMessage");
5539        mWindowManager.showBootMessage(msg, always);
5540    }
5541
5542    @Override
5543    public void dismissKeyguardOnNextActivity() {
5544        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5545        final long token = Binder.clearCallingIdentity();
5546        try {
5547            synchronized (this) {
5548                if (DEBUG_LOCKSCREEN) logLockScreen("");
5549                if (mLockScreenShown) {
5550                    mLockScreenShown = false;
5551                    comeOutOfSleepIfNeededLocked();
5552                }
5553                mStackSupervisor.setDismissKeyguard(true);
5554            }
5555        } finally {
5556            Binder.restoreCallingIdentity(token);
5557        }
5558    }
5559
5560    final void finishBooting() {
5561        // Register receivers to handle package update events
5562        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5563
5564        synchronized (this) {
5565            // Ensure that any processes we had put on hold are now started
5566            // up.
5567            final int NP = mProcessesOnHold.size();
5568            if (NP > 0) {
5569                ArrayList<ProcessRecord> procs =
5570                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5571                for (int ip=0; ip<NP; ip++) {
5572                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5573                            + procs.get(ip));
5574                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5575                }
5576            }
5577
5578            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5579                // Start looking for apps that are abusing wake locks.
5580                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5581                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5582                // Tell anyone interested that we are done booting!
5583                SystemProperties.set("sys.boot_completed", "1");
5584                SystemProperties.set("dev.bootcomplete", "1");
5585                for (int i=0; i<mStartedUsers.size(); i++) {
5586                    UserStartedState uss = mStartedUsers.valueAt(i);
5587                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5588                        uss.mState = UserStartedState.STATE_RUNNING;
5589                        final int userId = mStartedUsers.keyAt(i);
5590                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5591                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5592                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5593                        broadcastIntentLocked(null, null, intent, null,
5594                                new IIntentReceiver.Stub() {
5595                                    @Override
5596                                    public void performReceive(Intent intent, int resultCode,
5597                                            String data, Bundle extras, boolean ordered,
5598                                            boolean sticky, int sendingUser) {
5599                                        synchronized (ActivityManagerService.this) {
5600                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5601                                                    true, false);
5602                                        }
5603                                    }
5604                                },
5605                                0, null, null,
5606                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5607                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5608                                userId);
5609                    }
5610                }
5611                scheduleStartProfilesLocked();
5612            }
5613        }
5614    }
5615
5616    final void ensureBootCompleted() {
5617        boolean booting;
5618        boolean enableScreen;
5619        synchronized (this) {
5620            booting = mBooting;
5621            mBooting = false;
5622            enableScreen = !mBooted;
5623            mBooted = true;
5624        }
5625
5626        if (booting) {
5627            finishBooting();
5628        }
5629
5630        if (enableScreen) {
5631            enableScreenAfterBoot();
5632        }
5633    }
5634
5635    @Override
5636    public final void activityResumed(IBinder token) {
5637        final long origId = Binder.clearCallingIdentity();
5638        synchronized(this) {
5639            ActivityStack stack = ActivityRecord.getStackLocked(token);
5640            if (stack != null) {
5641                ActivityRecord.activityResumedLocked(token);
5642            }
5643        }
5644        Binder.restoreCallingIdentity(origId);
5645    }
5646
5647    @Override
5648    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5649        final long origId = Binder.clearCallingIdentity();
5650        synchronized(this) {
5651            ActivityStack stack = ActivityRecord.getStackLocked(token);
5652            if (stack != null) {
5653                stack.activityPausedLocked(token, false, persistentState);
5654            }
5655        }
5656        Binder.restoreCallingIdentity(origId);
5657    }
5658
5659    @Override
5660    public final void activityStopped(IBinder token, Bundle icicle,
5661            PersistableBundle persistentState, CharSequence description) {
5662        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5663
5664        // Refuse possible leaked file descriptors
5665        if (icicle != null && icicle.hasFileDescriptors()) {
5666            throw new IllegalArgumentException("File descriptors passed in Bundle");
5667        }
5668
5669        final long origId = Binder.clearCallingIdentity();
5670
5671        synchronized (this) {
5672            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5673            if (r != null) {
5674                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5675            }
5676        }
5677
5678        trimApplications();
5679
5680        Binder.restoreCallingIdentity(origId);
5681    }
5682
5683    @Override
5684    public final void activityDestroyed(IBinder token) {
5685        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5686        synchronized (this) {
5687            ActivityStack stack = ActivityRecord.getStackLocked(token);
5688            if (stack != null) {
5689                stack.activityDestroyedLocked(token);
5690            }
5691        }
5692    }
5693
5694    @Override
5695    public final void mediaResourcesReleased(IBinder token) {
5696        final long origId = Binder.clearCallingIdentity();
5697        try {
5698            synchronized (this) {
5699                ActivityStack stack = ActivityRecord.getStackLocked(token);
5700                if (stack != null) {
5701                    stack.mediaResourcesReleased(token);
5702                }
5703            }
5704        } finally {
5705            Binder.restoreCallingIdentity(origId);
5706        }
5707    }
5708
5709    @Override
5710    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5711        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5712    }
5713
5714    @Override
5715    public final void notifyEnterAnimationComplete(IBinder token) {
5716        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5717    }
5718
5719    @Override
5720    public String getCallingPackage(IBinder token) {
5721        synchronized (this) {
5722            ActivityRecord r = getCallingRecordLocked(token);
5723            return r != null ? r.info.packageName : null;
5724        }
5725    }
5726
5727    @Override
5728    public ComponentName getCallingActivity(IBinder token) {
5729        synchronized (this) {
5730            ActivityRecord r = getCallingRecordLocked(token);
5731            return r != null ? r.intent.getComponent() : null;
5732        }
5733    }
5734
5735    private ActivityRecord getCallingRecordLocked(IBinder token) {
5736        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5737        if (r == null) {
5738            return null;
5739        }
5740        return r.resultTo;
5741    }
5742
5743    @Override
5744    public ComponentName getActivityClassForToken(IBinder token) {
5745        synchronized(this) {
5746            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5747            if (r == null) {
5748                return null;
5749            }
5750            return r.intent.getComponent();
5751        }
5752    }
5753
5754    @Override
5755    public String getPackageForToken(IBinder token) {
5756        synchronized(this) {
5757            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5758            if (r == null) {
5759                return null;
5760            }
5761            return r.packageName;
5762        }
5763    }
5764
5765    @Override
5766    public IIntentSender getIntentSender(int type,
5767            String packageName, IBinder token, String resultWho,
5768            int requestCode, Intent[] intents, String[] resolvedTypes,
5769            int flags, Bundle options, int userId) {
5770        enforceNotIsolatedCaller("getIntentSender");
5771        // Refuse possible leaked file descriptors
5772        if (intents != null) {
5773            if (intents.length < 1) {
5774                throw new IllegalArgumentException("Intents array length must be >= 1");
5775            }
5776            for (int i=0; i<intents.length; i++) {
5777                Intent intent = intents[i];
5778                if (intent != null) {
5779                    if (intent.hasFileDescriptors()) {
5780                        throw new IllegalArgumentException("File descriptors passed in Intent");
5781                    }
5782                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5783                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5784                        throw new IllegalArgumentException(
5785                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5786                    }
5787                    intents[i] = new Intent(intent);
5788                }
5789            }
5790            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5791                throw new IllegalArgumentException(
5792                        "Intent array length does not match resolvedTypes length");
5793            }
5794        }
5795        if (options != null) {
5796            if (options.hasFileDescriptors()) {
5797                throw new IllegalArgumentException("File descriptors passed in options");
5798            }
5799        }
5800
5801        synchronized(this) {
5802            int callingUid = Binder.getCallingUid();
5803            int origUserId = userId;
5804            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5805                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5806                    ALLOW_NON_FULL, "getIntentSender", null);
5807            if (origUserId == UserHandle.USER_CURRENT) {
5808                // We don't want to evaluate this until the pending intent is
5809                // actually executed.  However, we do want to always do the
5810                // security checking for it above.
5811                userId = UserHandle.USER_CURRENT;
5812            }
5813            try {
5814                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5815                    int uid = AppGlobals.getPackageManager()
5816                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5817                    if (!UserHandle.isSameApp(callingUid, uid)) {
5818                        String msg = "Permission Denial: getIntentSender() from pid="
5819                            + Binder.getCallingPid()
5820                            + ", uid=" + Binder.getCallingUid()
5821                            + ", (need uid=" + uid + ")"
5822                            + " is not allowed to send as package " + packageName;
5823                        Slog.w(TAG, msg);
5824                        throw new SecurityException(msg);
5825                    }
5826                }
5827
5828                return getIntentSenderLocked(type, packageName, callingUid, userId,
5829                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5830
5831            } catch (RemoteException e) {
5832                throw new SecurityException(e);
5833            }
5834        }
5835    }
5836
5837    IIntentSender getIntentSenderLocked(int type, String packageName,
5838            int callingUid, int userId, IBinder token, String resultWho,
5839            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5840            Bundle options) {
5841        if (DEBUG_MU)
5842            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5843        ActivityRecord activity = null;
5844        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5845            activity = ActivityRecord.isInStackLocked(token);
5846            if (activity == null) {
5847                return null;
5848            }
5849            if (activity.finishing) {
5850                return null;
5851            }
5852        }
5853
5854        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5855        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5856        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5857        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5858                |PendingIntent.FLAG_UPDATE_CURRENT);
5859
5860        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5861                type, packageName, activity, resultWho,
5862                requestCode, intents, resolvedTypes, flags, options, userId);
5863        WeakReference<PendingIntentRecord> ref;
5864        ref = mIntentSenderRecords.get(key);
5865        PendingIntentRecord rec = ref != null ? ref.get() : null;
5866        if (rec != null) {
5867            if (!cancelCurrent) {
5868                if (updateCurrent) {
5869                    if (rec.key.requestIntent != null) {
5870                        rec.key.requestIntent.replaceExtras(intents != null ?
5871                                intents[intents.length - 1] : null);
5872                    }
5873                    if (intents != null) {
5874                        intents[intents.length-1] = rec.key.requestIntent;
5875                        rec.key.allIntents = intents;
5876                        rec.key.allResolvedTypes = resolvedTypes;
5877                    } else {
5878                        rec.key.allIntents = null;
5879                        rec.key.allResolvedTypes = null;
5880                    }
5881                }
5882                return rec;
5883            }
5884            rec.canceled = true;
5885            mIntentSenderRecords.remove(key);
5886        }
5887        if (noCreate) {
5888            return rec;
5889        }
5890        rec = new PendingIntentRecord(this, key, callingUid);
5891        mIntentSenderRecords.put(key, rec.ref);
5892        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5893            if (activity.pendingResults == null) {
5894                activity.pendingResults
5895                        = new HashSet<WeakReference<PendingIntentRecord>>();
5896            }
5897            activity.pendingResults.add(rec.ref);
5898        }
5899        return rec;
5900    }
5901
5902    @Override
5903    public void cancelIntentSender(IIntentSender sender) {
5904        if (!(sender instanceof PendingIntentRecord)) {
5905            return;
5906        }
5907        synchronized(this) {
5908            PendingIntentRecord rec = (PendingIntentRecord)sender;
5909            try {
5910                int uid = AppGlobals.getPackageManager()
5911                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5912                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5913                    String msg = "Permission Denial: cancelIntentSender() from pid="
5914                        + Binder.getCallingPid()
5915                        + ", uid=" + Binder.getCallingUid()
5916                        + " is not allowed to cancel packges "
5917                        + rec.key.packageName;
5918                    Slog.w(TAG, msg);
5919                    throw new SecurityException(msg);
5920                }
5921            } catch (RemoteException e) {
5922                throw new SecurityException(e);
5923            }
5924            cancelIntentSenderLocked(rec, true);
5925        }
5926    }
5927
5928    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5929        rec.canceled = true;
5930        mIntentSenderRecords.remove(rec.key);
5931        if (cleanActivity && rec.key.activity != null) {
5932            rec.key.activity.pendingResults.remove(rec.ref);
5933        }
5934    }
5935
5936    @Override
5937    public String getPackageForIntentSender(IIntentSender pendingResult) {
5938        if (!(pendingResult instanceof PendingIntentRecord)) {
5939            return null;
5940        }
5941        try {
5942            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5943            return res.key.packageName;
5944        } catch (ClassCastException e) {
5945        }
5946        return null;
5947    }
5948
5949    @Override
5950    public int getUidForIntentSender(IIntentSender sender) {
5951        if (sender instanceof PendingIntentRecord) {
5952            try {
5953                PendingIntentRecord res = (PendingIntentRecord)sender;
5954                return res.uid;
5955            } catch (ClassCastException e) {
5956            }
5957        }
5958        return -1;
5959    }
5960
5961    @Override
5962    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5963        if (!(pendingResult instanceof PendingIntentRecord)) {
5964            return false;
5965        }
5966        try {
5967            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5968            if (res.key.allIntents == null) {
5969                return false;
5970            }
5971            for (int i=0; i<res.key.allIntents.length; i++) {
5972                Intent intent = res.key.allIntents[i];
5973                if (intent.getPackage() != null && intent.getComponent() != null) {
5974                    return false;
5975                }
5976            }
5977            return true;
5978        } catch (ClassCastException e) {
5979        }
5980        return false;
5981    }
5982
5983    @Override
5984    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5985        if (!(pendingResult instanceof PendingIntentRecord)) {
5986            return false;
5987        }
5988        try {
5989            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5990            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5991                return true;
5992            }
5993            return false;
5994        } catch (ClassCastException e) {
5995        }
5996        return false;
5997    }
5998
5999    @Override
6000    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6001        if (!(pendingResult instanceof PendingIntentRecord)) {
6002            return null;
6003        }
6004        try {
6005            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6006            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6007        } catch (ClassCastException e) {
6008        }
6009        return null;
6010    }
6011
6012    @Override
6013    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6014        if (!(pendingResult instanceof PendingIntentRecord)) {
6015            return null;
6016        }
6017        try {
6018            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6019            Intent intent = res.key.requestIntent;
6020            if (intent != null) {
6021                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6022                        || res.lastTagPrefix.equals(prefix))) {
6023                    return res.lastTag;
6024                }
6025                res.lastTagPrefix = prefix;
6026                StringBuilder sb = new StringBuilder(128);
6027                if (prefix != null) {
6028                    sb.append(prefix);
6029                }
6030                if (intent.getAction() != null) {
6031                    sb.append(intent.getAction());
6032                } else if (intent.getComponent() != null) {
6033                    intent.getComponent().appendShortString(sb);
6034                } else {
6035                    sb.append("?");
6036                }
6037                return res.lastTag = sb.toString();
6038            }
6039        } catch (ClassCastException e) {
6040        }
6041        return null;
6042    }
6043
6044    @Override
6045    public void setProcessLimit(int max) {
6046        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6047                "setProcessLimit()");
6048        synchronized (this) {
6049            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6050            mProcessLimitOverride = max;
6051        }
6052        trimApplications();
6053    }
6054
6055    @Override
6056    public int getProcessLimit() {
6057        synchronized (this) {
6058            return mProcessLimitOverride;
6059        }
6060    }
6061
6062    void foregroundTokenDied(ForegroundToken token) {
6063        synchronized (ActivityManagerService.this) {
6064            synchronized (mPidsSelfLocked) {
6065                ForegroundToken cur
6066                    = mForegroundProcesses.get(token.pid);
6067                if (cur != token) {
6068                    return;
6069                }
6070                mForegroundProcesses.remove(token.pid);
6071                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6072                if (pr == null) {
6073                    return;
6074                }
6075                pr.forcingToForeground = null;
6076                updateProcessForegroundLocked(pr, false, false);
6077            }
6078            updateOomAdjLocked();
6079        }
6080    }
6081
6082    @Override
6083    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6084        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6085                "setProcessForeground()");
6086        synchronized(this) {
6087            boolean changed = false;
6088
6089            synchronized (mPidsSelfLocked) {
6090                ProcessRecord pr = mPidsSelfLocked.get(pid);
6091                if (pr == null && isForeground) {
6092                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6093                    return;
6094                }
6095                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6096                if (oldToken != null) {
6097                    oldToken.token.unlinkToDeath(oldToken, 0);
6098                    mForegroundProcesses.remove(pid);
6099                    if (pr != null) {
6100                        pr.forcingToForeground = null;
6101                    }
6102                    changed = true;
6103                }
6104                if (isForeground && token != null) {
6105                    ForegroundToken newToken = new ForegroundToken() {
6106                        @Override
6107                        public void binderDied() {
6108                            foregroundTokenDied(this);
6109                        }
6110                    };
6111                    newToken.pid = pid;
6112                    newToken.token = token;
6113                    try {
6114                        token.linkToDeath(newToken, 0);
6115                        mForegroundProcesses.put(pid, newToken);
6116                        pr.forcingToForeground = token;
6117                        changed = true;
6118                    } catch (RemoteException e) {
6119                        // If the process died while doing this, we will later
6120                        // do the cleanup with the process death link.
6121                    }
6122                }
6123            }
6124
6125            if (changed) {
6126                updateOomAdjLocked();
6127            }
6128        }
6129    }
6130
6131    // =========================================================
6132    // PERMISSIONS
6133    // =========================================================
6134
6135    static class PermissionController extends IPermissionController.Stub {
6136        ActivityManagerService mActivityManagerService;
6137        PermissionController(ActivityManagerService activityManagerService) {
6138            mActivityManagerService = activityManagerService;
6139        }
6140
6141        @Override
6142        public boolean checkPermission(String permission, int pid, int uid) {
6143            return mActivityManagerService.checkPermission(permission, pid,
6144                    uid) == PackageManager.PERMISSION_GRANTED;
6145        }
6146    }
6147
6148    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6149        @Override
6150        public int checkComponentPermission(String permission, int pid, int uid,
6151                int owningUid, boolean exported) {
6152            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6153                    owningUid, exported);
6154        }
6155
6156        @Override
6157        public Object getAMSLock() {
6158            return ActivityManagerService.this;
6159        }
6160    }
6161
6162    /**
6163     * This can be called with or without the global lock held.
6164     */
6165    int checkComponentPermission(String permission, int pid, int uid,
6166            int owningUid, boolean exported) {
6167        // We might be performing an operation on behalf of an indirect binder
6168        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6169        // client identity accordingly before proceeding.
6170        Identity tlsIdentity = sCallerIdentity.get();
6171        if (tlsIdentity != null) {
6172            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6173                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6174            uid = tlsIdentity.uid;
6175            pid = tlsIdentity.pid;
6176        }
6177
6178        if (pid == MY_PID) {
6179            return PackageManager.PERMISSION_GRANTED;
6180        }
6181
6182        return ActivityManager.checkComponentPermission(permission, uid,
6183                owningUid, exported);
6184    }
6185
6186    /**
6187     * As the only public entry point for permissions checking, this method
6188     * can enforce the semantic that requesting a check on a null global
6189     * permission is automatically denied.  (Internally a null permission
6190     * string is used when calling {@link #checkComponentPermission} in cases
6191     * when only uid-based security is needed.)
6192     *
6193     * This can be called with or without the global lock held.
6194     */
6195    @Override
6196    public int checkPermission(String permission, int pid, int uid) {
6197        if (permission == null) {
6198            return PackageManager.PERMISSION_DENIED;
6199        }
6200        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6201    }
6202
6203    /**
6204     * Binder IPC calls go through the public entry point.
6205     * This can be called with or without the global lock held.
6206     */
6207    int checkCallingPermission(String permission) {
6208        return checkPermission(permission,
6209                Binder.getCallingPid(),
6210                UserHandle.getAppId(Binder.getCallingUid()));
6211    }
6212
6213    /**
6214     * This can be called with or without the global lock held.
6215     */
6216    void enforceCallingPermission(String permission, String func) {
6217        if (checkCallingPermission(permission)
6218                == PackageManager.PERMISSION_GRANTED) {
6219            return;
6220        }
6221
6222        String msg = "Permission Denial: " + func + " from pid="
6223                + Binder.getCallingPid()
6224                + ", uid=" + Binder.getCallingUid()
6225                + " requires " + permission;
6226        Slog.w(TAG, msg);
6227        throw new SecurityException(msg);
6228    }
6229
6230    /**
6231     * Determine if UID is holding permissions required to access {@link Uri} in
6232     * the given {@link ProviderInfo}. Final permission checking is always done
6233     * in {@link ContentProvider}.
6234     */
6235    private final boolean checkHoldingPermissionsLocked(
6236            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6237        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6238                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6239        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6240            return false;
6241        }
6242        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6243    }
6244
6245    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6246            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6247        if (pi.applicationInfo.uid == uid) {
6248            return true;
6249        } else if (!pi.exported) {
6250            return false;
6251        }
6252
6253        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6254        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6255        try {
6256            // check if target holds top-level <provider> permissions
6257            if (!readMet && pi.readPermission != null && considerUidPermissions
6258                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6259                readMet = true;
6260            }
6261            if (!writeMet && pi.writePermission != null && considerUidPermissions
6262                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6263                writeMet = true;
6264            }
6265
6266            // track if unprotected read/write is allowed; any denied
6267            // <path-permission> below removes this ability
6268            boolean allowDefaultRead = pi.readPermission == null;
6269            boolean allowDefaultWrite = pi.writePermission == null;
6270
6271            // check if target holds any <path-permission> that match uri
6272            final PathPermission[] pps = pi.pathPermissions;
6273            if (pps != null) {
6274                final String path = grantUri.uri.getPath();
6275                int i = pps.length;
6276                while (i > 0 && (!readMet || !writeMet)) {
6277                    i--;
6278                    PathPermission pp = pps[i];
6279                    if (pp.match(path)) {
6280                        if (!readMet) {
6281                            final String pprperm = pp.getReadPermission();
6282                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6283                                    + pprperm + " for " + pp.getPath()
6284                                    + ": match=" + pp.match(path)
6285                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6286                            if (pprperm != null) {
6287                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6288                                        == PERMISSION_GRANTED) {
6289                                    readMet = true;
6290                                } else {
6291                                    allowDefaultRead = false;
6292                                }
6293                            }
6294                        }
6295                        if (!writeMet) {
6296                            final String ppwperm = pp.getWritePermission();
6297                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6298                                    + ppwperm + " for " + pp.getPath()
6299                                    + ": match=" + pp.match(path)
6300                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6301                            if (ppwperm != null) {
6302                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6303                                        == PERMISSION_GRANTED) {
6304                                    writeMet = true;
6305                                } else {
6306                                    allowDefaultWrite = false;
6307                                }
6308                            }
6309                        }
6310                    }
6311                }
6312            }
6313
6314            // grant unprotected <provider> read/write, if not blocked by
6315            // <path-permission> above
6316            if (allowDefaultRead) readMet = true;
6317            if (allowDefaultWrite) writeMet = true;
6318
6319        } catch (RemoteException e) {
6320            return false;
6321        }
6322
6323        return readMet && writeMet;
6324    }
6325
6326    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6327        ProviderInfo pi = null;
6328        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6329        if (cpr != null) {
6330            pi = cpr.info;
6331        } else {
6332            try {
6333                pi = AppGlobals.getPackageManager().resolveContentProvider(
6334                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6335            } catch (RemoteException ex) {
6336            }
6337        }
6338        return pi;
6339    }
6340
6341    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6342        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6343        if (targetUris != null) {
6344            return targetUris.get(grantUri);
6345        }
6346        return null;
6347    }
6348
6349    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6350            String targetPkg, int targetUid, GrantUri grantUri) {
6351        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6352        if (targetUris == null) {
6353            targetUris = Maps.newArrayMap();
6354            mGrantedUriPermissions.put(targetUid, targetUris);
6355        }
6356
6357        UriPermission perm = targetUris.get(grantUri);
6358        if (perm == null) {
6359            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6360            targetUris.put(grantUri, perm);
6361        }
6362
6363        return perm;
6364    }
6365
6366    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6367            final int modeFlags) {
6368        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6369        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6370                : UriPermission.STRENGTH_OWNED;
6371
6372        // Root gets to do everything.
6373        if (uid == 0) {
6374            return true;
6375        }
6376
6377        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6378        if (perms == null) return false;
6379
6380        // First look for exact match
6381        final UriPermission exactPerm = perms.get(grantUri);
6382        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6383            return true;
6384        }
6385
6386        // No exact match, look for prefixes
6387        final int N = perms.size();
6388        for (int i = 0; i < N; i++) {
6389            final UriPermission perm = perms.valueAt(i);
6390            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6391                    && perm.getStrength(modeFlags) >= minStrength) {
6392                return true;
6393            }
6394        }
6395
6396        return false;
6397    }
6398
6399    @Override
6400    public int checkUriPermission(Uri uri, int pid, int uid,
6401            final int modeFlags, int userId) {
6402        enforceNotIsolatedCaller("checkUriPermission");
6403
6404        // Another redirected-binder-call permissions check as in
6405        // {@link checkComponentPermission}.
6406        Identity tlsIdentity = sCallerIdentity.get();
6407        if (tlsIdentity != null) {
6408            uid = tlsIdentity.uid;
6409            pid = tlsIdentity.pid;
6410        }
6411
6412        // Our own process gets to do everything.
6413        if (pid == MY_PID) {
6414            return PackageManager.PERMISSION_GRANTED;
6415        }
6416        synchronized (this) {
6417            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6418                    ? PackageManager.PERMISSION_GRANTED
6419                    : PackageManager.PERMISSION_DENIED;
6420        }
6421    }
6422
6423    /**
6424     * Check if the targetPkg can be granted permission to access uri by
6425     * the callingUid using the given modeFlags.  Throws a security exception
6426     * if callingUid is not allowed to do this.  Returns the uid of the target
6427     * if the URI permission grant should be performed; returns -1 if it is not
6428     * needed (for example targetPkg already has permission to access the URI).
6429     * If you already know the uid of the target, you can supply it in
6430     * lastTargetUid else set that to -1.
6431     */
6432    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6433            final int modeFlags, int lastTargetUid) {
6434        if (!Intent.isAccessUriMode(modeFlags)) {
6435            return -1;
6436        }
6437
6438        if (targetPkg != null) {
6439            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6440                    "Checking grant " + targetPkg + " permission to " + grantUri);
6441        }
6442
6443        final IPackageManager pm = AppGlobals.getPackageManager();
6444
6445        // If this is not a content: uri, we can't do anything with it.
6446        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6447            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6448                    "Can't grant URI permission for non-content URI: " + grantUri);
6449            return -1;
6450        }
6451
6452        final String authority = grantUri.uri.getAuthority();
6453        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6454        if (pi == null) {
6455            Slog.w(TAG, "No content provider found for permission check: " +
6456                    grantUri.uri.toSafeString());
6457            return -1;
6458        }
6459
6460        int targetUid = lastTargetUid;
6461        if (targetUid < 0 && targetPkg != null) {
6462            try {
6463                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6464                if (targetUid < 0) {
6465                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6466                            "Can't grant URI permission no uid for: " + targetPkg);
6467                    return -1;
6468                }
6469            } catch (RemoteException ex) {
6470                return -1;
6471            }
6472        }
6473
6474        if (targetUid >= 0) {
6475            // First...  does the target actually need this permission?
6476            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6477                // No need to grant the target this permission.
6478                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6479                        "Target " + targetPkg + " already has full permission to " + grantUri);
6480                return -1;
6481            }
6482        } else {
6483            // First...  there is no target package, so can anyone access it?
6484            boolean allowed = pi.exported;
6485            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6486                if (pi.readPermission != null) {
6487                    allowed = false;
6488                }
6489            }
6490            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6491                if (pi.writePermission != null) {
6492                    allowed = false;
6493                }
6494            }
6495            if (allowed) {
6496                return -1;
6497            }
6498        }
6499
6500        /* There is a special cross user grant if:
6501         * - The target is on another user.
6502         * - Apps on the current user can access the uri without any uid permissions.
6503         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6504         * grant uri permissions.
6505         */
6506        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6507                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6508                modeFlags, false /*without considering the uid permissions*/);
6509
6510        // Second...  is the provider allowing granting of URI permissions?
6511        if (!specialCrossUserGrant) {
6512            if (!pi.grantUriPermissions) {
6513                throw new SecurityException("Provider " + pi.packageName
6514                        + "/" + pi.name
6515                        + " does not allow granting of Uri permissions (uri "
6516                        + grantUri + ")");
6517            }
6518            if (pi.uriPermissionPatterns != null) {
6519                final int N = pi.uriPermissionPatterns.length;
6520                boolean allowed = false;
6521                for (int i=0; i<N; i++) {
6522                    if (pi.uriPermissionPatterns[i] != null
6523                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6524                        allowed = true;
6525                        break;
6526                    }
6527                }
6528                if (!allowed) {
6529                    throw new SecurityException("Provider " + pi.packageName
6530                            + "/" + pi.name
6531                            + " does not allow granting of permission to path of Uri "
6532                            + grantUri);
6533                }
6534            }
6535        }
6536
6537        // Third...  does the caller itself have permission to access
6538        // this uri?
6539        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6540            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6541                // Require they hold a strong enough Uri permission
6542                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6543                    throw new SecurityException("Uid " + callingUid
6544                            + " does not have permission to uri " + grantUri);
6545                }
6546            }
6547        }
6548        return targetUid;
6549    }
6550
6551    @Override
6552    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6553            final int modeFlags, int userId) {
6554        enforceNotIsolatedCaller("checkGrantUriPermission");
6555        synchronized(this) {
6556            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6557                    new GrantUri(userId, uri, false), modeFlags, -1);
6558        }
6559    }
6560
6561    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6562            final int modeFlags, UriPermissionOwner owner) {
6563        if (!Intent.isAccessUriMode(modeFlags)) {
6564            return;
6565        }
6566
6567        // So here we are: the caller has the assumed permission
6568        // to the uri, and the target doesn't.  Let's now give this to
6569        // the target.
6570
6571        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6572                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6573
6574        final String authority = grantUri.uri.getAuthority();
6575        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6576        if (pi == null) {
6577            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6578            return;
6579        }
6580
6581        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6582            grantUri.prefix = true;
6583        }
6584        final UriPermission perm = findOrCreateUriPermissionLocked(
6585                pi.packageName, targetPkg, targetUid, grantUri);
6586        perm.grantModes(modeFlags, owner);
6587    }
6588
6589    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6590            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6591        if (targetPkg == null) {
6592            throw new NullPointerException("targetPkg");
6593        }
6594        int targetUid;
6595        final IPackageManager pm = AppGlobals.getPackageManager();
6596        try {
6597            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6598        } catch (RemoteException ex) {
6599            return;
6600        }
6601
6602        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6603                targetUid);
6604        if (targetUid < 0) {
6605            return;
6606        }
6607
6608        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6609                owner);
6610    }
6611
6612    static class NeededUriGrants extends ArrayList<GrantUri> {
6613        final String targetPkg;
6614        final int targetUid;
6615        final int flags;
6616
6617        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6618            this.targetPkg = targetPkg;
6619            this.targetUid = targetUid;
6620            this.flags = flags;
6621        }
6622    }
6623
6624    /**
6625     * Like checkGrantUriPermissionLocked, but takes an Intent.
6626     */
6627    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6628            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6629        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6630                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6631                + " clip=" + (intent != null ? intent.getClipData() : null)
6632                + " from " + intent + "; flags=0x"
6633                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6634
6635        if (targetPkg == null) {
6636            throw new NullPointerException("targetPkg");
6637        }
6638
6639        if (intent == null) {
6640            return null;
6641        }
6642        Uri data = intent.getData();
6643        ClipData clip = intent.getClipData();
6644        if (data == null && clip == null) {
6645            return null;
6646        }
6647        // Default userId for uris in the intent (if they don't specify it themselves)
6648        int contentUserHint = intent.getContentUserHint();
6649        if (contentUserHint == UserHandle.USER_CURRENT) {
6650            contentUserHint = UserHandle.getUserId(callingUid);
6651        }
6652        final IPackageManager pm = AppGlobals.getPackageManager();
6653        int targetUid;
6654        if (needed != null) {
6655            targetUid = needed.targetUid;
6656        } else {
6657            try {
6658                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6659            } catch (RemoteException ex) {
6660                return null;
6661            }
6662            if (targetUid < 0) {
6663                if (DEBUG_URI_PERMISSION) {
6664                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6665                            + " on user " + targetUserId);
6666                }
6667                return null;
6668            }
6669        }
6670        if (data != null) {
6671            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6672            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6673                    targetUid);
6674            if (targetUid > 0) {
6675                if (needed == null) {
6676                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6677                }
6678                needed.add(grantUri);
6679            }
6680        }
6681        if (clip != null) {
6682            for (int i=0; i<clip.getItemCount(); i++) {
6683                Uri uri = clip.getItemAt(i).getUri();
6684                if (uri != null) {
6685                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6686                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6687                            targetUid);
6688                    if (targetUid > 0) {
6689                        if (needed == null) {
6690                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6691                        }
6692                        needed.add(grantUri);
6693                    }
6694                } else {
6695                    Intent clipIntent = clip.getItemAt(i).getIntent();
6696                    if (clipIntent != null) {
6697                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6698                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6699                        if (newNeeded != null) {
6700                            needed = newNeeded;
6701                        }
6702                    }
6703                }
6704            }
6705        }
6706
6707        return needed;
6708    }
6709
6710    /**
6711     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6712     */
6713    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6714            UriPermissionOwner owner) {
6715        if (needed != null) {
6716            for (int i=0; i<needed.size(); i++) {
6717                GrantUri grantUri = needed.get(i);
6718                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6719                        grantUri, needed.flags, owner);
6720            }
6721        }
6722    }
6723
6724    void grantUriPermissionFromIntentLocked(int callingUid,
6725            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6726        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6727                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6728        if (needed == null) {
6729            return;
6730        }
6731
6732        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6733    }
6734
6735    @Override
6736    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6737            final int modeFlags, int userId) {
6738        enforceNotIsolatedCaller("grantUriPermission");
6739        GrantUri grantUri = new GrantUri(userId, uri, false);
6740        synchronized(this) {
6741            final ProcessRecord r = getRecordForAppLocked(caller);
6742            if (r == null) {
6743                throw new SecurityException("Unable to find app for caller "
6744                        + caller
6745                        + " when granting permission to uri " + grantUri);
6746            }
6747            if (targetPkg == null) {
6748                throw new IllegalArgumentException("null target");
6749            }
6750            if (grantUri == null) {
6751                throw new IllegalArgumentException("null uri");
6752            }
6753
6754            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6755                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6756                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6757                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6758
6759            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6760                    UserHandle.getUserId(r.uid));
6761        }
6762    }
6763
6764    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6765        if (perm.modeFlags == 0) {
6766            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6767                    perm.targetUid);
6768            if (perms != null) {
6769                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6770                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6771
6772                perms.remove(perm.uri);
6773                if (perms.isEmpty()) {
6774                    mGrantedUriPermissions.remove(perm.targetUid);
6775                }
6776            }
6777        }
6778    }
6779
6780    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6781        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6782
6783        final IPackageManager pm = AppGlobals.getPackageManager();
6784        final String authority = grantUri.uri.getAuthority();
6785        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6786        if (pi == null) {
6787            Slog.w(TAG, "No content provider found for permission revoke: "
6788                    + grantUri.toSafeString());
6789            return;
6790        }
6791
6792        // Does the caller have this permission on the URI?
6793        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6794            // Right now, if you are not the original owner of the permission,
6795            // you are not allowed to revoke it.
6796            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6797                throw new SecurityException("Uid " + callingUid
6798                        + " does not have permission to uri " + grantUri);
6799            //}
6800        }
6801
6802        boolean persistChanged = false;
6803
6804        // Go through all of the permissions and remove any that match.
6805        int N = mGrantedUriPermissions.size();
6806        for (int i = 0; i < N; i++) {
6807            final int targetUid = mGrantedUriPermissions.keyAt(i);
6808            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6809
6810            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6811                final UriPermission perm = it.next();
6812                if (perm.uri.sourceUserId == grantUri.sourceUserId
6813                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6814                    if (DEBUG_URI_PERMISSION)
6815                        Slog.v(TAG,
6816                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6817                    persistChanged |= perm.revokeModes(
6818                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6819                    if (perm.modeFlags == 0) {
6820                        it.remove();
6821                    }
6822                }
6823            }
6824
6825            if (perms.isEmpty()) {
6826                mGrantedUriPermissions.remove(targetUid);
6827                N--;
6828                i--;
6829            }
6830        }
6831
6832        if (persistChanged) {
6833            schedulePersistUriGrants();
6834        }
6835    }
6836
6837    @Override
6838    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6839            int userId) {
6840        enforceNotIsolatedCaller("revokeUriPermission");
6841        synchronized(this) {
6842            final ProcessRecord r = getRecordForAppLocked(caller);
6843            if (r == null) {
6844                throw new SecurityException("Unable to find app for caller "
6845                        + caller
6846                        + " when revoking permission to uri " + uri);
6847            }
6848            if (uri == null) {
6849                Slog.w(TAG, "revokeUriPermission: null uri");
6850                return;
6851            }
6852
6853            if (!Intent.isAccessUriMode(modeFlags)) {
6854                return;
6855            }
6856
6857            final IPackageManager pm = AppGlobals.getPackageManager();
6858            final String authority = uri.getAuthority();
6859            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6860            if (pi == null) {
6861                Slog.w(TAG, "No content provider found for permission revoke: "
6862                        + uri.toSafeString());
6863                return;
6864            }
6865
6866            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6867        }
6868    }
6869
6870    /**
6871     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6872     * given package.
6873     *
6874     * @param packageName Package name to match, or {@code null} to apply to all
6875     *            packages.
6876     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6877     *            to all users.
6878     * @param persistable If persistable grants should be removed.
6879     */
6880    private void removeUriPermissionsForPackageLocked(
6881            String packageName, int userHandle, boolean persistable) {
6882        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6883            throw new IllegalArgumentException("Must narrow by either package or user");
6884        }
6885
6886        boolean persistChanged = false;
6887
6888        int N = mGrantedUriPermissions.size();
6889        for (int i = 0; i < N; i++) {
6890            final int targetUid = mGrantedUriPermissions.keyAt(i);
6891            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6892
6893            // Only inspect grants matching user
6894            if (userHandle == UserHandle.USER_ALL
6895                    || userHandle == UserHandle.getUserId(targetUid)) {
6896                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6897                    final UriPermission perm = it.next();
6898
6899                    // Only inspect grants matching package
6900                    if (packageName == null || perm.sourcePkg.equals(packageName)
6901                            || perm.targetPkg.equals(packageName)) {
6902                        persistChanged |= perm.revokeModes(
6903                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6904
6905                        // Only remove when no modes remain; any persisted grants
6906                        // will keep this alive.
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
6921        if (persistChanged) {
6922            schedulePersistUriGrants();
6923        }
6924    }
6925
6926    @Override
6927    public IBinder newUriPermissionOwner(String name) {
6928        enforceNotIsolatedCaller("newUriPermissionOwner");
6929        synchronized(this) {
6930            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6931            return owner.getExternalTokenLocked();
6932        }
6933    }
6934
6935    @Override
6936    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6937            final int modeFlags, int sourceUserId, int targetUserId) {
6938        synchronized(this) {
6939            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6940            if (owner == null) {
6941                throw new IllegalArgumentException("Unknown owner: " + token);
6942            }
6943            if (fromUid != Binder.getCallingUid()) {
6944                if (Binder.getCallingUid() != Process.myUid()) {
6945                    // Only system code can grant URI permissions on behalf
6946                    // of other users.
6947                    throw new SecurityException("nice try");
6948                }
6949            }
6950            if (targetPkg == null) {
6951                throw new IllegalArgumentException("null target");
6952            }
6953            if (uri == null) {
6954                throw new IllegalArgumentException("null uri");
6955            }
6956
6957            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
6958                    modeFlags, owner, targetUserId);
6959        }
6960    }
6961
6962    @Override
6963    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6964        synchronized(this) {
6965            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6966            if (owner == null) {
6967                throw new IllegalArgumentException("Unknown owner: " + token);
6968            }
6969
6970            if (uri == null) {
6971                owner.removeUriPermissionsLocked(mode);
6972            } else {
6973                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6974            }
6975        }
6976    }
6977
6978    private void schedulePersistUriGrants() {
6979        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6980            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6981                    10 * DateUtils.SECOND_IN_MILLIS);
6982        }
6983    }
6984
6985    private void writeGrantedUriPermissions() {
6986        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6987
6988        // Snapshot permissions so we can persist without lock
6989        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6990        synchronized (this) {
6991            final int size = mGrantedUriPermissions.size();
6992            for (int i = 0; i < size; i++) {
6993                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6994                for (UriPermission perm : perms.values()) {
6995                    if (perm.persistedModeFlags != 0) {
6996                        persist.add(perm.snapshot());
6997                    }
6998                }
6999            }
7000        }
7001
7002        FileOutputStream fos = null;
7003        try {
7004            fos = mGrantFile.startWrite();
7005
7006            XmlSerializer out = new FastXmlSerializer();
7007            out.setOutput(fos, "utf-8");
7008            out.startDocument(null, true);
7009            out.startTag(null, TAG_URI_GRANTS);
7010            for (UriPermission.Snapshot perm : persist) {
7011                out.startTag(null, TAG_URI_GRANT);
7012                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7013                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7014                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7015                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7016                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7017                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7018                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7019                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7020                out.endTag(null, TAG_URI_GRANT);
7021            }
7022            out.endTag(null, TAG_URI_GRANTS);
7023            out.endDocument();
7024
7025            mGrantFile.finishWrite(fos);
7026        } catch (IOException e) {
7027            if (fos != null) {
7028                mGrantFile.failWrite(fos);
7029            }
7030        }
7031    }
7032
7033    private void readGrantedUriPermissionsLocked() {
7034        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7035
7036        final long now = System.currentTimeMillis();
7037
7038        FileInputStream fis = null;
7039        try {
7040            fis = mGrantFile.openRead();
7041            final XmlPullParser in = Xml.newPullParser();
7042            in.setInput(fis, null);
7043
7044            int type;
7045            while ((type = in.next()) != END_DOCUMENT) {
7046                final String tag = in.getName();
7047                if (type == START_TAG) {
7048                    if (TAG_URI_GRANT.equals(tag)) {
7049                        final int sourceUserId;
7050                        final int targetUserId;
7051                        final int userHandle = readIntAttribute(in,
7052                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7053                        if (userHandle != UserHandle.USER_NULL) {
7054                            // For backwards compatibility.
7055                            sourceUserId = userHandle;
7056                            targetUserId = userHandle;
7057                        } else {
7058                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7059                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7060                        }
7061                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7062                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7063                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7064                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7065                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7066                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7067
7068                        // Sanity check that provider still belongs to source package
7069                        final ProviderInfo pi = getProviderInfoLocked(
7070                                uri.getAuthority(), sourceUserId);
7071                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7072                            int targetUid = -1;
7073                            try {
7074                                targetUid = AppGlobals.getPackageManager()
7075                                        .getPackageUid(targetPkg, targetUserId);
7076                            } catch (RemoteException e) {
7077                            }
7078                            if (targetUid != -1) {
7079                                final UriPermission perm = findOrCreateUriPermissionLocked(
7080                                        sourcePkg, targetPkg, targetUid,
7081                                        new GrantUri(sourceUserId, uri, prefix));
7082                                perm.initPersistedModes(modeFlags, createdTime);
7083                            }
7084                        } else {
7085                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7086                                    + " but instead found " + pi);
7087                        }
7088                    }
7089                }
7090            }
7091        } catch (FileNotFoundException e) {
7092            // Missing grants is okay
7093        } catch (IOException e) {
7094            Log.wtf(TAG, "Failed reading Uri grants", e);
7095        } catch (XmlPullParserException e) {
7096            Log.wtf(TAG, "Failed reading Uri grants", e);
7097        } finally {
7098            IoUtils.closeQuietly(fis);
7099        }
7100    }
7101
7102    @Override
7103    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7104        enforceNotIsolatedCaller("takePersistableUriPermission");
7105
7106        Preconditions.checkFlagsArgument(modeFlags,
7107                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7108
7109        synchronized (this) {
7110            final int callingUid = Binder.getCallingUid();
7111            boolean persistChanged = false;
7112            GrantUri grantUri = new GrantUri(userId, uri, false);
7113
7114            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7115                    new GrantUri(userId, uri, false));
7116            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7117                    new GrantUri(userId, uri, true));
7118
7119            final boolean exactValid = (exactPerm != null)
7120                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7121            final boolean prefixValid = (prefixPerm != null)
7122                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7123
7124            if (!(exactValid || prefixValid)) {
7125                throw new SecurityException("No persistable permission grants found for UID "
7126                        + callingUid + " and Uri " + grantUri.toSafeString());
7127            }
7128
7129            if (exactValid) {
7130                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7131            }
7132            if (prefixValid) {
7133                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7134            }
7135
7136            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7137
7138            if (persistChanged) {
7139                schedulePersistUriGrants();
7140            }
7141        }
7142    }
7143
7144    @Override
7145    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7146        enforceNotIsolatedCaller("releasePersistableUriPermission");
7147
7148        Preconditions.checkFlagsArgument(modeFlags,
7149                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7150
7151        synchronized (this) {
7152            final int callingUid = Binder.getCallingUid();
7153            boolean persistChanged = false;
7154
7155            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7156                    new GrantUri(userId, uri, false));
7157            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7158                    new GrantUri(userId, uri, true));
7159            if (exactPerm == null && prefixPerm == null) {
7160                throw new SecurityException("No permission grants found for UID " + callingUid
7161                        + " and Uri " + uri.toSafeString());
7162            }
7163
7164            if (exactPerm != null) {
7165                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7166                removeUriPermissionIfNeededLocked(exactPerm);
7167            }
7168            if (prefixPerm != null) {
7169                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7170                removeUriPermissionIfNeededLocked(prefixPerm);
7171            }
7172
7173            if (persistChanged) {
7174                schedulePersistUriGrants();
7175            }
7176        }
7177    }
7178
7179    /**
7180     * Prune any older {@link UriPermission} for the given UID until outstanding
7181     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7182     *
7183     * @return if any mutations occured that require persisting.
7184     */
7185    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7186        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7187        if (perms == null) return false;
7188        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7189
7190        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7191        for (UriPermission perm : perms.values()) {
7192            if (perm.persistedModeFlags != 0) {
7193                persisted.add(perm);
7194            }
7195        }
7196
7197        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7198        if (trimCount <= 0) return false;
7199
7200        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7201        for (int i = 0; i < trimCount; i++) {
7202            final UriPermission perm = persisted.get(i);
7203
7204            if (DEBUG_URI_PERMISSION) {
7205                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7206            }
7207
7208            perm.releasePersistableModes(~0);
7209            removeUriPermissionIfNeededLocked(perm);
7210        }
7211
7212        return true;
7213    }
7214
7215    @Override
7216    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7217            String packageName, boolean incoming) {
7218        enforceNotIsolatedCaller("getPersistedUriPermissions");
7219        Preconditions.checkNotNull(packageName, "packageName");
7220
7221        final int callingUid = Binder.getCallingUid();
7222        final IPackageManager pm = AppGlobals.getPackageManager();
7223        try {
7224            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7225            if (packageUid != callingUid) {
7226                throw new SecurityException(
7227                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7228            }
7229        } catch (RemoteException e) {
7230            throw new SecurityException("Failed to verify package name ownership");
7231        }
7232
7233        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7234        synchronized (this) {
7235            if (incoming) {
7236                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7237                        callingUid);
7238                if (perms == null) {
7239                    Slog.w(TAG, "No permission grants found for " + packageName);
7240                } else {
7241                    for (UriPermission perm : perms.values()) {
7242                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7243                            result.add(perm.buildPersistedPublicApiObject());
7244                        }
7245                    }
7246                }
7247            } else {
7248                final int size = mGrantedUriPermissions.size();
7249                for (int i = 0; i < size; i++) {
7250                    final ArrayMap<GrantUri, UriPermission> perms =
7251                            mGrantedUriPermissions.valueAt(i);
7252                    for (UriPermission perm : perms.values()) {
7253                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7254                            result.add(perm.buildPersistedPublicApiObject());
7255                        }
7256                    }
7257                }
7258            }
7259        }
7260        return new ParceledListSlice<android.content.UriPermission>(result);
7261    }
7262
7263    @Override
7264    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7265        synchronized (this) {
7266            ProcessRecord app =
7267                who != null ? getRecordForAppLocked(who) : null;
7268            if (app == null) return;
7269
7270            Message msg = Message.obtain();
7271            msg.what = WAIT_FOR_DEBUGGER_MSG;
7272            msg.obj = app;
7273            msg.arg1 = waiting ? 1 : 0;
7274            mHandler.sendMessage(msg);
7275        }
7276    }
7277
7278    @Override
7279    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7280        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7281        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7282        outInfo.availMem = Process.getFreeMemory();
7283        outInfo.totalMem = Process.getTotalMemory();
7284        outInfo.threshold = homeAppMem;
7285        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7286        outInfo.hiddenAppThreshold = cachedAppMem;
7287        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7288                ProcessList.SERVICE_ADJ);
7289        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7290                ProcessList.VISIBLE_APP_ADJ);
7291        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7292                ProcessList.FOREGROUND_APP_ADJ);
7293    }
7294
7295    // =========================================================
7296    // TASK MANAGEMENT
7297    // =========================================================
7298
7299    @Override
7300    public List<IAppTask> getAppTasks() {
7301        final PackageManager pm = mContext.getPackageManager();
7302        int callingUid = Binder.getCallingUid();
7303        long ident = Binder.clearCallingIdentity();
7304
7305        // Compose the list of packages for this id to test against
7306        HashSet<String> packages = new HashSet<String>();
7307        String[] uidPackages = pm.getPackagesForUid(callingUid);
7308        for (int i = 0; i < uidPackages.length; i++) {
7309            packages.add(uidPackages[i]);
7310        }
7311
7312        synchronized(this) {
7313            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7314            try {
7315                if (localLOGV) Slog.v(TAG, "getAppTasks");
7316
7317                final int N = mRecentTasks.size();
7318                for (int i = 0; i < N; i++) {
7319                    TaskRecord tr = mRecentTasks.get(i);
7320                    // Skip tasks that are not created by the caller
7321                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7322                        ActivityManager.RecentTaskInfo taskInfo =
7323                                createRecentTaskInfoFromTaskRecord(tr);
7324                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7325                        list.add(taskImpl);
7326                    }
7327                }
7328            } finally {
7329                Binder.restoreCallingIdentity(ident);
7330            }
7331            return list;
7332        }
7333    }
7334
7335    @Override
7336    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7337        final int callingUid = Binder.getCallingUid();
7338        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7339
7340        synchronized(this) {
7341            if (localLOGV) Slog.v(
7342                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7343
7344            final boolean allowed = checkCallingPermission(
7345                    android.Manifest.permission.GET_TASKS)
7346                    == PackageManager.PERMISSION_GRANTED;
7347            if (!allowed) {
7348                Slog.w(TAG, "getTasks: caller " + callingUid
7349                        + " does not hold GET_TASKS; limiting output");
7350            }
7351
7352            // TODO: Improve with MRU list from all ActivityStacks.
7353            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7354        }
7355
7356        return list;
7357    }
7358
7359    TaskRecord getMostRecentTask() {
7360        return mRecentTasks.get(0);
7361    }
7362
7363    /**
7364     * Creates a new RecentTaskInfo from a TaskRecord.
7365     */
7366    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7367        // Update the task description to reflect any changes in the task stack
7368        tr.updateTaskDescription();
7369
7370        // Compose the recent task info
7371        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7372        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7373        rti.persistentId = tr.taskId;
7374        rti.baseIntent = new Intent(tr.getBaseIntent());
7375        rti.origActivity = tr.origActivity;
7376        rti.description = tr.lastDescription;
7377        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7378        rti.userId = tr.userId;
7379        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7380        rti.firstActiveTime = tr.firstActiveTime;
7381        rti.lastActiveTime = tr.lastActiveTime;
7382        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7383        return rti;
7384    }
7385
7386    @Override
7387    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7388        final int callingUid = Binder.getCallingUid();
7389        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7390                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7391
7392        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7393        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7394        synchronized (this) {
7395            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7396                    == PackageManager.PERMISSION_GRANTED;
7397            if (!allowed) {
7398                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7399                        + " does not hold GET_TASKS; limiting output");
7400            }
7401            final boolean detailed = checkCallingPermission(
7402                    android.Manifest.permission.GET_DETAILED_TASKS)
7403                    == PackageManager.PERMISSION_GRANTED;
7404
7405            IPackageManager pm = AppGlobals.getPackageManager();
7406
7407            final int N = mRecentTasks.size();
7408            ArrayList<ActivityManager.RecentTaskInfo> res
7409                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7410                            maxNum < N ? maxNum : N);
7411
7412            final Set<Integer> includedUsers;
7413            if (includeProfiles) {
7414                includedUsers = getProfileIdsLocked(userId);
7415            } else {
7416                includedUsers = new HashSet<Integer>();
7417            }
7418            includedUsers.add(Integer.valueOf(userId));
7419
7420            // Regroup affiliated tasks together.
7421            for (int i = 0; i < N; ) {
7422                TaskRecord task = mRecentTasks.remove(i);
7423                if (mTmpRecents.contains(task)) {
7424                    continue;
7425                }
7426                int affiliatedTaskId = task.mAffiliatedTaskId;
7427                while (true) {
7428                    TaskRecord next = task.mNextAffiliate;
7429                    if (next == null) {
7430                        break;
7431                    }
7432                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7433                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7434                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7435                        task.setNextAffiliate(null);
7436                        if (next.mPrevAffiliate == task) {
7437                            next.setPrevAffiliate(null);
7438                        }
7439                        break;
7440                    }
7441                    if (next.mPrevAffiliate != task) {
7442                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7443                                next.mPrevAffiliate + " task=" + task);
7444                        next.setPrevAffiliate(null);
7445                        break;
7446                    }
7447                    if (!mRecentTasks.contains(next)) {
7448                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7449                        task.setNextAffiliate(null);
7450                        if (next.mPrevAffiliate == task) {
7451                            next.setPrevAffiliate(null);
7452                        }
7453                        break;
7454                    }
7455                    task = next;
7456                }
7457                // task is now the end of the list
7458                do {
7459                    mRecentTasks.remove(task);
7460                    mRecentTasks.add(i++, task);
7461                    mTmpRecents.add(task);
7462                } while ((task = task.mPrevAffiliate) != null);
7463            }
7464            mTmpRecents.clear();
7465            // mRecentTasks is now in sorted, affiliated order.
7466
7467            for (int i=0; i<N && maxNum > 0; i++) {
7468                TaskRecord tr = mRecentTasks.get(i);
7469                // Only add calling user or related users recent tasks
7470                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7471
7472                // Return the entry if desired by the caller.  We always return
7473                // the first entry, because callers always expect this to be the
7474                // foreground app.  We may filter others if the caller has
7475                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7476                // we should exclude the entry.
7477
7478                if (i == 0
7479                        || withExcluded
7480                        || (tr.intent == null)
7481                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7482                                == 0)) {
7483                    if (!allowed) {
7484                        // If the caller doesn't have the GET_TASKS permission, then only
7485                        // allow them to see a small subset of tasks -- their own and home.
7486                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7487                            continue;
7488                        }
7489                    }
7490                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7491                        // Don't include auto remove tasks that are finished or finishing.
7492                        continue;
7493                    }
7494
7495                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7496                    if (!detailed) {
7497                        rti.baseIntent.replaceExtras((Bundle)null);
7498                    }
7499
7500                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7501                        // Check whether this activity is currently available.
7502                        try {
7503                            if (rti.origActivity != null) {
7504                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7505                                        == null) {
7506                                    continue;
7507                                }
7508                            } else if (rti.baseIntent != null) {
7509                                if (pm.queryIntentActivities(rti.baseIntent,
7510                                        null, 0, userId) == null) {
7511                                    continue;
7512                                }
7513                            }
7514                        } catch (RemoteException e) {
7515                            // Will never happen.
7516                        }
7517                    }
7518
7519                    res.add(rti);
7520                    maxNum--;
7521                }
7522            }
7523            return res;
7524        }
7525    }
7526
7527    private TaskRecord recentTaskForIdLocked(int id) {
7528        final int N = mRecentTasks.size();
7529            for (int i=0; i<N; i++) {
7530                TaskRecord tr = mRecentTasks.get(i);
7531                if (tr.taskId == id) {
7532                    return tr;
7533                }
7534            }
7535            return null;
7536    }
7537
7538    @Override
7539    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7540        synchronized (this) {
7541            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7542                    "getTaskThumbnail()");
7543            TaskRecord tr = recentTaskForIdLocked(id);
7544            if (tr != null) {
7545                return tr.getTaskThumbnailLocked();
7546            }
7547        }
7548        return null;
7549    }
7550
7551    @Override
7552    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7553        synchronized (this) {
7554            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7555            if (r != null) {
7556                r.taskDescription = td;
7557                r.task.updateTaskDescription();
7558            }
7559        }
7560    }
7561
7562    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7563        if (!pr.killedByAm) {
7564            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7565            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7566                    pr.processName, pr.setAdj, reason);
7567            pr.killedByAm = true;
7568            Process.killProcessQuiet(pr.pid);
7569            Process.killProcessGroup(pr.info.uid, pr.pid);
7570        }
7571    }
7572
7573    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7574        tr.disposeThumbnail();
7575        mRecentTasks.remove(tr);
7576        tr.closeRecentsChain();
7577        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7578        Intent baseIntent = new Intent(
7579                tr.intent != null ? tr.intent : tr.affinityIntent);
7580        ComponentName component = baseIntent.getComponent();
7581        if (component == null) {
7582            Slog.w(TAG, "Now component for base intent of task: " + tr);
7583            return;
7584        }
7585
7586        // Find any running services associated with this app.
7587        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7588
7589        if (killProcesses) {
7590            // Find any running processes associated with this app.
7591            final String pkg = component.getPackageName();
7592            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7593            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7594            for (int i=0; i<pmap.size(); i++) {
7595                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7596                for (int j=0; j<uids.size(); j++) {
7597                    ProcessRecord proc = uids.valueAt(j);
7598                    if (proc.userId != tr.userId) {
7599                        continue;
7600                    }
7601                    if (!proc.pkgList.containsKey(pkg)) {
7602                        continue;
7603                    }
7604                    procs.add(proc);
7605                }
7606            }
7607
7608            // Kill the running processes.
7609            for (int i=0; i<procs.size(); i++) {
7610                ProcessRecord pr = procs.get(i);
7611                if (pr == mHomeProcess) {
7612                    // Don't kill the home process along with tasks from the same package.
7613                    continue;
7614                }
7615                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7616                    killUnneededProcessLocked(pr, "remove task");
7617                } else {
7618                    pr.waitingToKill = "remove task";
7619                }
7620            }
7621        }
7622    }
7623
7624    /**
7625     * Removes the task with the specified task id.
7626     *
7627     * @param taskId Identifier of the task to be removed.
7628     * @param flags Additional operational flags.  May be 0 or
7629     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7630     * @return Returns true if the given task was found and removed.
7631     */
7632    private boolean removeTaskByIdLocked(int taskId, int flags) {
7633        TaskRecord tr = recentTaskForIdLocked(taskId);
7634        if (tr != null) {
7635            tr.removeTaskActivitiesLocked();
7636            cleanUpRemovedTaskLocked(tr, flags);
7637            if (tr.isPersistable) {
7638                notifyTaskPersisterLocked(tr, true);
7639            }
7640            return true;
7641        }
7642        return false;
7643    }
7644
7645    @Override
7646    public boolean removeTask(int taskId, int flags) {
7647        synchronized (this) {
7648            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7649                    "removeTask()");
7650            long ident = Binder.clearCallingIdentity();
7651            try {
7652                return removeTaskByIdLocked(taskId, flags);
7653            } finally {
7654                Binder.restoreCallingIdentity(ident);
7655            }
7656        }
7657    }
7658
7659    /**
7660     * TODO: Add mController hook
7661     */
7662    @Override
7663    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7664        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7665                "moveTaskToFront()");
7666
7667        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7668        synchronized(this) {
7669            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7670                    Binder.getCallingUid(), "Task to front")) {
7671                ActivityOptions.abort(options);
7672                return;
7673            }
7674            final long origId = Binder.clearCallingIdentity();
7675            try {
7676                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7677                if (task == null) {
7678                    return;
7679                }
7680                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7681                    mStackSupervisor.showLockTaskToast();
7682                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7683                    return;
7684                }
7685                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7686                if (prev != null && prev.isRecentsActivity()) {
7687                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7688                }
7689                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7690            } finally {
7691                Binder.restoreCallingIdentity(origId);
7692            }
7693            ActivityOptions.abort(options);
7694        }
7695    }
7696
7697    @Override
7698    public void moveTaskToBack(int taskId) {
7699        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7700                "moveTaskToBack()");
7701
7702        synchronized(this) {
7703            TaskRecord tr = recentTaskForIdLocked(taskId);
7704            if (tr != null) {
7705                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7706                ActivityStack stack = tr.stack;
7707                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7708                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7709                            Binder.getCallingUid(), "Task to back")) {
7710                        return;
7711                    }
7712                }
7713                final long origId = Binder.clearCallingIdentity();
7714                try {
7715                    stack.moveTaskToBackLocked(taskId, null);
7716                } finally {
7717                    Binder.restoreCallingIdentity(origId);
7718                }
7719            }
7720        }
7721    }
7722
7723    /**
7724     * Moves an activity, and all of the other activities within the same task, to the bottom
7725     * of the history stack.  The activity's order within the task is unchanged.
7726     *
7727     * @param token A reference to the activity we wish to move
7728     * @param nonRoot If false then this only works if the activity is the root
7729     *                of a task; if true it will work for any activity in a task.
7730     * @return Returns true if the move completed, false if not.
7731     */
7732    @Override
7733    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7734        enforceNotIsolatedCaller("moveActivityTaskToBack");
7735        synchronized(this) {
7736            final long origId = Binder.clearCallingIdentity();
7737            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7738            if (taskId >= 0) {
7739                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7740            }
7741            Binder.restoreCallingIdentity(origId);
7742        }
7743        return false;
7744    }
7745
7746    @Override
7747    public void moveTaskBackwards(int task) {
7748        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7749                "moveTaskBackwards()");
7750
7751        synchronized(this) {
7752            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7753                    Binder.getCallingUid(), "Task backwards")) {
7754                return;
7755            }
7756            final long origId = Binder.clearCallingIdentity();
7757            moveTaskBackwardsLocked(task);
7758            Binder.restoreCallingIdentity(origId);
7759        }
7760    }
7761
7762    private final void moveTaskBackwardsLocked(int task) {
7763        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7764    }
7765
7766    @Override
7767    public IBinder getHomeActivityToken() throws RemoteException {
7768        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7769                "getHomeActivityToken()");
7770        synchronized (this) {
7771            return mStackSupervisor.getHomeActivityToken();
7772        }
7773    }
7774
7775    @Override
7776    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7777            IActivityContainerCallback callback) throws RemoteException {
7778        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7779                "createActivityContainer()");
7780        synchronized (this) {
7781            if (parentActivityToken == null) {
7782                throw new IllegalArgumentException("parent token must not be null");
7783            }
7784            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7785            if (r == null) {
7786                return null;
7787            }
7788            if (callback == null) {
7789                throw new IllegalArgumentException("callback must not be null");
7790            }
7791            return mStackSupervisor.createActivityContainer(r, callback);
7792        }
7793    }
7794
7795    @Override
7796    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7797        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7798                "deleteActivityContainer()");
7799        synchronized (this) {
7800            mStackSupervisor.deleteActivityContainer(container);
7801        }
7802    }
7803
7804    @Override
7805    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7806            throws RemoteException {
7807        synchronized (this) {
7808            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7809            if (stack != null) {
7810                return stack.mActivityContainer;
7811            }
7812            return null;
7813        }
7814    }
7815
7816    @Override
7817    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7818        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7819                "moveTaskToStack()");
7820        if (stackId == HOME_STACK_ID) {
7821            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7822                    new RuntimeException("here").fillInStackTrace());
7823        }
7824        synchronized (this) {
7825            long ident = Binder.clearCallingIdentity();
7826            try {
7827                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7828                        + stackId + " toTop=" + toTop);
7829                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7830            } finally {
7831                Binder.restoreCallingIdentity(ident);
7832            }
7833        }
7834    }
7835
7836    @Override
7837    public void resizeStack(int stackBoxId, Rect bounds) {
7838        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7839                "resizeStackBox()");
7840        long ident = Binder.clearCallingIdentity();
7841        try {
7842            mWindowManager.resizeStack(stackBoxId, bounds);
7843        } finally {
7844            Binder.restoreCallingIdentity(ident);
7845        }
7846    }
7847
7848    @Override
7849    public List<StackInfo> getAllStackInfos() {
7850        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7851                "getAllStackInfos()");
7852        long ident = Binder.clearCallingIdentity();
7853        try {
7854            synchronized (this) {
7855                return mStackSupervisor.getAllStackInfosLocked();
7856            }
7857        } finally {
7858            Binder.restoreCallingIdentity(ident);
7859        }
7860    }
7861
7862    @Override
7863    public StackInfo getStackInfo(int stackId) {
7864        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7865                "getStackInfo()");
7866        long ident = Binder.clearCallingIdentity();
7867        try {
7868            synchronized (this) {
7869                return mStackSupervisor.getStackInfoLocked(stackId);
7870            }
7871        } finally {
7872            Binder.restoreCallingIdentity(ident);
7873        }
7874    }
7875
7876    @Override
7877    public boolean isInHomeStack(int taskId) {
7878        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7879                "getStackInfo()");
7880        long ident = Binder.clearCallingIdentity();
7881        try {
7882            synchronized (this) {
7883                TaskRecord tr = recentTaskForIdLocked(taskId);
7884                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7885            }
7886        } finally {
7887            Binder.restoreCallingIdentity(ident);
7888        }
7889    }
7890
7891    @Override
7892    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7893        synchronized(this) {
7894            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7895        }
7896    }
7897
7898    private boolean isLockTaskAuthorized(String pkg) {
7899        final DevicePolicyManager dpm = (DevicePolicyManager)
7900                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7901        try {
7902            int uid = mContext.getPackageManager().getPackageUid(pkg,
7903                    Binder.getCallingUserHandle().getIdentifier());
7904            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7905        } catch (NameNotFoundException e) {
7906            return false;
7907        }
7908    }
7909
7910    void startLockTaskMode(TaskRecord task) {
7911        final String pkg;
7912        synchronized (this) {
7913            pkg = task.intent.getComponent().getPackageName();
7914        }
7915        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7916        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7917            final TaskRecord taskRecord = task;
7918            mHandler.post(new Runnable() {
7919                @Override
7920                public void run() {
7921                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7922                }
7923            });
7924            return;
7925        }
7926        long ident = Binder.clearCallingIdentity();
7927        try {
7928            synchronized (this) {
7929                // Since we lost lock on task, make sure it is still there.
7930                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7931                if (task != null) {
7932                    if (!isSystemInitiated
7933                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7934                        throw new IllegalArgumentException("Invalid task, not in foreground");
7935                    }
7936                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7937                }
7938            }
7939        } finally {
7940            Binder.restoreCallingIdentity(ident);
7941        }
7942    }
7943
7944    @Override
7945    public void startLockTaskMode(int taskId) {
7946        final TaskRecord task;
7947        long ident = Binder.clearCallingIdentity();
7948        try {
7949            synchronized (this) {
7950                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7951            }
7952        } finally {
7953            Binder.restoreCallingIdentity(ident);
7954        }
7955        if (task != null) {
7956            startLockTaskMode(task);
7957        }
7958    }
7959
7960    @Override
7961    public void startLockTaskMode(IBinder token) {
7962        final TaskRecord task;
7963        long ident = Binder.clearCallingIdentity();
7964        try {
7965            synchronized (this) {
7966                final ActivityRecord r = ActivityRecord.forToken(token);
7967                if (r == null) {
7968                    return;
7969                }
7970                task = r.task;
7971            }
7972        } finally {
7973            Binder.restoreCallingIdentity(ident);
7974        }
7975        if (task != null) {
7976            startLockTaskMode(task);
7977        }
7978    }
7979
7980    @Override
7981    public void startLockTaskModeOnCurrent() throws RemoteException {
7982        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7983        ActivityRecord r = null;
7984        synchronized (this) {
7985            r = mStackSupervisor.topRunningActivityLocked();
7986        }
7987        startLockTaskMode(r.task);
7988    }
7989
7990    @Override
7991    public void stopLockTaskMode() {
7992        // Verify that the user matches the package of the intent for the TaskRecord
7993        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7994        // and stopLockTaskMode.
7995        final int callingUid = Binder.getCallingUid();
7996        if (callingUid != Process.SYSTEM_UID) {
7997            try {
7998                String pkg =
7999                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8000                int uid = mContext.getPackageManager().getPackageUid(pkg,
8001                        Binder.getCallingUserHandle().getIdentifier());
8002                if (uid != callingUid) {
8003                    throw new SecurityException("Invalid uid, expected " + uid);
8004                }
8005            } catch (NameNotFoundException e) {
8006                Log.d(TAG, "stopLockTaskMode " + e);
8007                return;
8008            }
8009        }
8010        long ident = Binder.clearCallingIdentity();
8011        try {
8012            Log.d(TAG, "stopLockTaskMode");
8013            // Stop lock task
8014            synchronized (this) {
8015                mStackSupervisor.setLockTaskModeLocked(null, false);
8016            }
8017        } finally {
8018            Binder.restoreCallingIdentity(ident);
8019        }
8020    }
8021
8022    @Override
8023    public void stopLockTaskModeOnCurrent() throws RemoteException {
8024        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8025        long ident = Binder.clearCallingIdentity();
8026        try {
8027            stopLockTaskMode();
8028        } finally {
8029            Binder.restoreCallingIdentity(ident);
8030        }
8031    }
8032
8033    @Override
8034    public boolean isInLockTaskMode() {
8035        synchronized (this) {
8036            return mStackSupervisor.isInLockTaskMode();
8037        }
8038    }
8039
8040    // =========================================================
8041    // CONTENT PROVIDERS
8042    // =========================================================
8043
8044    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8045        List<ProviderInfo> providers = null;
8046        try {
8047            providers = AppGlobals.getPackageManager().
8048                queryContentProviders(app.processName, app.uid,
8049                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8050        } catch (RemoteException ex) {
8051        }
8052        if (DEBUG_MU)
8053            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8054        int userId = app.userId;
8055        if (providers != null) {
8056            int N = providers.size();
8057            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8058            for (int i=0; i<N; i++) {
8059                ProviderInfo cpi =
8060                    (ProviderInfo)providers.get(i);
8061                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8062                        cpi.name, cpi.flags);
8063                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8064                    // This is a singleton provider, but a user besides the
8065                    // default user is asking to initialize a process it runs
8066                    // in...  well, no, it doesn't actually run in this process,
8067                    // it runs in the process of the default user.  Get rid of it.
8068                    providers.remove(i);
8069                    N--;
8070                    i--;
8071                    continue;
8072                }
8073
8074                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8075                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8076                if (cpr == null) {
8077                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8078                    mProviderMap.putProviderByClass(comp, cpr);
8079                }
8080                if (DEBUG_MU)
8081                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8082                app.pubProviders.put(cpi.name, cpr);
8083                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8084                    // Don't add this if it is a platform component that is marked
8085                    // to run in multiple processes, because this is actually
8086                    // part of the framework so doesn't make sense to track as a
8087                    // separate apk in the process.
8088                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8089                            mProcessStats);
8090                }
8091                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8092            }
8093        }
8094        return providers;
8095    }
8096
8097    /**
8098     * Check if {@link ProcessRecord} has a possible chance at accessing the
8099     * given {@link ProviderInfo}. Final permission checking is always done
8100     * in {@link ContentProvider}.
8101     */
8102    private final String checkContentProviderPermissionLocked(
8103            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8104        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8105        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8106        boolean checkedGrants = false;
8107        if (checkUser) {
8108            // Looking for cross-user grants before enforcing the typical cross-users permissions
8109            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8110            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8111                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8112                    return null;
8113                }
8114                checkedGrants = true;
8115            }
8116            userId = handleIncomingUser(callingPid, callingUid, userId,
8117                    false, ALLOW_NON_FULL,
8118                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8119            if (userId != tmpTargetUserId) {
8120                // When we actually went to determine the final targer user ID, this ended
8121                // up different than our initial check for the authority.  This is because
8122                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8123                // SELF.  So we need to re-check the grants again.
8124                checkedGrants = false;
8125            }
8126        }
8127        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8128                cpi.applicationInfo.uid, cpi.exported)
8129                == PackageManager.PERMISSION_GRANTED) {
8130            return null;
8131        }
8132        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8133                cpi.applicationInfo.uid, cpi.exported)
8134                == PackageManager.PERMISSION_GRANTED) {
8135            return null;
8136        }
8137
8138        PathPermission[] pps = cpi.pathPermissions;
8139        if (pps != null) {
8140            int i = pps.length;
8141            while (i > 0) {
8142                i--;
8143                PathPermission pp = pps[i];
8144                String pprperm = pp.getReadPermission();
8145                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8146                        cpi.applicationInfo.uid, cpi.exported)
8147                        == PackageManager.PERMISSION_GRANTED) {
8148                    return null;
8149                }
8150                String ppwperm = pp.getWritePermission();
8151                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8152                        cpi.applicationInfo.uid, cpi.exported)
8153                        == PackageManager.PERMISSION_GRANTED) {
8154                    return null;
8155                }
8156            }
8157        }
8158        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8159            return null;
8160        }
8161
8162        String msg;
8163        if (!cpi.exported) {
8164            msg = "Permission Denial: opening provider " + cpi.name
8165                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8166                    + ", uid=" + callingUid + ") that is not exported from uid "
8167                    + cpi.applicationInfo.uid;
8168        } else {
8169            msg = "Permission Denial: opening provider " + cpi.name
8170                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8171                    + ", uid=" + callingUid + ") requires "
8172                    + cpi.readPermission + " or " + cpi.writePermission;
8173        }
8174        Slog.w(TAG, msg);
8175        return msg;
8176    }
8177
8178    /**
8179     * Returns if the ContentProvider has granted a uri to callingUid
8180     */
8181    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8182        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8183        if (perms != null) {
8184            for (int i=perms.size()-1; i>=0; i--) {
8185                GrantUri grantUri = perms.keyAt(i);
8186                if (grantUri.sourceUserId == userId || !checkUser) {
8187                    if (matchesProvider(grantUri.uri, cpi)) {
8188                        return true;
8189                    }
8190                }
8191            }
8192        }
8193        return false;
8194    }
8195
8196    /**
8197     * Returns true if the uri authority is one of the authorities specified in the provider.
8198     */
8199    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8200        String uriAuth = uri.getAuthority();
8201        String cpiAuth = cpi.authority;
8202        if (cpiAuth.indexOf(';') == -1) {
8203            return cpiAuth.equals(uriAuth);
8204        }
8205        String[] cpiAuths = cpiAuth.split(";");
8206        int length = cpiAuths.length;
8207        for (int i = 0; i < length; i++) {
8208            if (cpiAuths[i].equals(uriAuth)) return true;
8209        }
8210        return false;
8211    }
8212
8213    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8214            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8215        if (r != null) {
8216            for (int i=0; i<r.conProviders.size(); i++) {
8217                ContentProviderConnection conn = r.conProviders.get(i);
8218                if (conn.provider == cpr) {
8219                    if (DEBUG_PROVIDER) Slog.v(TAG,
8220                            "Adding provider requested by "
8221                            + r.processName + " from process "
8222                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8223                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8224                    if (stable) {
8225                        conn.stableCount++;
8226                        conn.numStableIncs++;
8227                    } else {
8228                        conn.unstableCount++;
8229                        conn.numUnstableIncs++;
8230                    }
8231                    return conn;
8232                }
8233            }
8234            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8235            if (stable) {
8236                conn.stableCount = 1;
8237                conn.numStableIncs = 1;
8238            } else {
8239                conn.unstableCount = 1;
8240                conn.numUnstableIncs = 1;
8241            }
8242            cpr.connections.add(conn);
8243            r.conProviders.add(conn);
8244            return conn;
8245        }
8246        cpr.addExternalProcessHandleLocked(externalProcessToken);
8247        return null;
8248    }
8249
8250    boolean decProviderCountLocked(ContentProviderConnection conn,
8251            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8252        if (conn != null) {
8253            cpr = conn.provider;
8254            if (DEBUG_PROVIDER) Slog.v(TAG,
8255                    "Removing provider requested by "
8256                    + conn.client.processName + " from process "
8257                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8258                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8259            if (stable) {
8260                conn.stableCount--;
8261            } else {
8262                conn.unstableCount--;
8263            }
8264            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8265                cpr.connections.remove(conn);
8266                conn.client.conProviders.remove(conn);
8267                return true;
8268            }
8269            return false;
8270        }
8271        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8272        return false;
8273    }
8274
8275    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8276            String name, IBinder token, boolean stable, int userId) {
8277        ContentProviderRecord cpr;
8278        ContentProviderConnection conn = null;
8279        ProviderInfo cpi = null;
8280
8281        synchronized(this) {
8282            ProcessRecord r = null;
8283            if (caller != null) {
8284                r = getRecordForAppLocked(caller);
8285                if (r == null) {
8286                    throw new SecurityException(
8287                            "Unable to find app for caller " + caller
8288                          + " (pid=" + Binder.getCallingPid()
8289                          + ") when getting content provider " + name);
8290                }
8291            }
8292
8293            boolean checkCrossUser = true;
8294
8295            // First check if this content provider has been published...
8296            cpr = mProviderMap.getProviderByName(name, userId);
8297            // If that didn't work, check if it exists for user 0 and then
8298            // verify that it's a singleton provider before using it.
8299            if (cpr == null && userId != UserHandle.USER_OWNER) {
8300                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8301                if (cpr != null) {
8302                    cpi = cpr.info;
8303                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8304                            cpi.name, cpi.flags)
8305                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8306                        userId = UserHandle.USER_OWNER;
8307                        checkCrossUser = false;
8308                    } else {
8309                        cpr = null;
8310                        cpi = null;
8311                    }
8312                }
8313            }
8314
8315            boolean providerRunning = cpr != null;
8316            if (providerRunning) {
8317                cpi = cpr.info;
8318                String msg;
8319                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8320                        != null) {
8321                    throw new SecurityException(msg);
8322                }
8323
8324                if (r != null && cpr.canRunHere(r)) {
8325                    // This provider has been published or is in the process
8326                    // of being published...  but it is also allowed to run
8327                    // in the caller's process, so don't make a connection
8328                    // and just let the caller instantiate its own instance.
8329                    ContentProviderHolder holder = cpr.newHolder(null);
8330                    // don't give caller the provider object, it needs
8331                    // to make its own.
8332                    holder.provider = null;
8333                    return holder;
8334                }
8335
8336                final long origId = Binder.clearCallingIdentity();
8337
8338                // In this case the provider instance already exists, so we can
8339                // return it right away.
8340                conn = incProviderCountLocked(r, cpr, token, stable);
8341                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8342                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8343                        // If this is a perceptible app accessing the provider,
8344                        // make sure to count it as being accessed and thus
8345                        // back up on the LRU list.  This is good because
8346                        // content providers are often expensive to start.
8347                        updateLruProcessLocked(cpr.proc, false, null);
8348                    }
8349                }
8350
8351                if (cpr.proc != null) {
8352                    if (false) {
8353                        if (cpr.name.flattenToShortString().equals(
8354                                "com.android.providers.calendar/.CalendarProvider2")) {
8355                            Slog.v(TAG, "****************** KILLING "
8356                                + cpr.name.flattenToShortString());
8357                            Process.killProcess(cpr.proc.pid);
8358                        }
8359                    }
8360                    boolean success = updateOomAdjLocked(cpr.proc);
8361                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8362                    // NOTE: there is still a race here where a signal could be
8363                    // pending on the process even though we managed to update its
8364                    // adj level.  Not sure what to do about this, but at least
8365                    // the race is now smaller.
8366                    if (!success) {
8367                        // Uh oh...  it looks like the provider's process
8368                        // has been killed on us.  We need to wait for a new
8369                        // process to be started, and make sure its death
8370                        // doesn't kill our process.
8371                        Slog.i(TAG,
8372                                "Existing provider " + cpr.name.flattenToShortString()
8373                                + " is crashing; detaching " + r);
8374                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8375                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8376                        if (!lastRef) {
8377                            // This wasn't the last ref our process had on
8378                            // the provider...  we have now been killed, bail.
8379                            return null;
8380                        }
8381                        providerRunning = false;
8382                        conn = null;
8383                    }
8384                }
8385
8386                Binder.restoreCallingIdentity(origId);
8387            }
8388
8389            boolean singleton;
8390            if (!providerRunning) {
8391                try {
8392                    cpi = AppGlobals.getPackageManager().
8393                        resolveContentProvider(name,
8394                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8395                } catch (RemoteException ex) {
8396                }
8397                if (cpi == null) {
8398                    return null;
8399                }
8400                // If the provider is a singleton AND
8401                // (it's a call within the same user || the provider is a
8402                // privileged app)
8403                // Then allow connecting to the singleton provider
8404                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8405                        cpi.name, cpi.flags)
8406                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8407                if (singleton) {
8408                    userId = UserHandle.USER_OWNER;
8409                }
8410                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8411
8412                String msg;
8413                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8414                        != null) {
8415                    throw new SecurityException(msg);
8416                }
8417
8418                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8419                        && !cpi.processName.equals("system")) {
8420                    // If this content provider does not run in the system
8421                    // process, and the system is not yet ready to run other
8422                    // processes, then fail fast instead of hanging.
8423                    throw new IllegalArgumentException(
8424                            "Attempt to launch content provider before system ready");
8425                }
8426
8427                // Make sure that the user who owns this provider is started.  If not,
8428                // we don't want to allow it to run.
8429                if (mStartedUsers.get(userId) == null) {
8430                    Slog.w(TAG, "Unable to launch app "
8431                            + cpi.applicationInfo.packageName + "/"
8432                            + cpi.applicationInfo.uid + " for provider "
8433                            + name + ": user " + userId + " is stopped");
8434                    return null;
8435                }
8436
8437                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8438                cpr = mProviderMap.getProviderByClass(comp, userId);
8439                final boolean firstClass = cpr == null;
8440                if (firstClass) {
8441                    try {
8442                        ApplicationInfo ai =
8443                            AppGlobals.getPackageManager().
8444                                getApplicationInfo(
8445                                        cpi.applicationInfo.packageName,
8446                                        STOCK_PM_FLAGS, userId);
8447                        if (ai == null) {
8448                            Slog.w(TAG, "No package info for content provider "
8449                                    + cpi.name);
8450                            return null;
8451                        }
8452                        ai = getAppInfoForUser(ai, userId);
8453                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8454                    } catch (RemoteException ex) {
8455                        // pm is in same process, this will never happen.
8456                    }
8457                }
8458
8459                if (r != null && cpr.canRunHere(r)) {
8460                    // If this is a multiprocess provider, then just return its
8461                    // info and allow the caller to instantiate it.  Only do
8462                    // this if the provider is the same user as the caller's
8463                    // process, or can run as root (so can be in any process).
8464                    return cpr.newHolder(null);
8465                }
8466
8467                if (DEBUG_PROVIDER) {
8468                    RuntimeException e = new RuntimeException("here");
8469                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8470                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8471                }
8472
8473                // This is single process, and our app is now connecting to it.
8474                // See if we are already in the process of launching this
8475                // provider.
8476                final int N = mLaunchingProviders.size();
8477                int i;
8478                for (i=0; i<N; i++) {
8479                    if (mLaunchingProviders.get(i) == cpr) {
8480                        break;
8481                    }
8482                }
8483
8484                // If the provider is not already being launched, then get it
8485                // started.
8486                if (i >= N) {
8487                    final long origId = Binder.clearCallingIdentity();
8488
8489                    try {
8490                        // Content provider is now in use, its package can't be stopped.
8491                        try {
8492                            AppGlobals.getPackageManager().setPackageStoppedState(
8493                                    cpr.appInfo.packageName, false, userId);
8494                        } catch (RemoteException e) {
8495                        } catch (IllegalArgumentException e) {
8496                            Slog.w(TAG, "Failed trying to unstop package "
8497                                    + cpr.appInfo.packageName + ": " + e);
8498                        }
8499
8500                        // Use existing process if already started
8501                        ProcessRecord proc = getProcessRecordLocked(
8502                                cpi.processName, cpr.appInfo.uid, false);
8503                        if (proc != null && proc.thread != null) {
8504                            if (DEBUG_PROVIDER) {
8505                                Slog.d(TAG, "Installing in existing process " + proc);
8506                            }
8507                            proc.pubProviders.put(cpi.name, cpr);
8508                            try {
8509                                proc.thread.scheduleInstallProvider(cpi);
8510                            } catch (RemoteException e) {
8511                            }
8512                        } else {
8513                            proc = startProcessLocked(cpi.processName,
8514                                    cpr.appInfo, false, 0, "content provider",
8515                                    new ComponentName(cpi.applicationInfo.packageName,
8516                                            cpi.name), false, false, false);
8517                            if (proc == null) {
8518                                Slog.w(TAG, "Unable to launch app "
8519                                        + cpi.applicationInfo.packageName + "/"
8520                                        + cpi.applicationInfo.uid + " for provider "
8521                                        + name + ": process is bad");
8522                                return null;
8523                            }
8524                        }
8525                        cpr.launchingApp = proc;
8526                        mLaunchingProviders.add(cpr);
8527                    } finally {
8528                        Binder.restoreCallingIdentity(origId);
8529                    }
8530                }
8531
8532                // Make sure the provider is published (the same provider class
8533                // may be published under multiple names).
8534                if (firstClass) {
8535                    mProviderMap.putProviderByClass(comp, cpr);
8536                }
8537
8538                mProviderMap.putProviderByName(name, cpr);
8539                conn = incProviderCountLocked(r, cpr, token, stable);
8540                if (conn != null) {
8541                    conn.waiting = true;
8542                }
8543            }
8544        }
8545
8546        // Wait for the provider to be published...
8547        synchronized (cpr) {
8548            while (cpr.provider == null) {
8549                if (cpr.launchingApp == null) {
8550                    Slog.w(TAG, "Unable to launch app "
8551                            + cpi.applicationInfo.packageName + "/"
8552                            + cpi.applicationInfo.uid + " for provider "
8553                            + name + ": launching app became null");
8554                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8555                            UserHandle.getUserId(cpi.applicationInfo.uid),
8556                            cpi.applicationInfo.packageName,
8557                            cpi.applicationInfo.uid, name);
8558                    return null;
8559                }
8560                try {
8561                    if (DEBUG_MU) {
8562                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8563                                + cpr.launchingApp);
8564                    }
8565                    if (conn != null) {
8566                        conn.waiting = true;
8567                    }
8568                    cpr.wait();
8569                } catch (InterruptedException ex) {
8570                } finally {
8571                    if (conn != null) {
8572                        conn.waiting = false;
8573                    }
8574                }
8575            }
8576        }
8577        return cpr != null ? cpr.newHolder(conn) : null;
8578    }
8579
8580    @Override
8581    public final ContentProviderHolder getContentProvider(
8582            IApplicationThread caller, String name, int userId, boolean stable) {
8583        enforceNotIsolatedCaller("getContentProvider");
8584        if (caller == null) {
8585            String msg = "null IApplicationThread when getting content provider "
8586                    + name;
8587            Slog.w(TAG, msg);
8588            throw new SecurityException(msg);
8589        }
8590        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8591        // with cross-user grant.
8592        return getContentProviderImpl(caller, name, null, stable, userId);
8593    }
8594
8595    public ContentProviderHolder getContentProviderExternal(
8596            String name, int userId, IBinder token) {
8597        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8598            "Do not have permission in call getContentProviderExternal()");
8599        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8600                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8601        return getContentProviderExternalUnchecked(name, token, userId);
8602    }
8603
8604    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8605            IBinder token, int userId) {
8606        return getContentProviderImpl(null, name, token, true, userId);
8607    }
8608
8609    /**
8610     * Drop a content provider from a ProcessRecord's bookkeeping
8611     */
8612    public void removeContentProvider(IBinder connection, boolean stable) {
8613        enforceNotIsolatedCaller("removeContentProvider");
8614        long ident = Binder.clearCallingIdentity();
8615        try {
8616            synchronized (this) {
8617                ContentProviderConnection conn;
8618                try {
8619                    conn = (ContentProviderConnection)connection;
8620                } catch (ClassCastException e) {
8621                    String msg ="removeContentProvider: " + connection
8622                            + " not a ContentProviderConnection";
8623                    Slog.w(TAG, msg);
8624                    throw new IllegalArgumentException(msg);
8625                }
8626                if (conn == null) {
8627                    throw new NullPointerException("connection is null");
8628                }
8629                if (decProviderCountLocked(conn, null, null, stable)) {
8630                    updateOomAdjLocked();
8631                }
8632            }
8633        } finally {
8634            Binder.restoreCallingIdentity(ident);
8635        }
8636    }
8637
8638    public void removeContentProviderExternal(String name, IBinder token) {
8639        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8640            "Do not have permission in call removeContentProviderExternal()");
8641        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8642    }
8643
8644    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8645        synchronized (this) {
8646            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8647            if(cpr == null) {
8648                //remove from mProvidersByClass
8649                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8650                return;
8651            }
8652
8653            //update content provider record entry info
8654            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8655            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8656            if (localCpr.hasExternalProcessHandles()) {
8657                if (localCpr.removeExternalProcessHandleLocked(token)) {
8658                    updateOomAdjLocked();
8659                } else {
8660                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8661                            + " with no external reference for token: "
8662                            + token + ".");
8663                }
8664            } else {
8665                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8666                        + " with no external references.");
8667            }
8668        }
8669    }
8670
8671    public final void publishContentProviders(IApplicationThread caller,
8672            List<ContentProviderHolder> providers) {
8673        if (providers == null) {
8674            return;
8675        }
8676
8677        enforceNotIsolatedCaller("publishContentProviders");
8678        synchronized (this) {
8679            final ProcessRecord r = getRecordForAppLocked(caller);
8680            if (DEBUG_MU)
8681                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8682            if (r == null) {
8683                throw new SecurityException(
8684                        "Unable to find app for caller " + caller
8685                      + " (pid=" + Binder.getCallingPid()
8686                      + ") when publishing content providers");
8687            }
8688
8689            final long origId = Binder.clearCallingIdentity();
8690
8691            final int N = providers.size();
8692            for (int i=0; i<N; i++) {
8693                ContentProviderHolder src = providers.get(i);
8694                if (src == null || src.info == null || src.provider == null) {
8695                    continue;
8696                }
8697                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8698                if (DEBUG_MU)
8699                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8700                if (dst != null) {
8701                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8702                    mProviderMap.putProviderByClass(comp, dst);
8703                    String names[] = dst.info.authority.split(";");
8704                    for (int j = 0; j < names.length; j++) {
8705                        mProviderMap.putProviderByName(names[j], dst);
8706                    }
8707
8708                    int NL = mLaunchingProviders.size();
8709                    int j;
8710                    for (j=0; j<NL; j++) {
8711                        if (mLaunchingProviders.get(j) == dst) {
8712                            mLaunchingProviders.remove(j);
8713                            j--;
8714                            NL--;
8715                        }
8716                    }
8717                    synchronized (dst) {
8718                        dst.provider = src.provider;
8719                        dst.proc = r;
8720                        dst.notifyAll();
8721                    }
8722                    updateOomAdjLocked(r);
8723                }
8724            }
8725
8726            Binder.restoreCallingIdentity(origId);
8727        }
8728    }
8729
8730    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8731        ContentProviderConnection conn;
8732        try {
8733            conn = (ContentProviderConnection)connection;
8734        } catch (ClassCastException e) {
8735            String msg ="refContentProvider: " + connection
8736                    + " not a ContentProviderConnection";
8737            Slog.w(TAG, msg);
8738            throw new IllegalArgumentException(msg);
8739        }
8740        if (conn == null) {
8741            throw new NullPointerException("connection is null");
8742        }
8743
8744        synchronized (this) {
8745            if (stable > 0) {
8746                conn.numStableIncs += stable;
8747            }
8748            stable = conn.stableCount + stable;
8749            if (stable < 0) {
8750                throw new IllegalStateException("stableCount < 0: " + stable);
8751            }
8752
8753            if (unstable > 0) {
8754                conn.numUnstableIncs += unstable;
8755            }
8756            unstable = conn.unstableCount + unstable;
8757            if (unstable < 0) {
8758                throw new IllegalStateException("unstableCount < 0: " + unstable);
8759            }
8760
8761            if ((stable+unstable) <= 0) {
8762                throw new IllegalStateException("ref counts can't go to zero here: stable="
8763                        + stable + " unstable=" + unstable);
8764            }
8765            conn.stableCount = stable;
8766            conn.unstableCount = unstable;
8767            return !conn.dead;
8768        }
8769    }
8770
8771    public void unstableProviderDied(IBinder connection) {
8772        ContentProviderConnection conn;
8773        try {
8774            conn = (ContentProviderConnection)connection;
8775        } catch (ClassCastException e) {
8776            String msg ="refContentProvider: " + connection
8777                    + " not a ContentProviderConnection";
8778            Slog.w(TAG, msg);
8779            throw new IllegalArgumentException(msg);
8780        }
8781        if (conn == null) {
8782            throw new NullPointerException("connection is null");
8783        }
8784
8785        // Safely retrieve the content provider associated with the connection.
8786        IContentProvider provider;
8787        synchronized (this) {
8788            provider = conn.provider.provider;
8789        }
8790
8791        if (provider == null) {
8792            // Um, yeah, we're way ahead of you.
8793            return;
8794        }
8795
8796        // Make sure the caller is being honest with us.
8797        if (provider.asBinder().pingBinder()) {
8798            // Er, no, still looks good to us.
8799            synchronized (this) {
8800                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8801                        + " says " + conn + " died, but we don't agree");
8802                return;
8803            }
8804        }
8805
8806        // Well look at that!  It's dead!
8807        synchronized (this) {
8808            if (conn.provider.provider != provider) {
8809                // But something changed...  good enough.
8810                return;
8811            }
8812
8813            ProcessRecord proc = conn.provider.proc;
8814            if (proc == null || proc.thread == null) {
8815                // Seems like the process is already cleaned up.
8816                return;
8817            }
8818
8819            // As far as we're concerned, this is just like receiving a
8820            // death notification...  just a bit prematurely.
8821            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8822                    + ") early provider death");
8823            final long ident = Binder.clearCallingIdentity();
8824            try {
8825                appDiedLocked(proc, proc.pid, proc.thread);
8826            } finally {
8827                Binder.restoreCallingIdentity(ident);
8828            }
8829        }
8830    }
8831
8832    @Override
8833    public void appNotRespondingViaProvider(IBinder connection) {
8834        enforceCallingPermission(
8835                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8836
8837        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8838        if (conn == null) {
8839            Slog.w(TAG, "ContentProviderConnection is null");
8840            return;
8841        }
8842
8843        final ProcessRecord host = conn.provider.proc;
8844        if (host == null) {
8845            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8846            return;
8847        }
8848
8849        final long token = Binder.clearCallingIdentity();
8850        try {
8851            appNotResponding(host, null, null, false, "ContentProvider not responding");
8852        } finally {
8853            Binder.restoreCallingIdentity(token);
8854        }
8855    }
8856
8857    public final void installSystemProviders() {
8858        List<ProviderInfo> providers;
8859        synchronized (this) {
8860            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8861            providers = generateApplicationProvidersLocked(app);
8862            if (providers != null) {
8863                for (int i=providers.size()-1; i>=0; i--) {
8864                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8865                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8866                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8867                                + ": not system .apk");
8868                        providers.remove(i);
8869                    }
8870                }
8871            }
8872        }
8873        if (providers != null) {
8874            mSystemThread.installSystemProviders(providers);
8875        }
8876
8877        mCoreSettingsObserver = new CoreSettingsObserver(this);
8878
8879        //mUsageStatsService.monitorPackages();
8880    }
8881
8882    /**
8883     * Allows app to retrieve the MIME type of a URI without having permission
8884     * to access its content provider.
8885     *
8886     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8887     *
8888     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8889     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8890     */
8891    public String getProviderMimeType(Uri uri, int userId) {
8892        enforceNotIsolatedCaller("getProviderMimeType");
8893        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8894                userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null);
8895        final String name = uri.getAuthority();
8896        final long ident = Binder.clearCallingIdentity();
8897        ContentProviderHolder holder = null;
8898
8899        try {
8900            holder = getContentProviderExternalUnchecked(name, null, userId);
8901            if (holder != null) {
8902                return holder.provider.getType(uri);
8903            }
8904        } catch (RemoteException e) {
8905            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8906            return null;
8907        } finally {
8908            if (holder != null) {
8909                removeContentProviderExternalUnchecked(name, null, userId);
8910            }
8911            Binder.restoreCallingIdentity(ident);
8912        }
8913
8914        return null;
8915    }
8916
8917    // =========================================================
8918    // GLOBAL MANAGEMENT
8919    // =========================================================
8920
8921    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8922            boolean isolated) {
8923        String proc = customProcess != null ? customProcess : info.processName;
8924        BatteryStatsImpl.Uid.Proc ps = null;
8925        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8926        int uid = info.uid;
8927        if (isolated) {
8928            int userId = UserHandle.getUserId(uid);
8929            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8930            while (true) {
8931                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8932                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8933                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8934                }
8935                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8936                mNextIsolatedProcessUid++;
8937                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8938                    // No process for this uid, use it.
8939                    break;
8940                }
8941                stepsLeft--;
8942                if (stepsLeft <= 0) {
8943                    return null;
8944                }
8945            }
8946        }
8947        return new ProcessRecord(stats, info, proc, uid);
8948    }
8949
8950    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8951            String abiOverride) {
8952        ProcessRecord app;
8953        if (!isolated) {
8954            app = getProcessRecordLocked(info.processName, info.uid, true);
8955        } else {
8956            app = null;
8957        }
8958
8959        if (app == null) {
8960            app = newProcessRecordLocked(info, null, isolated);
8961            mProcessNames.put(info.processName, app.uid, app);
8962            if (isolated) {
8963                mIsolatedProcesses.put(app.uid, app);
8964            }
8965            updateLruProcessLocked(app, false, null);
8966            updateOomAdjLocked();
8967        }
8968
8969        // This package really, really can not be stopped.
8970        try {
8971            AppGlobals.getPackageManager().setPackageStoppedState(
8972                    info.packageName, false, UserHandle.getUserId(app.uid));
8973        } catch (RemoteException e) {
8974        } catch (IllegalArgumentException e) {
8975            Slog.w(TAG, "Failed trying to unstop package "
8976                    + info.packageName + ": " + e);
8977        }
8978
8979        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8980                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8981            app.persistent = true;
8982            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8983        }
8984        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8985            mPersistentStartingProcesses.add(app);
8986            startProcessLocked(app, "added application", app.processName,
8987                    abiOverride);
8988        }
8989
8990        return app;
8991    }
8992
8993    public void unhandledBack() {
8994        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8995                "unhandledBack()");
8996
8997        synchronized(this) {
8998            final long origId = Binder.clearCallingIdentity();
8999            try {
9000                getFocusedStack().unhandledBackLocked();
9001            } finally {
9002                Binder.restoreCallingIdentity(origId);
9003            }
9004        }
9005    }
9006
9007    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9008        enforceNotIsolatedCaller("openContentUri");
9009        final int userId = UserHandle.getCallingUserId();
9010        String name = uri.getAuthority();
9011        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9012        ParcelFileDescriptor pfd = null;
9013        if (cph != null) {
9014            // We record the binder invoker's uid in thread-local storage before
9015            // going to the content provider to open the file.  Later, in the code
9016            // that handles all permissions checks, we look for this uid and use
9017            // that rather than the Activity Manager's own uid.  The effect is that
9018            // we do the check against the caller's permissions even though it looks
9019            // to the content provider like the Activity Manager itself is making
9020            // the request.
9021            sCallerIdentity.set(new Identity(
9022                    Binder.getCallingPid(), Binder.getCallingUid()));
9023            try {
9024                pfd = cph.provider.openFile(null, uri, "r", null);
9025            } catch (FileNotFoundException e) {
9026                // do nothing; pfd will be returned null
9027            } finally {
9028                // Ensure that whatever happens, we clean up the identity state
9029                sCallerIdentity.remove();
9030            }
9031
9032            // We've got the fd now, so we're done with the provider.
9033            removeContentProviderExternalUnchecked(name, null, userId);
9034        } else {
9035            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9036        }
9037        return pfd;
9038    }
9039
9040    // Actually is sleeping or shutting down or whatever else in the future
9041    // is an inactive state.
9042    public boolean isSleepingOrShuttingDown() {
9043        return mSleeping || mShuttingDown;
9044    }
9045
9046    public boolean isSleeping() {
9047        return mSleeping;
9048    }
9049
9050    void goingToSleep() {
9051        synchronized(this) {
9052            mWentToSleep = true;
9053            updateEventDispatchingLocked();
9054            goToSleepIfNeededLocked();
9055        }
9056    }
9057
9058    void finishRunningVoiceLocked() {
9059        if (mRunningVoice) {
9060            mRunningVoice = false;
9061            goToSleepIfNeededLocked();
9062        }
9063    }
9064
9065    void goToSleepIfNeededLocked() {
9066        if (mWentToSleep && !mRunningVoice) {
9067            if (!mSleeping) {
9068                mSleeping = true;
9069                mStackSupervisor.goingToSleepLocked();
9070
9071                // Initialize the wake times of all processes.
9072                checkExcessivePowerUsageLocked(false);
9073                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9074                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9075                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9076            }
9077        }
9078    }
9079
9080    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9081        mTaskPersister.notify(task, flush);
9082    }
9083
9084    @Override
9085    public boolean shutdown(int timeout) {
9086        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9087                != PackageManager.PERMISSION_GRANTED) {
9088            throw new SecurityException("Requires permission "
9089                    + android.Manifest.permission.SHUTDOWN);
9090        }
9091
9092        boolean timedout = false;
9093
9094        synchronized(this) {
9095            mShuttingDown = true;
9096            updateEventDispatchingLocked();
9097            timedout = mStackSupervisor.shutdownLocked(timeout);
9098        }
9099
9100        mAppOpsService.shutdown();
9101        if (mUsageStatsService != null) {
9102            mUsageStatsService.prepareShutdown();
9103        }
9104        mBatteryStatsService.shutdown();
9105        synchronized (this) {
9106            mProcessStats.shutdownLocked();
9107        }
9108        notifyTaskPersisterLocked(null, true);
9109
9110        return timedout;
9111    }
9112
9113    public final void activitySlept(IBinder token) {
9114        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9115
9116        final long origId = Binder.clearCallingIdentity();
9117
9118        synchronized (this) {
9119            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9120            if (r != null) {
9121                mStackSupervisor.activitySleptLocked(r);
9122            }
9123        }
9124
9125        Binder.restoreCallingIdentity(origId);
9126    }
9127
9128    void logLockScreen(String msg) {
9129        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9130                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9131                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9132                mStackSupervisor.mDismissKeyguardOnNextActivity);
9133    }
9134
9135    private void comeOutOfSleepIfNeededLocked() {
9136        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9137            if (mSleeping) {
9138                mSleeping = false;
9139                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9140            }
9141        }
9142    }
9143
9144    void wakingUp() {
9145        synchronized(this) {
9146            mWentToSleep = false;
9147            updateEventDispatchingLocked();
9148            comeOutOfSleepIfNeededLocked();
9149        }
9150    }
9151
9152    void startRunningVoiceLocked() {
9153        if (!mRunningVoice) {
9154            mRunningVoice = true;
9155            comeOutOfSleepIfNeededLocked();
9156        }
9157    }
9158
9159    private void updateEventDispatchingLocked() {
9160        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9161    }
9162
9163    public void setLockScreenShown(boolean shown) {
9164        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9165                != PackageManager.PERMISSION_GRANTED) {
9166            throw new SecurityException("Requires permission "
9167                    + android.Manifest.permission.DEVICE_POWER);
9168        }
9169
9170        synchronized(this) {
9171            long ident = Binder.clearCallingIdentity();
9172            try {
9173                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9174                mLockScreenShown = shown;
9175                comeOutOfSleepIfNeededLocked();
9176            } finally {
9177                Binder.restoreCallingIdentity(ident);
9178            }
9179        }
9180    }
9181
9182    @Override
9183    public void stopAppSwitches() {
9184        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9185                != PackageManager.PERMISSION_GRANTED) {
9186            throw new SecurityException("Requires permission "
9187                    + android.Manifest.permission.STOP_APP_SWITCHES);
9188        }
9189
9190        synchronized(this) {
9191            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9192                    + APP_SWITCH_DELAY_TIME;
9193            mDidAppSwitch = false;
9194            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9195            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9196            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9197        }
9198    }
9199
9200    public void resumeAppSwitches() {
9201        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9202                != PackageManager.PERMISSION_GRANTED) {
9203            throw new SecurityException("Requires permission "
9204                    + android.Manifest.permission.STOP_APP_SWITCHES);
9205        }
9206
9207        synchronized(this) {
9208            // Note that we don't execute any pending app switches... we will
9209            // let those wait until either the timeout, or the next start
9210            // activity request.
9211            mAppSwitchesAllowedTime = 0;
9212        }
9213    }
9214
9215    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9216            String name) {
9217        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9218            return true;
9219        }
9220
9221        final int perm = checkComponentPermission(
9222                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9223                callingUid, -1, true);
9224        if (perm == PackageManager.PERMISSION_GRANTED) {
9225            return true;
9226        }
9227
9228        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9229        return false;
9230    }
9231
9232    public void setDebugApp(String packageName, boolean waitForDebugger,
9233            boolean persistent) {
9234        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9235                "setDebugApp()");
9236
9237        long ident = Binder.clearCallingIdentity();
9238        try {
9239            // Note that this is not really thread safe if there are multiple
9240            // callers into it at the same time, but that's not a situation we
9241            // care about.
9242            if (persistent) {
9243                final ContentResolver resolver = mContext.getContentResolver();
9244                Settings.Global.putString(
9245                    resolver, Settings.Global.DEBUG_APP,
9246                    packageName);
9247                Settings.Global.putInt(
9248                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9249                    waitForDebugger ? 1 : 0);
9250            }
9251
9252            synchronized (this) {
9253                if (!persistent) {
9254                    mOrigDebugApp = mDebugApp;
9255                    mOrigWaitForDebugger = mWaitForDebugger;
9256                }
9257                mDebugApp = packageName;
9258                mWaitForDebugger = waitForDebugger;
9259                mDebugTransient = !persistent;
9260                if (packageName != null) {
9261                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9262                            false, UserHandle.USER_ALL, "set debug app");
9263                }
9264            }
9265        } finally {
9266            Binder.restoreCallingIdentity(ident);
9267        }
9268    }
9269
9270    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9271        synchronized (this) {
9272            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9273            if (!isDebuggable) {
9274                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9275                    throw new SecurityException("Process not debuggable: " + app.packageName);
9276                }
9277            }
9278
9279            mOpenGlTraceApp = processName;
9280        }
9281    }
9282
9283    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9284            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9285        synchronized (this) {
9286            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9287            if (!isDebuggable) {
9288                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9289                    throw new SecurityException("Process not debuggable: " + app.packageName);
9290                }
9291            }
9292            mProfileApp = processName;
9293            mProfileFile = profileFile;
9294            if (mProfileFd != null) {
9295                try {
9296                    mProfileFd.close();
9297                } catch (IOException e) {
9298                }
9299                mProfileFd = null;
9300            }
9301            mProfileFd = profileFd;
9302            mProfileType = 0;
9303            mAutoStopProfiler = autoStopProfiler;
9304        }
9305    }
9306
9307    @Override
9308    public void setAlwaysFinish(boolean enabled) {
9309        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9310                "setAlwaysFinish()");
9311
9312        Settings.Global.putInt(
9313                mContext.getContentResolver(),
9314                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9315
9316        synchronized (this) {
9317            mAlwaysFinishActivities = enabled;
9318        }
9319    }
9320
9321    @Override
9322    public void setActivityController(IActivityController controller) {
9323        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9324                "setActivityController()");
9325        synchronized (this) {
9326            mController = controller;
9327            Watchdog.getInstance().setActivityController(controller);
9328        }
9329    }
9330
9331    @Override
9332    public void setUserIsMonkey(boolean userIsMonkey) {
9333        synchronized (this) {
9334            synchronized (mPidsSelfLocked) {
9335                final int callingPid = Binder.getCallingPid();
9336                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9337                if (precessRecord == null) {
9338                    throw new SecurityException("Unknown process: " + callingPid);
9339                }
9340                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9341                    throw new SecurityException("Only an instrumentation process "
9342                            + "with a UiAutomation can call setUserIsMonkey");
9343                }
9344            }
9345            mUserIsMonkey = userIsMonkey;
9346        }
9347    }
9348
9349    @Override
9350    public boolean isUserAMonkey() {
9351        synchronized (this) {
9352            // If there is a controller also implies the user is a monkey.
9353            return (mUserIsMonkey || mController != null);
9354        }
9355    }
9356
9357    public void requestBugReport() {
9358        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9359        SystemProperties.set("ctl.start", "bugreport");
9360    }
9361
9362    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9363        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9364    }
9365
9366    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9367        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9368            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9369        }
9370        return KEY_DISPATCHING_TIMEOUT;
9371    }
9372
9373    @Override
9374    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9375        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9376                != PackageManager.PERMISSION_GRANTED) {
9377            throw new SecurityException("Requires permission "
9378                    + android.Manifest.permission.FILTER_EVENTS);
9379        }
9380        ProcessRecord proc;
9381        long timeout;
9382        synchronized (this) {
9383            synchronized (mPidsSelfLocked) {
9384                proc = mPidsSelfLocked.get(pid);
9385            }
9386            timeout = getInputDispatchingTimeoutLocked(proc);
9387        }
9388
9389        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9390            return -1;
9391        }
9392
9393        return timeout;
9394    }
9395
9396    /**
9397     * Handle input dispatching timeouts.
9398     * Returns whether input dispatching should be aborted or not.
9399     */
9400    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9401            final ActivityRecord activity, final ActivityRecord parent,
9402            final boolean aboveSystem, String reason) {
9403        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9404                != PackageManager.PERMISSION_GRANTED) {
9405            throw new SecurityException("Requires permission "
9406                    + android.Manifest.permission.FILTER_EVENTS);
9407        }
9408
9409        final String annotation;
9410        if (reason == null) {
9411            annotation = "Input dispatching timed out";
9412        } else {
9413            annotation = "Input dispatching timed out (" + reason + ")";
9414        }
9415
9416        if (proc != null) {
9417            synchronized (this) {
9418                if (proc.debugging) {
9419                    return false;
9420                }
9421
9422                if (mDidDexOpt) {
9423                    // Give more time since we were dexopting.
9424                    mDidDexOpt = false;
9425                    return false;
9426                }
9427
9428                if (proc.instrumentationClass != null) {
9429                    Bundle info = new Bundle();
9430                    info.putString("shortMsg", "keyDispatchingTimedOut");
9431                    info.putString("longMsg", annotation);
9432                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9433                    return true;
9434                }
9435            }
9436            mHandler.post(new Runnable() {
9437                @Override
9438                public void run() {
9439                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9440                }
9441            });
9442        }
9443
9444        return true;
9445    }
9446
9447    public Bundle getAssistContextExtras(int requestType) {
9448        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9449                "getAssistContextExtras()");
9450        PendingAssistExtras pae;
9451        Bundle extras = new Bundle();
9452        synchronized (this) {
9453            ActivityRecord activity = getFocusedStack().mResumedActivity;
9454            if (activity == null) {
9455                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9456                return null;
9457            }
9458            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9459            if (activity.app == null || activity.app.thread == null) {
9460                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9461                return extras;
9462            }
9463            if (activity.app.pid == Binder.getCallingPid()) {
9464                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9465                return extras;
9466            }
9467            pae = new PendingAssistExtras(activity);
9468            try {
9469                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9470                        requestType);
9471                mPendingAssistExtras.add(pae);
9472                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9473            } catch (RemoteException e) {
9474                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9475                return extras;
9476            }
9477        }
9478        synchronized (pae) {
9479            while (!pae.haveResult) {
9480                try {
9481                    pae.wait();
9482                } catch (InterruptedException e) {
9483                }
9484            }
9485            if (pae.result != null) {
9486                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9487            }
9488        }
9489        synchronized (this) {
9490            mPendingAssistExtras.remove(pae);
9491            mHandler.removeCallbacks(pae);
9492        }
9493        return extras;
9494    }
9495
9496    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9497        PendingAssistExtras pae = (PendingAssistExtras)token;
9498        synchronized (pae) {
9499            pae.result = extras;
9500            pae.haveResult = true;
9501            pae.notifyAll();
9502        }
9503    }
9504
9505    public void registerProcessObserver(IProcessObserver observer) {
9506        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9507                "registerProcessObserver()");
9508        synchronized (this) {
9509            mProcessObservers.register(observer);
9510        }
9511    }
9512
9513    @Override
9514    public void unregisterProcessObserver(IProcessObserver observer) {
9515        synchronized (this) {
9516            mProcessObservers.unregister(observer);
9517        }
9518    }
9519
9520    @Override
9521    public boolean convertFromTranslucent(IBinder token) {
9522        final long origId = Binder.clearCallingIdentity();
9523        try {
9524            synchronized (this) {
9525                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9526                if (r == null) {
9527                    return false;
9528                }
9529                if (r.changeWindowTranslucency(true)) {
9530                    mWindowManager.setAppFullscreen(token, true);
9531                    r.task.stack.releaseMediaResources();
9532                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9533                    return true;
9534                }
9535                return false;
9536            }
9537        } finally {
9538            Binder.restoreCallingIdentity(origId);
9539        }
9540    }
9541
9542    @Override
9543    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9544        final long origId = Binder.clearCallingIdentity();
9545        try {
9546            synchronized (this) {
9547                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9548                if (r == null) {
9549                    return false;
9550                }
9551                if (r.changeWindowTranslucency(false)) {
9552                    r.task.stack.convertToTranslucent(r, options);
9553                    mWindowManager.setAppFullscreen(token, false);
9554                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9555                    return true;
9556                } else {
9557                    r.task.stack.mReturningActivityOptions = options;
9558                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9559                    return false;
9560                }
9561            }
9562        } finally {
9563            Binder.restoreCallingIdentity(origId);
9564        }
9565    }
9566
9567    @Override
9568    public boolean setMediaPlaying(IBinder token, boolean playing) {
9569        final long origId = Binder.clearCallingIdentity();
9570        try {
9571            synchronized (this) {
9572                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9573                if (r != null) {
9574                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9575                }
9576            }
9577            return false;
9578        } finally {
9579            Binder.restoreCallingIdentity(origId);
9580        }
9581    }
9582
9583    @Override
9584    public boolean isBackgroundMediaPlaying(IBinder token) {
9585        final long origId = Binder.clearCallingIdentity();
9586        try {
9587            synchronized (this) {
9588                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9589                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9590                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9591                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9592                return playing;
9593            }
9594        } finally {
9595            Binder.restoreCallingIdentity(origId);
9596        }
9597    }
9598
9599    @Override
9600    public ActivityOptions getActivityOptions(IBinder token) {
9601        final long origId = Binder.clearCallingIdentity();
9602        try {
9603            synchronized (this) {
9604                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9605                if (r != null) {
9606                    final ActivityOptions activityOptions = r.pendingOptions;
9607                    r.pendingOptions = null;
9608                    return activityOptions;
9609                }
9610                return null;
9611            }
9612        } finally {
9613            Binder.restoreCallingIdentity(origId);
9614        }
9615    }
9616
9617    @Override
9618    public void setImmersive(IBinder token, boolean immersive) {
9619        synchronized(this) {
9620            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9621            if (r == null) {
9622                throw new IllegalArgumentException();
9623            }
9624            r.immersive = immersive;
9625
9626            // update associated state if we're frontmost
9627            if (r == mFocusedActivity) {
9628                if (DEBUG_IMMERSIVE) {
9629                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9630                }
9631                applyUpdateLockStateLocked(r);
9632            }
9633        }
9634    }
9635
9636    @Override
9637    public boolean isImmersive(IBinder token) {
9638        synchronized (this) {
9639            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9640            if (r == null) {
9641                throw new IllegalArgumentException();
9642            }
9643            return r.immersive;
9644        }
9645    }
9646
9647    public boolean isTopActivityImmersive() {
9648        enforceNotIsolatedCaller("startActivity");
9649        synchronized (this) {
9650            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9651            return (r != null) ? r.immersive : false;
9652        }
9653    }
9654
9655    @Override
9656    public boolean isTopOfTask(IBinder token) {
9657        synchronized (this) {
9658            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9659            if (r == null) {
9660                throw new IllegalArgumentException();
9661            }
9662            return r.task.getTopActivity() == r;
9663        }
9664    }
9665
9666    public final void enterSafeMode() {
9667        synchronized(this) {
9668            // It only makes sense to do this before the system is ready
9669            // and started launching other packages.
9670            if (!mSystemReady) {
9671                try {
9672                    AppGlobals.getPackageManager().enterSafeMode();
9673                } catch (RemoteException e) {
9674                }
9675            }
9676
9677            mSafeMode = true;
9678        }
9679    }
9680
9681    public final void showSafeModeOverlay() {
9682        View v = LayoutInflater.from(mContext).inflate(
9683                com.android.internal.R.layout.safe_mode, null);
9684        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9685        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9686        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9687        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9688        lp.gravity = Gravity.BOTTOM | Gravity.START;
9689        lp.format = v.getBackground().getOpacity();
9690        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9691                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9692        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9693        ((WindowManager)mContext.getSystemService(
9694                Context.WINDOW_SERVICE)).addView(v, lp);
9695    }
9696
9697    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9698        if (!(sender instanceof PendingIntentRecord)) {
9699            return;
9700        }
9701        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9702        synchronized (stats) {
9703            if (mBatteryStatsService.isOnBattery()) {
9704                mBatteryStatsService.enforceCallingPermission();
9705                PendingIntentRecord rec = (PendingIntentRecord)sender;
9706                int MY_UID = Binder.getCallingUid();
9707                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9708                BatteryStatsImpl.Uid.Pkg pkg =
9709                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9710                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9711                pkg.incWakeupsLocked();
9712            }
9713        }
9714    }
9715
9716    public boolean killPids(int[] pids, String pReason, boolean secure) {
9717        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9718            throw new SecurityException("killPids only available to the system");
9719        }
9720        String reason = (pReason == null) ? "Unknown" : pReason;
9721        // XXX Note: don't acquire main activity lock here, because the window
9722        // manager calls in with its locks held.
9723
9724        boolean killed = false;
9725        synchronized (mPidsSelfLocked) {
9726            int[] types = new int[pids.length];
9727            int worstType = 0;
9728            for (int i=0; i<pids.length; i++) {
9729                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9730                if (proc != null) {
9731                    int type = proc.setAdj;
9732                    types[i] = type;
9733                    if (type > worstType) {
9734                        worstType = type;
9735                    }
9736                }
9737            }
9738
9739            // If the worst oom_adj is somewhere in the cached proc LRU range,
9740            // then constrain it so we will kill all cached procs.
9741            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9742                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9743                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9744            }
9745
9746            // If this is not a secure call, don't let it kill processes that
9747            // are important.
9748            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9749                worstType = ProcessList.SERVICE_ADJ;
9750            }
9751
9752            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9753            for (int i=0; i<pids.length; i++) {
9754                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9755                if (proc == null) {
9756                    continue;
9757                }
9758                int adj = proc.setAdj;
9759                if (adj >= worstType && !proc.killedByAm) {
9760                    killUnneededProcessLocked(proc, reason);
9761                    killed = true;
9762                }
9763            }
9764        }
9765        return killed;
9766    }
9767
9768    @Override
9769    public void killUid(int uid, String reason) {
9770        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9771            throw new SecurityException("killUid only available to the system");
9772        }
9773        synchronized (this) {
9774            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9775                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9776                    reason != null ? reason : "kill uid");
9777        }
9778    }
9779
9780    @Override
9781    public boolean killProcessesBelowForeground(String reason) {
9782        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9783            throw new SecurityException("killProcessesBelowForeground() only available to system");
9784        }
9785
9786        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9787    }
9788
9789    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9790        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9791            throw new SecurityException("killProcessesBelowAdj() only available to system");
9792        }
9793
9794        boolean killed = false;
9795        synchronized (mPidsSelfLocked) {
9796            final int size = mPidsSelfLocked.size();
9797            for (int i = 0; i < size; i++) {
9798                final int pid = mPidsSelfLocked.keyAt(i);
9799                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9800                if (proc == null) continue;
9801
9802                final int adj = proc.setAdj;
9803                if (adj > belowAdj && !proc.killedByAm) {
9804                    killUnneededProcessLocked(proc, reason);
9805                    killed = true;
9806                }
9807            }
9808        }
9809        return killed;
9810    }
9811
9812    @Override
9813    public void hang(final IBinder who, boolean allowRestart) {
9814        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9815                != PackageManager.PERMISSION_GRANTED) {
9816            throw new SecurityException("Requires permission "
9817                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9818        }
9819
9820        final IBinder.DeathRecipient death = new DeathRecipient() {
9821            @Override
9822            public void binderDied() {
9823                synchronized (this) {
9824                    notifyAll();
9825                }
9826            }
9827        };
9828
9829        try {
9830            who.linkToDeath(death, 0);
9831        } catch (RemoteException e) {
9832            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9833            return;
9834        }
9835
9836        synchronized (this) {
9837            Watchdog.getInstance().setAllowRestart(allowRestart);
9838            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9839            synchronized (death) {
9840                while (who.isBinderAlive()) {
9841                    try {
9842                        death.wait();
9843                    } catch (InterruptedException e) {
9844                    }
9845                }
9846            }
9847            Watchdog.getInstance().setAllowRestart(true);
9848        }
9849    }
9850
9851    @Override
9852    public void restart() {
9853        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9854                != PackageManager.PERMISSION_GRANTED) {
9855            throw new SecurityException("Requires permission "
9856                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9857        }
9858
9859        Log.i(TAG, "Sending shutdown broadcast...");
9860
9861        BroadcastReceiver br = new BroadcastReceiver() {
9862            @Override public void onReceive(Context context, Intent intent) {
9863                // Now the broadcast is done, finish up the low-level shutdown.
9864                Log.i(TAG, "Shutting down activity manager...");
9865                shutdown(10000);
9866                Log.i(TAG, "Shutdown complete, restarting!");
9867                Process.killProcess(Process.myPid());
9868                System.exit(10);
9869            }
9870        };
9871
9872        // First send the high-level shut down broadcast.
9873        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9874        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9875        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9876        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9877        mContext.sendOrderedBroadcastAsUser(intent,
9878                UserHandle.ALL, null, br, mHandler, 0, null, null);
9879        */
9880        br.onReceive(mContext, intent);
9881    }
9882
9883    private long getLowRamTimeSinceIdle(long now) {
9884        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9885    }
9886
9887    @Override
9888    public void performIdleMaintenance() {
9889        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9890                != PackageManager.PERMISSION_GRANTED) {
9891            throw new SecurityException("Requires permission "
9892                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9893        }
9894
9895        synchronized (this) {
9896            final long now = SystemClock.uptimeMillis();
9897            final long timeSinceLastIdle = now - mLastIdleTime;
9898            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9899            mLastIdleTime = now;
9900            mLowRamTimeSinceLastIdle = 0;
9901            if (mLowRamStartTime != 0) {
9902                mLowRamStartTime = now;
9903            }
9904
9905            StringBuilder sb = new StringBuilder(128);
9906            sb.append("Idle maintenance over ");
9907            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9908            sb.append(" low RAM for ");
9909            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9910            Slog.i(TAG, sb.toString());
9911
9912            // If at least 1/3 of our time since the last idle period has been spent
9913            // with RAM low, then we want to kill processes.
9914            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9915
9916            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9917                ProcessRecord proc = mLruProcesses.get(i);
9918                if (proc.notCachedSinceIdle) {
9919                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9920                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9921                        if (doKilling && proc.initialIdlePss != 0
9922                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9923                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9924                                    + " from " + proc.initialIdlePss + ")");
9925                        }
9926                    }
9927                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9928                    proc.notCachedSinceIdle = true;
9929                    proc.initialIdlePss = 0;
9930                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9931                            isSleeping(), now);
9932                }
9933            }
9934
9935            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9936            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9937        }
9938    }
9939
9940    private void retrieveSettings() {
9941        final ContentResolver resolver = mContext.getContentResolver();
9942        String debugApp = Settings.Global.getString(
9943            resolver, Settings.Global.DEBUG_APP);
9944        boolean waitForDebugger = Settings.Global.getInt(
9945            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9946        boolean alwaysFinishActivities = Settings.Global.getInt(
9947            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9948        boolean forceRtl = Settings.Global.getInt(
9949                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9950        // Transfer any global setting for forcing RTL layout, into a System Property
9951        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9952
9953        Configuration configuration = new Configuration();
9954        Settings.System.getConfiguration(resolver, configuration);
9955        if (forceRtl) {
9956            // This will take care of setting the correct layout direction flags
9957            configuration.setLayoutDirection(configuration.locale);
9958        }
9959
9960        synchronized (this) {
9961            mDebugApp = mOrigDebugApp = debugApp;
9962            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9963            mAlwaysFinishActivities = alwaysFinishActivities;
9964            // This happens before any activities are started, so we can
9965            // change mConfiguration in-place.
9966            updateConfigurationLocked(configuration, null, false, true);
9967            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9968        }
9969    }
9970
9971    public boolean testIsSystemReady() {
9972        // no need to synchronize(this) just to read & return the value
9973        return mSystemReady;
9974    }
9975
9976    private static File getCalledPreBootReceiversFile() {
9977        File dataDir = Environment.getDataDirectory();
9978        File systemDir = new File(dataDir, "system");
9979        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
9980        return fname;
9981    }
9982
9983    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9984        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9985        File file = getCalledPreBootReceiversFile();
9986        FileInputStream fis = null;
9987        try {
9988            fis = new FileInputStream(file);
9989            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9990            int fvers = dis.readInt();
9991            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
9992                String vers = dis.readUTF();
9993                String codename = dis.readUTF();
9994                String build = dis.readUTF();
9995                if (android.os.Build.VERSION.RELEASE.equals(vers)
9996                        && android.os.Build.VERSION.CODENAME.equals(codename)
9997                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9998                    int num = dis.readInt();
9999                    while (num > 0) {
10000                        num--;
10001                        String pkg = dis.readUTF();
10002                        String cls = dis.readUTF();
10003                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10004                    }
10005                }
10006            }
10007        } catch (FileNotFoundException e) {
10008        } catch (IOException e) {
10009            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10010        } finally {
10011            if (fis != null) {
10012                try {
10013                    fis.close();
10014                } catch (IOException e) {
10015                }
10016            }
10017        }
10018        return lastDoneReceivers;
10019    }
10020
10021    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10022        File file = getCalledPreBootReceiversFile();
10023        FileOutputStream fos = null;
10024        DataOutputStream dos = null;
10025        try {
10026            fos = new FileOutputStream(file);
10027            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10028            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10029            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10030            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10031            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10032            dos.writeInt(list.size());
10033            for (int i=0; i<list.size(); i++) {
10034                dos.writeUTF(list.get(i).getPackageName());
10035                dos.writeUTF(list.get(i).getClassName());
10036            }
10037        } catch (IOException e) {
10038            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10039            file.delete();
10040        } finally {
10041            FileUtils.sync(fos);
10042            if (dos != null) {
10043                try {
10044                    dos.close();
10045                } catch (IOException e) {
10046                    // TODO Auto-generated catch block
10047                    e.printStackTrace();
10048                }
10049            }
10050        }
10051    }
10052
10053    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10054            ArrayList<ComponentName> doneReceivers, int userId) {
10055        boolean waitingUpdate = false;
10056        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10057        List<ResolveInfo> ris = null;
10058        try {
10059            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10060                    intent, null, 0, userId);
10061        } catch (RemoteException e) {
10062        }
10063        if (ris != null) {
10064            for (int i=ris.size()-1; i>=0; i--) {
10065                if ((ris.get(i).activityInfo.applicationInfo.flags
10066                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10067                    ris.remove(i);
10068                }
10069            }
10070            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10071
10072            // For User 0, load the version number. When delivering to a new user, deliver
10073            // to all receivers.
10074            if (userId == UserHandle.USER_OWNER) {
10075                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10076                for (int i=0; i<ris.size(); i++) {
10077                    ActivityInfo ai = ris.get(i).activityInfo;
10078                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10079                    if (lastDoneReceivers.contains(comp)) {
10080                        // We already did the pre boot receiver for this app with the current
10081                        // platform version, so don't do it again...
10082                        ris.remove(i);
10083                        i--;
10084                        // ...however, do keep it as one that has been done, so we don't
10085                        // forget about it when rewriting the file of last done receivers.
10086                        doneReceivers.add(comp);
10087                    }
10088                }
10089            }
10090
10091            // If primary user, send broadcast to all available users, else just to userId
10092            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10093                    : new int[] { userId };
10094            for (int i = 0; i < ris.size(); i++) {
10095                ActivityInfo ai = ris.get(i).activityInfo;
10096                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10097                doneReceivers.add(comp);
10098                intent.setComponent(comp);
10099                for (int j=0; j<users.length; j++) {
10100                    IIntentReceiver finisher = null;
10101                    // On last receiver and user, set up a completion callback
10102                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10103                        finisher = new IIntentReceiver.Stub() {
10104                            public void performReceive(Intent intent, int resultCode,
10105                                    String data, Bundle extras, boolean ordered,
10106                                    boolean sticky, int sendingUser) {
10107                                // The raw IIntentReceiver interface is called
10108                                // with the AM lock held, so redispatch to
10109                                // execute our code without the lock.
10110                                mHandler.post(onFinishCallback);
10111                            }
10112                        };
10113                    }
10114                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10115                            + " for user " + users[j]);
10116                    broadcastIntentLocked(null, null, intent, null, finisher,
10117                            0, null, null, null, AppOpsManager.OP_NONE,
10118                            true, false, MY_PID, Process.SYSTEM_UID,
10119                            users[j]);
10120                    if (finisher != null) {
10121                        waitingUpdate = true;
10122                    }
10123                }
10124            }
10125        }
10126
10127        return waitingUpdate;
10128    }
10129
10130    public void systemReady(final Runnable goingCallback) {
10131        synchronized(this) {
10132            if (mSystemReady) {
10133                // If we're done calling all the receivers, run the next "boot phase" passed in
10134                // by the SystemServer
10135                if (goingCallback != null) {
10136                    goingCallback.run();
10137                }
10138                return;
10139            }
10140
10141            // Make sure we have the current profile info, since it is needed for
10142            // security checks.
10143            updateCurrentProfileIdsLocked();
10144
10145            if (mRecentTasks == null) {
10146                mRecentTasks = mTaskPersister.restoreTasksLocked();
10147                if (!mRecentTasks.isEmpty()) {
10148                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10149                }
10150                mTaskPersister.startPersisting();
10151            }
10152
10153            // Check to see if there are any update receivers to run.
10154            if (!mDidUpdate) {
10155                if (mWaitingUpdate) {
10156                    return;
10157                }
10158                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10159                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10160                    public void run() {
10161                        synchronized (ActivityManagerService.this) {
10162                            mDidUpdate = true;
10163                        }
10164                        writeLastDonePreBootReceivers(doneReceivers);
10165                        showBootMessage(mContext.getText(
10166                                R.string.android_upgrading_complete),
10167                                false);
10168                        systemReady(goingCallback);
10169                    }
10170                }, doneReceivers, UserHandle.USER_OWNER);
10171
10172                if (mWaitingUpdate) {
10173                    return;
10174                }
10175                mDidUpdate = true;
10176            }
10177
10178            mAppOpsService.systemReady();
10179            mSystemReady = true;
10180        }
10181
10182        ArrayList<ProcessRecord> procsToKill = null;
10183        synchronized(mPidsSelfLocked) {
10184            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10185                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10186                if (!isAllowedWhileBooting(proc.info)){
10187                    if (procsToKill == null) {
10188                        procsToKill = new ArrayList<ProcessRecord>();
10189                    }
10190                    procsToKill.add(proc);
10191                }
10192            }
10193        }
10194
10195        synchronized(this) {
10196            if (procsToKill != null) {
10197                for (int i=procsToKill.size()-1; i>=0; i--) {
10198                    ProcessRecord proc = procsToKill.get(i);
10199                    Slog.i(TAG, "Removing system update proc: " + proc);
10200                    removeProcessLocked(proc, true, false, "system update done");
10201                }
10202            }
10203
10204            // Now that we have cleaned up any update processes, we
10205            // are ready to start launching real processes and know that
10206            // we won't trample on them any more.
10207            mProcessesReady = true;
10208        }
10209
10210        Slog.i(TAG, "System now ready");
10211        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10212            SystemClock.uptimeMillis());
10213
10214        synchronized(this) {
10215            // Make sure we have no pre-ready processes sitting around.
10216
10217            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10218                ResolveInfo ri = mContext.getPackageManager()
10219                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10220                                STOCK_PM_FLAGS);
10221                CharSequence errorMsg = null;
10222                if (ri != null) {
10223                    ActivityInfo ai = ri.activityInfo;
10224                    ApplicationInfo app = ai.applicationInfo;
10225                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10226                        mTopAction = Intent.ACTION_FACTORY_TEST;
10227                        mTopData = null;
10228                        mTopComponent = new ComponentName(app.packageName,
10229                                ai.name);
10230                    } else {
10231                        errorMsg = mContext.getResources().getText(
10232                                com.android.internal.R.string.factorytest_not_system);
10233                    }
10234                } else {
10235                    errorMsg = mContext.getResources().getText(
10236                            com.android.internal.R.string.factorytest_no_action);
10237                }
10238                if (errorMsg != null) {
10239                    mTopAction = null;
10240                    mTopData = null;
10241                    mTopComponent = null;
10242                    Message msg = Message.obtain();
10243                    msg.what = SHOW_FACTORY_ERROR_MSG;
10244                    msg.getData().putCharSequence("msg", errorMsg);
10245                    mHandler.sendMessage(msg);
10246                }
10247            }
10248        }
10249
10250        retrieveSettings();
10251
10252        synchronized (this) {
10253            readGrantedUriPermissionsLocked();
10254        }
10255
10256        if (goingCallback != null) goingCallback.run();
10257
10258        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10259                Integer.toString(mCurrentUserId), mCurrentUserId);
10260        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10261                Integer.toString(mCurrentUserId), mCurrentUserId);
10262        mSystemServiceManager.startUser(mCurrentUserId);
10263
10264        synchronized (this) {
10265            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10266                try {
10267                    List apps = AppGlobals.getPackageManager().
10268                        getPersistentApplications(STOCK_PM_FLAGS);
10269                    if (apps != null) {
10270                        int N = apps.size();
10271                        int i;
10272                        for (i=0; i<N; i++) {
10273                            ApplicationInfo info
10274                                = (ApplicationInfo)apps.get(i);
10275                            if (info != null &&
10276                                    !info.packageName.equals("android")) {
10277                                addAppLocked(info, false, null /* ABI override */);
10278                            }
10279                        }
10280                    }
10281                } catch (RemoteException ex) {
10282                    // pm is in same process, this will never happen.
10283                }
10284            }
10285
10286            // Start up initial activity.
10287            mBooting = true;
10288
10289            try {
10290                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10291                    Message msg = Message.obtain();
10292                    msg.what = SHOW_UID_ERROR_MSG;
10293                    mHandler.sendMessage(msg);
10294                }
10295            } catch (RemoteException e) {
10296            }
10297
10298            long ident = Binder.clearCallingIdentity();
10299            try {
10300                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10301                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10302                        | Intent.FLAG_RECEIVER_FOREGROUND);
10303                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10304                broadcastIntentLocked(null, null, intent,
10305                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10306                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10307                intent = new Intent(Intent.ACTION_USER_STARTING);
10308                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10309                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10310                broadcastIntentLocked(null, null, intent,
10311                        null, new IIntentReceiver.Stub() {
10312                            @Override
10313                            public void performReceive(Intent intent, int resultCode, String data,
10314                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10315                                    throws RemoteException {
10316                            }
10317                        }, 0, null, null,
10318                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10319                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10320            } catch (Throwable t) {
10321                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10322            } finally {
10323                Binder.restoreCallingIdentity(ident);
10324            }
10325            mStackSupervisor.resumeTopActivitiesLocked();
10326            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10327        }
10328    }
10329
10330    private boolean makeAppCrashingLocked(ProcessRecord app,
10331            String shortMsg, String longMsg, String stackTrace) {
10332        app.crashing = true;
10333        app.crashingReport = generateProcessError(app,
10334                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10335        startAppProblemLocked(app);
10336        app.stopFreezingAllLocked();
10337        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10338    }
10339
10340    private void makeAppNotRespondingLocked(ProcessRecord app,
10341            String activity, String shortMsg, String longMsg) {
10342        app.notResponding = true;
10343        app.notRespondingReport = generateProcessError(app,
10344                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10345                activity, shortMsg, longMsg, null);
10346        startAppProblemLocked(app);
10347        app.stopFreezingAllLocked();
10348    }
10349
10350    /**
10351     * Generate a process error record, suitable for attachment to a ProcessRecord.
10352     *
10353     * @param app The ProcessRecord in which the error occurred.
10354     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10355     *                      ActivityManager.AppErrorStateInfo
10356     * @param activity The activity associated with the crash, if known.
10357     * @param shortMsg Short message describing the crash.
10358     * @param longMsg Long message describing the crash.
10359     * @param stackTrace Full crash stack trace, may be null.
10360     *
10361     * @return Returns a fully-formed AppErrorStateInfo record.
10362     */
10363    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10364            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10365        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10366
10367        report.condition = condition;
10368        report.processName = app.processName;
10369        report.pid = app.pid;
10370        report.uid = app.info.uid;
10371        report.tag = activity;
10372        report.shortMsg = shortMsg;
10373        report.longMsg = longMsg;
10374        report.stackTrace = stackTrace;
10375
10376        return report;
10377    }
10378
10379    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10380        synchronized (this) {
10381            app.crashing = false;
10382            app.crashingReport = null;
10383            app.notResponding = false;
10384            app.notRespondingReport = null;
10385            if (app.anrDialog == fromDialog) {
10386                app.anrDialog = null;
10387            }
10388            if (app.waitDialog == fromDialog) {
10389                app.waitDialog = null;
10390            }
10391            if (app.pid > 0 && app.pid != MY_PID) {
10392                handleAppCrashLocked(app, null, null, null);
10393                killUnneededProcessLocked(app, "user request after error");
10394            }
10395        }
10396    }
10397
10398    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10399            String stackTrace) {
10400        long now = SystemClock.uptimeMillis();
10401
10402        Long crashTime;
10403        if (!app.isolated) {
10404            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10405        } else {
10406            crashTime = null;
10407        }
10408        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10409            // This process loses!
10410            Slog.w(TAG, "Process " + app.info.processName
10411                    + " has crashed too many times: killing!");
10412            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10413                    app.userId, app.info.processName, app.uid);
10414            mStackSupervisor.handleAppCrashLocked(app);
10415            if (!app.persistent) {
10416                // We don't want to start this process again until the user
10417                // explicitly does so...  but for persistent process, we really
10418                // need to keep it running.  If a persistent process is actually
10419                // repeatedly crashing, then badness for everyone.
10420                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10421                        app.info.processName);
10422                if (!app.isolated) {
10423                    // XXX We don't have a way to mark isolated processes
10424                    // as bad, since they don't have a peristent identity.
10425                    mBadProcesses.put(app.info.processName, app.uid,
10426                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10427                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10428                }
10429                app.bad = true;
10430                app.removed = true;
10431                // Don't let services in this process be restarted and potentially
10432                // annoy the user repeatedly.  Unless it is persistent, since those
10433                // processes run critical code.
10434                removeProcessLocked(app, false, false, "crash");
10435                mStackSupervisor.resumeTopActivitiesLocked();
10436                return false;
10437            }
10438            mStackSupervisor.resumeTopActivitiesLocked();
10439        } else {
10440            mStackSupervisor.finishTopRunningActivityLocked(app);
10441        }
10442
10443        // Bump up the crash count of any services currently running in the proc.
10444        for (int i=app.services.size()-1; i>=0; i--) {
10445            // Any services running in the application need to be placed
10446            // back in the pending list.
10447            ServiceRecord sr = app.services.valueAt(i);
10448            sr.crashCount++;
10449        }
10450
10451        // If the crashing process is what we consider to be the "home process" and it has been
10452        // replaced by a third-party app, clear the package preferred activities from packages
10453        // with a home activity running in the process to prevent a repeatedly crashing app
10454        // from blocking the user to manually clear the list.
10455        final ArrayList<ActivityRecord> activities = app.activities;
10456        if (app == mHomeProcess && activities.size() > 0
10457                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10458            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10459                final ActivityRecord r = activities.get(activityNdx);
10460                if (r.isHomeActivity()) {
10461                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10462                    try {
10463                        ActivityThread.getPackageManager()
10464                                .clearPackagePreferredActivities(r.packageName);
10465                    } catch (RemoteException c) {
10466                        // pm is in same process, this will never happen.
10467                    }
10468                }
10469            }
10470        }
10471
10472        if (!app.isolated) {
10473            // XXX Can't keep track of crash times for isolated processes,
10474            // because they don't have a perisistent identity.
10475            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10476        }
10477
10478        return true;
10479    }
10480
10481    void startAppProblemLocked(ProcessRecord app) {
10482        if (app.userId == mCurrentUserId) {
10483            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10484                    mContext, app.info.packageName, app.info.flags);
10485        } else {
10486            // If this app is not running under the current user, then we
10487            // can't give it a report button because that would require
10488            // launching the report UI under a different user.
10489            app.errorReportReceiver = null;
10490        }
10491        skipCurrentReceiverLocked(app);
10492    }
10493
10494    void skipCurrentReceiverLocked(ProcessRecord app) {
10495        for (BroadcastQueue queue : mBroadcastQueues) {
10496            queue.skipCurrentReceiverLocked(app);
10497        }
10498    }
10499
10500    /**
10501     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10502     * The application process will exit immediately after this call returns.
10503     * @param app object of the crashing app, null for the system server
10504     * @param crashInfo describing the exception
10505     */
10506    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10507        ProcessRecord r = findAppProcess(app, "Crash");
10508        final String processName = app == null ? "system_server"
10509                : (r == null ? "unknown" : r.processName);
10510
10511        handleApplicationCrashInner("crash", r, processName, crashInfo);
10512    }
10513
10514    /* Native crash reporting uses this inner version because it needs to be somewhat
10515     * decoupled from the AM-managed cleanup lifecycle
10516     */
10517    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10518            ApplicationErrorReport.CrashInfo crashInfo) {
10519        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10520                UserHandle.getUserId(Binder.getCallingUid()), processName,
10521                r == null ? -1 : r.info.flags,
10522                crashInfo.exceptionClassName,
10523                crashInfo.exceptionMessage,
10524                crashInfo.throwFileName,
10525                crashInfo.throwLineNumber);
10526
10527        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10528
10529        crashApplication(r, crashInfo);
10530    }
10531
10532    public void handleApplicationStrictModeViolation(
10533            IBinder app,
10534            int violationMask,
10535            StrictMode.ViolationInfo info) {
10536        ProcessRecord r = findAppProcess(app, "StrictMode");
10537        if (r == null) {
10538            return;
10539        }
10540
10541        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10542            Integer stackFingerprint = info.hashCode();
10543            boolean logIt = true;
10544            synchronized (mAlreadyLoggedViolatedStacks) {
10545                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10546                    logIt = false;
10547                    // TODO: sub-sample into EventLog for these, with
10548                    // the info.durationMillis?  Then we'd get
10549                    // the relative pain numbers, without logging all
10550                    // the stack traces repeatedly.  We'd want to do
10551                    // likewise in the client code, which also does
10552                    // dup suppression, before the Binder call.
10553                } else {
10554                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10555                        mAlreadyLoggedViolatedStacks.clear();
10556                    }
10557                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10558                }
10559            }
10560            if (logIt) {
10561                logStrictModeViolationToDropBox(r, info);
10562            }
10563        }
10564
10565        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10566            AppErrorResult result = new AppErrorResult();
10567            synchronized (this) {
10568                final long origId = Binder.clearCallingIdentity();
10569
10570                Message msg = Message.obtain();
10571                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10572                HashMap<String, Object> data = new HashMap<String, Object>();
10573                data.put("result", result);
10574                data.put("app", r);
10575                data.put("violationMask", violationMask);
10576                data.put("info", info);
10577                msg.obj = data;
10578                mHandler.sendMessage(msg);
10579
10580                Binder.restoreCallingIdentity(origId);
10581            }
10582            int res = result.get();
10583            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10584        }
10585    }
10586
10587    // Depending on the policy in effect, there could be a bunch of
10588    // these in quick succession so we try to batch these together to
10589    // minimize disk writes, number of dropbox entries, and maximize
10590    // compression, by having more fewer, larger records.
10591    private void logStrictModeViolationToDropBox(
10592            ProcessRecord process,
10593            StrictMode.ViolationInfo info) {
10594        if (info == null) {
10595            return;
10596        }
10597        final boolean isSystemApp = process == null ||
10598                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10599                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10600        final String processName = process == null ? "unknown" : process.processName;
10601        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10602        final DropBoxManager dbox = (DropBoxManager)
10603                mContext.getSystemService(Context.DROPBOX_SERVICE);
10604
10605        // Exit early if the dropbox isn't configured to accept this report type.
10606        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10607
10608        boolean bufferWasEmpty;
10609        boolean needsFlush;
10610        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10611        synchronized (sb) {
10612            bufferWasEmpty = sb.length() == 0;
10613            appendDropBoxProcessHeaders(process, processName, sb);
10614            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10615            sb.append("System-App: ").append(isSystemApp).append("\n");
10616            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10617            if (info.violationNumThisLoop != 0) {
10618                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10619            }
10620            if (info.numAnimationsRunning != 0) {
10621                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10622            }
10623            if (info.broadcastIntentAction != null) {
10624                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10625            }
10626            if (info.durationMillis != -1) {
10627                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10628            }
10629            if (info.numInstances != -1) {
10630                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10631            }
10632            if (info.tags != null) {
10633                for (String tag : info.tags) {
10634                    sb.append("Span-Tag: ").append(tag).append("\n");
10635                }
10636            }
10637            sb.append("\n");
10638            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10639                sb.append(info.crashInfo.stackTrace);
10640            }
10641            sb.append("\n");
10642
10643            // Only buffer up to ~64k.  Various logging bits truncate
10644            // things at 128k.
10645            needsFlush = (sb.length() > 64 * 1024);
10646        }
10647
10648        // Flush immediately if the buffer's grown too large, or this
10649        // is a non-system app.  Non-system apps are isolated with a
10650        // different tag & policy and not batched.
10651        //
10652        // Batching is useful during internal testing with
10653        // StrictMode settings turned up high.  Without batching,
10654        // thousands of separate files could be created on boot.
10655        if (!isSystemApp || needsFlush) {
10656            new Thread("Error dump: " + dropboxTag) {
10657                @Override
10658                public void run() {
10659                    String report;
10660                    synchronized (sb) {
10661                        report = sb.toString();
10662                        sb.delete(0, sb.length());
10663                        sb.trimToSize();
10664                    }
10665                    if (report.length() != 0) {
10666                        dbox.addText(dropboxTag, report);
10667                    }
10668                }
10669            }.start();
10670            return;
10671        }
10672
10673        // System app batching:
10674        if (!bufferWasEmpty) {
10675            // An existing dropbox-writing thread is outstanding, so
10676            // we don't need to start it up.  The existing thread will
10677            // catch the buffer appends we just did.
10678            return;
10679        }
10680
10681        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10682        // (After this point, we shouldn't access AMS internal data structures.)
10683        new Thread("Error dump: " + dropboxTag) {
10684            @Override
10685            public void run() {
10686                // 5 second sleep to let stacks arrive and be batched together
10687                try {
10688                    Thread.sleep(5000);  // 5 seconds
10689                } catch (InterruptedException e) {}
10690
10691                String errorReport;
10692                synchronized (mStrictModeBuffer) {
10693                    errorReport = mStrictModeBuffer.toString();
10694                    if (errorReport.length() == 0) {
10695                        return;
10696                    }
10697                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10698                    mStrictModeBuffer.trimToSize();
10699                }
10700                dbox.addText(dropboxTag, errorReport);
10701            }
10702        }.start();
10703    }
10704
10705    /**
10706     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10707     * @param app object of the crashing app, null for the system server
10708     * @param tag reported by the caller
10709     * @param crashInfo describing the context of the error
10710     * @return true if the process should exit immediately (WTF is fatal)
10711     */
10712    public boolean handleApplicationWtf(IBinder app, String tag,
10713            ApplicationErrorReport.CrashInfo crashInfo) {
10714        ProcessRecord r = findAppProcess(app, "WTF");
10715        final String processName = app == null ? "system_server"
10716                : (r == null ? "unknown" : r.processName);
10717
10718        EventLog.writeEvent(EventLogTags.AM_WTF,
10719                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10720                processName,
10721                r == null ? -1 : r.info.flags,
10722                tag, crashInfo.exceptionMessage);
10723
10724        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10725
10726        if (r != null && r.pid != Process.myPid() &&
10727                Settings.Global.getInt(mContext.getContentResolver(),
10728                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10729            crashApplication(r, crashInfo);
10730            return true;
10731        } else {
10732            return false;
10733        }
10734    }
10735
10736    /**
10737     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10738     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10739     */
10740    private ProcessRecord findAppProcess(IBinder app, String reason) {
10741        if (app == null) {
10742            return null;
10743        }
10744
10745        synchronized (this) {
10746            final int NP = mProcessNames.getMap().size();
10747            for (int ip=0; ip<NP; ip++) {
10748                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10749                final int NA = apps.size();
10750                for (int ia=0; ia<NA; ia++) {
10751                    ProcessRecord p = apps.valueAt(ia);
10752                    if (p.thread != null && p.thread.asBinder() == app) {
10753                        return p;
10754                    }
10755                }
10756            }
10757
10758            Slog.w(TAG, "Can't find mystery application for " + reason
10759                    + " from pid=" + Binder.getCallingPid()
10760                    + " uid=" + Binder.getCallingUid() + ": " + app);
10761            return null;
10762        }
10763    }
10764
10765    /**
10766     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10767     * to append various headers to the dropbox log text.
10768     */
10769    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10770            StringBuilder sb) {
10771        // Watchdog thread ends up invoking this function (with
10772        // a null ProcessRecord) to add the stack file to dropbox.
10773        // Do not acquire a lock on this (am) in such cases, as it
10774        // could cause a potential deadlock, if and when watchdog
10775        // is invoked due to unavailability of lock on am and it
10776        // would prevent watchdog from killing system_server.
10777        if (process == null) {
10778            sb.append("Process: ").append(processName).append("\n");
10779            return;
10780        }
10781        // Note: ProcessRecord 'process' is guarded by the service
10782        // instance.  (notably process.pkgList, which could otherwise change
10783        // concurrently during execution of this method)
10784        synchronized (this) {
10785            sb.append("Process: ").append(processName).append("\n");
10786            int flags = process.info.flags;
10787            IPackageManager pm = AppGlobals.getPackageManager();
10788            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10789            for (int ip=0; ip<process.pkgList.size(); ip++) {
10790                String pkg = process.pkgList.keyAt(ip);
10791                sb.append("Package: ").append(pkg);
10792                try {
10793                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10794                    if (pi != null) {
10795                        sb.append(" v").append(pi.versionCode);
10796                        if (pi.versionName != null) {
10797                            sb.append(" (").append(pi.versionName).append(")");
10798                        }
10799                    }
10800                } catch (RemoteException e) {
10801                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10802                }
10803                sb.append("\n");
10804            }
10805        }
10806    }
10807
10808    private static String processClass(ProcessRecord process) {
10809        if (process == null || process.pid == MY_PID) {
10810            return "system_server";
10811        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10812            return "system_app";
10813        } else {
10814            return "data_app";
10815        }
10816    }
10817
10818    /**
10819     * Write a description of an error (crash, WTF, ANR) to the drop box.
10820     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10821     * @param process which caused the error, null means the system server
10822     * @param activity which triggered the error, null if unknown
10823     * @param parent activity related to the error, null if unknown
10824     * @param subject line related to the error, null if absent
10825     * @param report in long form describing the error, null if absent
10826     * @param logFile to include in the report, null if none
10827     * @param crashInfo giving an application stack trace, null if absent
10828     */
10829    public void addErrorToDropBox(String eventType,
10830            ProcessRecord process, String processName, ActivityRecord activity,
10831            ActivityRecord parent, String subject,
10832            final String report, final File logFile,
10833            final ApplicationErrorReport.CrashInfo crashInfo) {
10834        // NOTE -- this must never acquire the ActivityManagerService lock,
10835        // otherwise the watchdog may be prevented from resetting the system.
10836
10837        final String dropboxTag = processClass(process) + "_" + eventType;
10838        final DropBoxManager dbox = (DropBoxManager)
10839                mContext.getSystemService(Context.DROPBOX_SERVICE);
10840
10841        // Exit early if the dropbox isn't configured to accept this report type.
10842        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10843
10844        final StringBuilder sb = new StringBuilder(1024);
10845        appendDropBoxProcessHeaders(process, processName, sb);
10846        if (activity != null) {
10847            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10848        }
10849        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10850            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10851        }
10852        if (parent != null && parent != activity) {
10853            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10854        }
10855        if (subject != null) {
10856            sb.append("Subject: ").append(subject).append("\n");
10857        }
10858        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10859        if (Debug.isDebuggerConnected()) {
10860            sb.append("Debugger: Connected\n");
10861        }
10862        sb.append("\n");
10863
10864        // Do the rest in a worker thread to avoid blocking the caller on I/O
10865        // (After this point, we shouldn't access AMS internal data structures.)
10866        Thread worker = new Thread("Error dump: " + dropboxTag) {
10867            @Override
10868            public void run() {
10869                if (report != null) {
10870                    sb.append(report);
10871                }
10872                if (logFile != null) {
10873                    try {
10874                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10875                                    "\n\n[[TRUNCATED]]"));
10876                    } catch (IOException e) {
10877                        Slog.e(TAG, "Error reading " + logFile, e);
10878                    }
10879                }
10880                if (crashInfo != null && crashInfo.stackTrace != null) {
10881                    sb.append(crashInfo.stackTrace);
10882                }
10883
10884                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10885                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10886                if (lines > 0) {
10887                    sb.append("\n");
10888
10889                    // Merge several logcat streams, and take the last N lines
10890                    InputStreamReader input = null;
10891                    try {
10892                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10893                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10894                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10895
10896                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10897                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10898                        input = new InputStreamReader(logcat.getInputStream());
10899
10900                        int num;
10901                        char[] buf = new char[8192];
10902                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10903                    } catch (IOException e) {
10904                        Slog.e(TAG, "Error running logcat", e);
10905                    } finally {
10906                        if (input != null) try { input.close(); } catch (IOException e) {}
10907                    }
10908                }
10909
10910                dbox.addText(dropboxTag, sb.toString());
10911            }
10912        };
10913
10914        if (process == null) {
10915            // If process is null, we are being called from some internal code
10916            // and may be about to die -- run this synchronously.
10917            worker.run();
10918        } else {
10919            worker.start();
10920        }
10921    }
10922
10923    /**
10924     * Bring up the "unexpected error" dialog box for a crashing app.
10925     * Deal with edge cases (intercepts from instrumented applications,
10926     * ActivityController, error intent receivers, that sort of thing).
10927     * @param r the application crashing
10928     * @param crashInfo describing the failure
10929     */
10930    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10931        long timeMillis = System.currentTimeMillis();
10932        String shortMsg = crashInfo.exceptionClassName;
10933        String longMsg = crashInfo.exceptionMessage;
10934        String stackTrace = crashInfo.stackTrace;
10935        if (shortMsg != null && longMsg != null) {
10936            longMsg = shortMsg + ": " + longMsg;
10937        } else if (shortMsg != null) {
10938            longMsg = shortMsg;
10939        }
10940
10941        AppErrorResult result = new AppErrorResult();
10942        synchronized (this) {
10943            if (mController != null) {
10944                try {
10945                    String name = r != null ? r.processName : null;
10946                    int pid = r != null ? r.pid : Binder.getCallingPid();
10947                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
10948                    if (!mController.appCrashed(name, pid,
10949                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10950                        Slog.w(TAG, "Force-killing crashed app " + name
10951                                + " at watcher's request");
10952                        Process.killProcess(pid);
10953                        if (r != null) {
10954                            Process.killProcessGroup(uid, pid);
10955                        }
10956                        return;
10957                    }
10958                } catch (RemoteException e) {
10959                    mController = null;
10960                    Watchdog.getInstance().setActivityController(null);
10961                }
10962            }
10963
10964            final long origId = Binder.clearCallingIdentity();
10965
10966            // If this process is running instrumentation, finish it.
10967            if (r != null && r.instrumentationClass != null) {
10968                Slog.w(TAG, "Error in app " + r.processName
10969                      + " running instrumentation " + r.instrumentationClass + ":");
10970                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10971                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10972                Bundle info = new Bundle();
10973                info.putString("shortMsg", shortMsg);
10974                info.putString("longMsg", longMsg);
10975                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10976                Binder.restoreCallingIdentity(origId);
10977                return;
10978            }
10979
10980            // If we can't identify the process or it's already exceeded its crash quota,
10981            // quit right away without showing a crash dialog.
10982            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10983                Binder.restoreCallingIdentity(origId);
10984                return;
10985            }
10986
10987            Message msg = Message.obtain();
10988            msg.what = SHOW_ERROR_MSG;
10989            HashMap data = new HashMap();
10990            data.put("result", result);
10991            data.put("app", r);
10992            msg.obj = data;
10993            mHandler.sendMessage(msg);
10994
10995            Binder.restoreCallingIdentity(origId);
10996        }
10997
10998        int res = result.get();
10999
11000        Intent appErrorIntent = null;
11001        synchronized (this) {
11002            if (r != null && !r.isolated) {
11003                // XXX Can't keep track of crash time for isolated processes,
11004                // since they don't have a persistent identity.
11005                mProcessCrashTimes.put(r.info.processName, r.uid,
11006                        SystemClock.uptimeMillis());
11007            }
11008            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11009                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11010            }
11011        }
11012
11013        if (appErrorIntent != null) {
11014            try {
11015                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11016            } catch (ActivityNotFoundException e) {
11017                Slog.w(TAG, "bug report receiver dissappeared", e);
11018            }
11019        }
11020    }
11021
11022    Intent createAppErrorIntentLocked(ProcessRecord r,
11023            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11024        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11025        if (report == null) {
11026            return null;
11027        }
11028        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11029        result.setComponent(r.errorReportReceiver);
11030        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11031        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11032        return result;
11033    }
11034
11035    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11036            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11037        if (r.errorReportReceiver == null) {
11038            return null;
11039        }
11040
11041        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11042            return null;
11043        }
11044
11045        ApplicationErrorReport report = new ApplicationErrorReport();
11046        report.packageName = r.info.packageName;
11047        report.installerPackageName = r.errorReportReceiver.getPackageName();
11048        report.processName = r.processName;
11049        report.time = timeMillis;
11050        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11051
11052        if (r.crashing || r.forceCrashReport) {
11053            report.type = ApplicationErrorReport.TYPE_CRASH;
11054            report.crashInfo = crashInfo;
11055        } else if (r.notResponding) {
11056            report.type = ApplicationErrorReport.TYPE_ANR;
11057            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11058
11059            report.anrInfo.activity = r.notRespondingReport.tag;
11060            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11061            report.anrInfo.info = r.notRespondingReport.longMsg;
11062        }
11063
11064        return report;
11065    }
11066
11067    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11068        enforceNotIsolatedCaller("getProcessesInErrorState");
11069        // assume our apps are happy - lazy create the list
11070        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11071
11072        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11073                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11074        int userId = UserHandle.getUserId(Binder.getCallingUid());
11075
11076        synchronized (this) {
11077
11078            // iterate across all processes
11079            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11080                ProcessRecord app = mLruProcesses.get(i);
11081                if (!allUsers && app.userId != userId) {
11082                    continue;
11083                }
11084                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11085                    // This one's in trouble, so we'll generate a report for it
11086                    // crashes are higher priority (in case there's a crash *and* an anr)
11087                    ActivityManager.ProcessErrorStateInfo report = null;
11088                    if (app.crashing) {
11089                        report = app.crashingReport;
11090                    } else if (app.notResponding) {
11091                        report = app.notRespondingReport;
11092                    }
11093
11094                    if (report != null) {
11095                        if (errList == null) {
11096                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11097                        }
11098                        errList.add(report);
11099                    } else {
11100                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11101                                " crashing = " + app.crashing +
11102                                " notResponding = " + app.notResponding);
11103                    }
11104                }
11105            }
11106        }
11107
11108        return errList;
11109    }
11110
11111    static int procStateToImportance(int procState, int memAdj,
11112            ActivityManager.RunningAppProcessInfo currApp) {
11113        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11114        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11115            currApp.lru = memAdj;
11116        } else {
11117            currApp.lru = 0;
11118        }
11119        return imp;
11120    }
11121
11122    private void fillInProcMemInfo(ProcessRecord app,
11123            ActivityManager.RunningAppProcessInfo outInfo) {
11124        outInfo.pid = app.pid;
11125        outInfo.uid = app.info.uid;
11126        if (mHeavyWeightProcess == app) {
11127            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11128        }
11129        if (app.persistent) {
11130            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11131        }
11132        if (app.activities.size() > 0) {
11133            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11134        }
11135        outInfo.lastTrimLevel = app.trimMemoryLevel;
11136        int adj = app.curAdj;
11137        int procState = app.curProcState;
11138        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11139        outInfo.importanceReasonCode = app.adjTypeCode;
11140        outInfo.processState = app.curProcState;
11141    }
11142
11143    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11144        enforceNotIsolatedCaller("getRunningAppProcesses");
11145        // Lazy instantiation of list
11146        List<ActivityManager.RunningAppProcessInfo> runList = null;
11147        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11148                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11149        int userId = UserHandle.getUserId(Binder.getCallingUid());
11150        synchronized (this) {
11151            // Iterate across all processes
11152            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11153                ProcessRecord app = mLruProcesses.get(i);
11154                if (!allUsers && app.userId != userId) {
11155                    continue;
11156                }
11157                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11158                    // Generate process state info for running application
11159                    ActivityManager.RunningAppProcessInfo currApp =
11160                        new ActivityManager.RunningAppProcessInfo(app.processName,
11161                                app.pid, app.getPackageList());
11162                    fillInProcMemInfo(app, currApp);
11163                    if (app.adjSource instanceof ProcessRecord) {
11164                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11165                        currApp.importanceReasonImportance =
11166                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11167                                        app.adjSourceProcState);
11168                    } else if (app.adjSource instanceof ActivityRecord) {
11169                        ActivityRecord r = (ActivityRecord)app.adjSource;
11170                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11171                    }
11172                    if (app.adjTarget instanceof ComponentName) {
11173                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11174                    }
11175                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11176                    //        + " lru=" + currApp.lru);
11177                    if (runList == null) {
11178                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11179                    }
11180                    runList.add(currApp);
11181                }
11182            }
11183        }
11184        return runList;
11185    }
11186
11187    public List<ApplicationInfo> getRunningExternalApplications() {
11188        enforceNotIsolatedCaller("getRunningExternalApplications");
11189        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11190        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11191        if (runningApps != null && runningApps.size() > 0) {
11192            Set<String> extList = new HashSet<String>();
11193            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11194                if (app.pkgList != null) {
11195                    for (String pkg : app.pkgList) {
11196                        extList.add(pkg);
11197                    }
11198                }
11199            }
11200            IPackageManager pm = AppGlobals.getPackageManager();
11201            for (String pkg : extList) {
11202                try {
11203                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11204                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11205                        retList.add(info);
11206                    }
11207                } catch (RemoteException e) {
11208                }
11209            }
11210        }
11211        return retList;
11212    }
11213
11214    @Override
11215    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11216        enforceNotIsolatedCaller("getMyMemoryState");
11217        synchronized (this) {
11218            ProcessRecord proc;
11219            synchronized (mPidsSelfLocked) {
11220                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11221            }
11222            fillInProcMemInfo(proc, outInfo);
11223        }
11224    }
11225
11226    @Override
11227    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11228        if (checkCallingPermission(android.Manifest.permission.DUMP)
11229                != PackageManager.PERMISSION_GRANTED) {
11230            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11231                    + Binder.getCallingPid()
11232                    + ", uid=" + Binder.getCallingUid()
11233                    + " without permission "
11234                    + android.Manifest.permission.DUMP);
11235            return;
11236        }
11237
11238        boolean dumpAll = false;
11239        boolean dumpClient = false;
11240        String dumpPackage = null;
11241
11242        int opti = 0;
11243        while (opti < args.length) {
11244            String opt = args[opti];
11245            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11246                break;
11247            }
11248            opti++;
11249            if ("-a".equals(opt)) {
11250                dumpAll = true;
11251            } else if ("-c".equals(opt)) {
11252                dumpClient = true;
11253            } else if ("-h".equals(opt)) {
11254                pw.println("Activity manager dump options:");
11255                pw.println("  [-a] [-c] [-h] [cmd] ...");
11256                pw.println("  cmd may be one of:");
11257                pw.println("    a[ctivities]: activity stack state");
11258                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11259                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11260                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11261                pw.println("    o[om]: out of memory management");
11262                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11263                pw.println("    provider [COMP_SPEC]: provider client-side state");
11264                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11265                pw.println("    service [COMP_SPEC]: service client-side state");
11266                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11267                pw.println("    all: dump all activities");
11268                pw.println("    top: dump the top activity");
11269                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11270                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11271                pw.println("    a partial substring in a component name, a");
11272                pw.println("    hex object identifier.");
11273                pw.println("  -a: include all available server state.");
11274                pw.println("  -c: include client state.");
11275                return;
11276            } else {
11277                pw.println("Unknown argument: " + opt + "; use -h for help");
11278            }
11279        }
11280
11281        long origId = Binder.clearCallingIdentity();
11282        boolean more = false;
11283        // Is the caller requesting to dump a particular piece of data?
11284        if (opti < args.length) {
11285            String cmd = args[opti];
11286            opti++;
11287            if ("activities".equals(cmd) || "a".equals(cmd)) {
11288                synchronized (this) {
11289                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11290                }
11291            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11292                String[] newArgs;
11293                String name;
11294                if (opti >= args.length) {
11295                    name = null;
11296                    newArgs = EMPTY_STRING_ARRAY;
11297                } else {
11298                    name = args[opti];
11299                    opti++;
11300                    newArgs = new String[args.length - opti];
11301                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11302                            args.length - opti);
11303                }
11304                synchronized (this) {
11305                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11306                }
11307            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11308                String[] newArgs;
11309                String name;
11310                if (opti >= args.length) {
11311                    name = null;
11312                    newArgs = EMPTY_STRING_ARRAY;
11313                } else {
11314                    name = args[opti];
11315                    opti++;
11316                    newArgs = new String[args.length - opti];
11317                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11318                            args.length - opti);
11319                }
11320                synchronized (this) {
11321                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11322                }
11323            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11324                String[] newArgs;
11325                String name;
11326                if (opti >= args.length) {
11327                    name = null;
11328                    newArgs = EMPTY_STRING_ARRAY;
11329                } else {
11330                    name = args[opti];
11331                    opti++;
11332                    newArgs = new String[args.length - opti];
11333                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11334                            args.length - opti);
11335                }
11336                synchronized (this) {
11337                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11338                }
11339            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11340                synchronized (this) {
11341                    dumpOomLocked(fd, pw, args, opti, true);
11342                }
11343            } else if ("provider".equals(cmd)) {
11344                String[] newArgs;
11345                String name;
11346                if (opti >= args.length) {
11347                    name = null;
11348                    newArgs = EMPTY_STRING_ARRAY;
11349                } else {
11350                    name = args[opti];
11351                    opti++;
11352                    newArgs = new String[args.length - opti];
11353                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11354                }
11355                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11356                    pw.println("No providers match: " + name);
11357                    pw.println("Use -h for help.");
11358                }
11359            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11360                synchronized (this) {
11361                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11362                }
11363            } else if ("service".equals(cmd)) {
11364                String[] newArgs;
11365                String name;
11366                if (opti >= args.length) {
11367                    name = null;
11368                    newArgs = EMPTY_STRING_ARRAY;
11369                } else {
11370                    name = args[opti];
11371                    opti++;
11372                    newArgs = new String[args.length - opti];
11373                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11374                            args.length - opti);
11375                }
11376                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11377                    pw.println("No services match: " + name);
11378                    pw.println("Use -h for help.");
11379                }
11380            } else if ("package".equals(cmd)) {
11381                String[] newArgs;
11382                if (opti >= args.length) {
11383                    pw.println("package: no package name specified");
11384                    pw.println("Use -h for help.");
11385                } else {
11386                    dumpPackage = args[opti];
11387                    opti++;
11388                    newArgs = new String[args.length - opti];
11389                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11390                            args.length - opti);
11391                    args = newArgs;
11392                    opti = 0;
11393                    more = true;
11394                }
11395            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11396                synchronized (this) {
11397                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11398                }
11399            } else {
11400                // Dumping a single activity?
11401                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11402                    pw.println("Bad activity command, or no activities match: " + cmd);
11403                    pw.println("Use -h for help.");
11404                }
11405            }
11406            if (!more) {
11407                Binder.restoreCallingIdentity(origId);
11408                return;
11409            }
11410        }
11411
11412        // No piece of data specified, dump everything.
11413        synchronized (this) {
11414            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11415            pw.println();
11416            if (dumpAll) {
11417                pw.println("-------------------------------------------------------------------------------");
11418            }
11419            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11420            pw.println();
11421            if (dumpAll) {
11422                pw.println("-------------------------------------------------------------------------------");
11423            }
11424            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11425            pw.println();
11426            if (dumpAll) {
11427                pw.println("-------------------------------------------------------------------------------");
11428            }
11429            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11430            pw.println();
11431            if (dumpAll) {
11432                pw.println("-------------------------------------------------------------------------------");
11433            }
11434            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11435            pw.println();
11436            if (dumpAll) {
11437                pw.println("-------------------------------------------------------------------------------");
11438            }
11439            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11440        }
11441        Binder.restoreCallingIdentity(origId);
11442    }
11443
11444    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11445            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11446        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11447
11448        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11449                dumpPackage);
11450        boolean needSep = printedAnything;
11451
11452        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11453                dumpPackage, needSep, "  mFocusedActivity: ");
11454        if (printed) {
11455            printedAnything = true;
11456            needSep = false;
11457        }
11458
11459        if (dumpPackage == null) {
11460            if (needSep) {
11461                pw.println();
11462            }
11463            needSep = true;
11464            printedAnything = true;
11465            mStackSupervisor.dump(pw, "  ");
11466        }
11467
11468        if (mRecentTasks.size() > 0) {
11469            boolean printedHeader = false;
11470
11471            final int N = mRecentTasks.size();
11472            for (int i=0; i<N; i++) {
11473                TaskRecord tr = mRecentTasks.get(i);
11474                if (dumpPackage != null) {
11475                    if (tr.realActivity == null ||
11476                            !dumpPackage.equals(tr.realActivity)) {
11477                        continue;
11478                    }
11479                }
11480                if (!printedHeader) {
11481                    if (needSep) {
11482                        pw.println();
11483                    }
11484                    pw.println("  Recent tasks:");
11485                    printedHeader = true;
11486                    printedAnything = true;
11487                }
11488                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11489                        pw.println(tr);
11490                if (dumpAll) {
11491                    mRecentTasks.get(i).dump(pw, "    ");
11492                }
11493            }
11494        }
11495
11496        if (!printedAnything) {
11497            pw.println("  (nothing)");
11498        }
11499    }
11500
11501    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11502            int opti, boolean dumpAll, String dumpPackage) {
11503        boolean needSep = false;
11504        boolean printedAnything = false;
11505        int numPers = 0;
11506
11507        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11508
11509        if (dumpAll) {
11510            final int NP = mProcessNames.getMap().size();
11511            for (int ip=0; ip<NP; ip++) {
11512                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11513                final int NA = procs.size();
11514                for (int ia=0; ia<NA; ia++) {
11515                    ProcessRecord r = procs.valueAt(ia);
11516                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11517                        continue;
11518                    }
11519                    if (!needSep) {
11520                        pw.println("  All known processes:");
11521                        needSep = true;
11522                        printedAnything = true;
11523                    }
11524                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11525                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11526                        pw.print(" "); pw.println(r);
11527                    r.dump(pw, "    ");
11528                    if (r.persistent) {
11529                        numPers++;
11530                    }
11531                }
11532            }
11533        }
11534
11535        if (mIsolatedProcesses.size() > 0) {
11536            boolean printed = false;
11537            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11538                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11539                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11540                    continue;
11541                }
11542                if (!printed) {
11543                    if (needSep) {
11544                        pw.println();
11545                    }
11546                    pw.println("  Isolated process list (sorted by uid):");
11547                    printedAnything = true;
11548                    printed = true;
11549                    needSep = true;
11550                }
11551                pw.println(String.format("%sIsolated #%2d: %s",
11552                        "    ", i, r.toString()));
11553            }
11554        }
11555
11556        if (mLruProcesses.size() > 0) {
11557            if (needSep) {
11558                pw.println();
11559            }
11560            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11561                    pw.print(" total, non-act at ");
11562                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11563                    pw.print(", non-svc at ");
11564                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11565                    pw.println("):");
11566            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11567            needSep = true;
11568            printedAnything = true;
11569        }
11570
11571        if (dumpAll || dumpPackage != null) {
11572            synchronized (mPidsSelfLocked) {
11573                boolean printed = false;
11574                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11575                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11576                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11577                        continue;
11578                    }
11579                    if (!printed) {
11580                        if (needSep) pw.println();
11581                        needSep = true;
11582                        pw.println("  PID mappings:");
11583                        printed = true;
11584                        printedAnything = true;
11585                    }
11586                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11587                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11588                }
11589            }
11590        }
11591
11592        if (mForegroundProcesses.size() > 0) {
11593            synchronized (mPidsSelfLocked) {
11594                boolean printed = false;
11595                for (int i=0; i<mForegroundProcesses.size(); i++) {
11596                    ProcessRecord r = mPidsSelfLocked.get(
11597                            mForegroundProcesses.valueAt(i).pid);
11598                    if (dumpPackage != null && (r == null
11599                            || !r.pkgList.containsKey(dumpPackage))) {
11600                        continue;
11601                    }
11602                    if (!printed) {
11603                        if (needSep) pw.println();
11604                        needSep = true;
11605                        pw.println("  Foreground Processes:");
11606                        printed = true;
11607                        printedAnything = true;
11608                    }
11609                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11610                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11611                }
11612            }
11613        }
11614
11615        if (mPersistentStartingProcesses.size() > 0) {
11616            if (needSep) pw.println();
11617            needSep = true;
11618            printedAnything = true;
11619            pw.println("  Persisent processes that are starting:");
11620            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11621                    "Starting Norm", "Restarting PERS", dumpPackage);
11622        }
11623
11624        if (mRemovedProcesses.size() > 0) {
11625            if (needSep) pw.println();
11626            needSep = true;
11627            printedAnything = true;
11628            pw.println("  Processes that are being removed:");
11629            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11630                    "Removed Norm", "Removed PERS", dumpPackage);
11631        }
11632
11633        if (mProcessesOnHold.size() > 0) {
11634            if (needSep) pw.println();
11635            needSep = true;
11636            printedAnything = true;
11637            pw.println("  Processes that are on old until the system is ready:");
11638            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11639                    "OnHold Norm", "OnHold PERS", dumpPackage);
11640        }
11641
11642        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11643
11644        if (mProcessCrashTimes.getMap().size() > 0) {
11645            boolean printed = false;
11646            long now = SystemClock.uptimeMillis();
11647            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11648            final int NP = pmap.size();
11649            for (int ip=0; ip<NP; ip++) {
11650                String pname = pmap.keyAt(ip);
11651                SparseArray<Long> uids = pmap.valueAt(ip);
11652                final int N = uids.size();
11653                for (int i=0; i<N; i++) {
11654                    int puid = uids.keyAt(i);
11655                    ProcessRecord r = mProcessNames.get(pname, puid);
11656                    if (dumpPackage != null && (r == null
11657                            || !r.pkgList.containsKey(dumpPackage))) {
11658                        continue;
11659                    }
11660                    if (!printed) {
11661                        if (needSep) pw.println();
11662                        needSep = true;
11663                        pw.println("  Time since processes crashed:");
11664                        printed = true;
11665                        printedAnything = true;
11666                    }
11667                    pw.print("    Process "); pw.print(pname);
11668                            pw.print(" uid "); pw.print(puid);
11669                            pw.print(": last crashed ");
11670                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11671                            pw.println(" ago");
11672                }
11673            }
11674        }
11675
11676        if (mBadProcesses.getMap().size() > 0) {
11677            boolean printed = false;
11678            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11679            final int NP = pmap.size();
11680            for (int ip=0; ip<NP; ip++) {
11681                String pname = pmap.keyAt(ip);
11682                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11683                final int N = uids.size();
11684                for (int i=0; i<N; i++) {
11685                    int puid = uids.keyAt(i);
11686                    ProcessRecord r = mProcessNames.get(pname, puid);
11687                    if (dumpPackage != null && (r == null
11688                            || !r.pkgList.containsKey(dumpPackage))) {
11689                        continue;
11690                    }
11691                    if (!printed) {
11692                        if (needSep) pw.println();
11693                        needSep = true;
11694                        pw.println("  Bad processes:");
11695                        printedAnything = true;
11696                    }
11697                    BadProcessInfo info = uids.valueAt(i);
11698                    pw.print("    Bad process "); pw.print(pname);
11699                            pw.print(" uid "); pw.print(puid);
11700                            pw.print(": crashed at time "); pw.println(info.time);
11701                    if (info.shortMsg != null) {
11702                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11703                    }
11704                    if (info.longMsg != null) {
11705                        pw.print("      Long msg: "); pw.println(info.longMsg);
11706                    }
11707                    if (info.stack != null) {
11708                        pw.println("      Stack:");
11709                        int lastPos = 0;
11710                        for (int pos=0; pos<info.stack.length(); pos++) {
11711                            if (info.stack.charAt(pos) == '\n') {
11712                                pw.print("        ");
11713                                pw.write(info.stack, lastPos, pos-lastPos);
11714                                pw.println();
11715                                lastPos = pos+1;
11716                            }
11717                        }
11718                        if (lastPos < info.stack.length()) {
11719                            pw.print("        ");
11720                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11721                            pw.println();
11722                        }
11723                    }
11724                }
11725            }
11726        }
11727
11728        if (dumpPackage == null) {
11729            pw.println();
11730            needSep = false;
11731            pw.println("  mStartedUsers:");
11732            for (int i=0; i<mStartedUsers.size(); i++) {
11733                UserStartedState uss = mStartedUsers.valueAt(i);
11734                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11735                        pw.print(": "); uss.dump("", pw);
11736            }
11737            pw.print("  mStartedUserArray: [");
11738            for (int i=0; i<mStartedUserArray.length; i++) {
11739                if (i > 0) pw.print(", ");
11740                pw.print(mStartedUserArray[i]);
11741            }
11742            pw.println("]");
11743            pw.print("  mUserLru: [");
11744            for (int i=0; i<mUserLru.size(); i++) {
11745                if (i > 0) pw.print(", ");
11746                pw.print(mUserLru.get(i));
11747            }
11748            pw.println("]");
11749            if (dumpAll) {
11750                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11751            }
11752            synchronized (mUserProfileGroupIdsSelfLocked) {
11753                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11754                    pw.println("  mUserProfileGroupIds:");
11755                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11756                        pw.print("    User #");
11757                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11758                        pw.print(" -> profile #");
11759                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11760                    }
11761                }
11762            }
11763        }
11764        if (mHomeProcess != null && (dumpPackage == null
11765                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11766            if (needSep) {
11767                pw.println();
11768                needSep = false;
11769            }
11770            pw.println("  mHomeProcess: " + mHomeProcess);
11771        }
11772        if (mPreviousProcess != null && (dumpPackage == null
11773                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11774            if (needSep) {
11775                pw.println();
11776                needSep = false;
11777            }
11778            pw.println("  mPreviousProcess: " + mPreviousProcess);
11779        }
11780        if (dumpAll) {
11781            StringBuilder sb = new StringBuilder(128);
11782            sb.append("  mPreviousProcessVisibleTime: ");
11783            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11784            pw.println(sb);
11785        }
11786        if (mHeavyWeightProcess != null && (dumpPackage == null
11787                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11788            if (needSep) {
11789                pw.println();
11790                needSep = false;
11791            }
11792            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11793        }
11794        if (dumpPackage == null) {
11795            pw.println("  mConfiguration: " + mConfiguration);
11796        }
11797        if (dumpAll) {
11798            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11799            if (mCompatModePackages.getPackages().size() > 0) {
11800                boolean printed = false;
11801                for (Map.Entry<String, Integer> entry
11802                        : mCompatModePackages.getPackages().entrySet()) {
11803                    String pkg = entry.getKey();
11804                    int mode = entry.getValue();
11805                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11806                        continue;
11807                    }
11808                    if (!printed) {
11809                        pw.println("  mScreenCompatPackages:");
11810                        printed = true;
11811                    }
11812                    pw.print("    "); pw.print(pkg); pw.print(": ");
11813                            pw.print(mode); pw.println();
11814                }
11815            }
11816        }
11817        if (dumpPackage == null) {
11818            if (mSleeping || mWentToSleep || mLockScreenShown) {
11819                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11820                        + " mLockScreenShown " + mLockScreenShown);
11821            }
11822            if (mShuttingDown || mRunningVoice) {
11823                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11824            }
11825        }
11826        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11827                || mOrigWaitForDebugger) {
11828            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11829                    || dumpPackage.equals(mOrigDebugApp)) {
11830                if (needSep) {
11831                    pw.println();
11832                    needSep = false;
11833                }
11834                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11835                        + " mDebugTransient=" + mDebugTransient
11836                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11837            }
11838        }
11839        if (mOpenGlTraceApp != null) {
11840            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11841                if (needSep) {
11842                    pw.println();
11843                    needSep = false;
11844                }
11845                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11846            }
11847        }
11848        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11849                || mProfileFd != null) {
11850            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11851                if (needSep) {
11852                    pw.println();
11853                    needSep = false;
11854                }
11855                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11856                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11857                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11858                        + mAutoStopProfiler);
11859            }
11860        }
11861        if (dumpPackage == null) {
11862            if (mAlwaysFinishActivities || mController != null) {
11863                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11864                        + " mController=" + mController);
11865            }
11866            if (dumpAll) {
11867                pw.println("  Total persistent processes: " + numPers);
11868                pw.println("  mProcessesReady=" + mProcessesReady
11869                        + " mSystemReady=" + mSystemReady);
11870                pw.println("  mBooting=" + mBooting
11871                        + " mBooted=" + mBooted
11872                        + " mFactoryTest=" + mFactoryTest);
11873                pw.print("  mLastPowerCheckRealtime=");
11874                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11875                        pw.println("");
11876                pw.print("  mLastPowerCheckUptime=");
11877                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11878                        pw.println("");
11879                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11880                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11881                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11882                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11883                        + " (" + mLruProcesses.size() + " total)"
11884                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11885                        + " mNumServiceProcs=" + mNumServiceProcs
11886                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11887                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11888                        + " mLastMemoryLevel" + mLastMemoryLevel
11889                        + " mLastNumProcesses" + mLastNumProcesses);
11890                long now = SystemClock.uptimeMillis();
11891                pw.print("  mLastIdleTime=");
11892                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11893                        pw.print(" mLowRamSinceLastIdle=");
11894                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11895                        pw.println();
11896            }
11897        }
11898
11899        if (!printedAnything) {
11900            pw.println("  (nothing)");
11901        }
11902    }
11903
11904    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11905            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11906        if (mProcessesToGc.size() > 0) {
11907            boolean printed = false;
11908            long now = SystemClock.uptimeMillis();
11909            for (int i=0; i<mProcessesToGc.size(); i++) {
11910                ProcessRecord proc = mProcessesToGc.get(i);
11911                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11912                    continue;
11913                }
11914                if (!printed) {
11915                    if (needSep) pw.println();
11916                    needSep = true;
11917                    pw.println("  Processes that are waiting to GC:");
11918                    printed = true;
11919                }
11920                pw.print("    Process "); pw.println(proc);
11921                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11922                        pw.print(", last gced=");
11923                        pw.print(now-proc.lastRequestedGc);
11924                        pw.print(" ms ago, last lowMem=");
11925                        pw.print(now-proc.lastLowMemory);
11926                        pw.println(" ms ago");
11927
11928            }
11929        }
11930        return needSep;
11931    }
11932
11933    void printOomLevel(PrintWriter pw, String name, int adj) {
11934        pw.print("    ");
11935        if (adj >= 0) {
11936            pw.print(' ');
11937            if (adj < 10) pw.print(' ');
11938        } else {
11939            if (adj > -10) pw.print(' ');
11940        }
11941        pw.print(adj);
11942        pw.print(": ");
11943        pw.print(name);
11944        pw.print(" (");
11945        pw.print(mProcessList.getMemLevel(adj)/1024);
11946        pw.println(" kB)");
11947    }
11948
11949    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11950            int opti, boolean dumpAll) {
11951        boolean needSep = false;
11952
11953        if (mLruProcesses.size() > 0) {
11954            if (needSep) pw.println();
11955            needSep = true;
11956            pw.println("  OOM levels:");
11957            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11958            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11959            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11960            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11961            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11962            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11963            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11964            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11965            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11966            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11967            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11968            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11969            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11970
11971            if (needSep) pw.println();
11972            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11973                    pw.print(" total, non-act at ");
11974                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11975                    pw.print(", non-svc at ");
11976                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11977                    pw.println("):");
11978            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11979            needSep = true;
11980        }
11981
11982        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11983
11984        pw.println();
11985        pw.println("  mHomeProcess: " + mHomeProcess);
11986        pw.println("  mPreviousProcess: " + mPreviousProcess);
11987        if (mHeavyWeightProcess != null) {
11988            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11989        }
11990
11991        return true;
11992    }
11993
11994    /**
11995     * There are three ways to call this:
11996     *  - no provider specified: dump all the providers
11997     *  - a flattened component name that matched an existing provider was specified as the
11998     *    first arg: dump that one provider
11999     *  - the first arg isn't the flattened component name of an existing provider:
12000     *    dump all providers whose component contains the first arg as a substring
12001     */
12002    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12003            int opti, boolean dumpAll) {
12004        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12005    }
12006
12007    static class ItemMatcher {
12008        ArrayList<ComponentName> components;
12009        ArrayList<String> strings;
12010        ArrayList<Integer> objects;
12011        boolean all;
12012
12013        ItemMatcher() {
12014            all = true;
12015        }
12016
12017        void build(String name) {
12018            ComponentName componentName = ComponentName.unflattenFromString(name);
12019            if (componentName != null) {
12020                if (components == null) {
12021                    components = new ArrayList<ComponentName>();
12022                }
12023                components.add(componentName);
12024                all = false;
12025            } else {
12026                int objectId = 0;
12027                // Not a '/' separated full component name; maybe an object ID?
12028                try {
12029                    objectId = Integer.parseInt(name, 16);
12030                    if (objects == null) {
12031                        objects = new ArrayList<Integer>();
12032                    }
12033                    objects.add(objectId);
12034                    all = false;
12035                } catch (RuntimeException e) {
12036                    // Not an integer; just do string match.
12037                    if (strings == null) {
12038                        strings = new ArrayList<String>();
12039                    }
12040                    strings.add(name);
12041                    all = false;
12042                }
12043            }
12044        }
12045
12046        int build(String[] args, int opti) {
12047            for (; opti<args.length; opti++) {
12048                String name = args[opti];
12049                if ("--".equals(name)) {
12050                    return opti+1;
12051                }
12052                build(name);
12053            }
12054            return opti;
12055        }
12056
12057        boolean match(Object object, ComponentName comp) {
12058            if (all) {
12059                return true;
12060            }
12061            if (components != null) {
12062                for (int i=0; i<components.size(); i++) {
12063                    if (components.get(i).equals(comp)) {
12064                        return true;
12065                    }
12066                }
12067            }
12068            if (objects != null) {
12069                for (int i=0; i<objects.size(); i++) {
12070                    if (System.identityHashCode(object) == objects.get(i)) {
12071                        return true;
12072                    }
12073                }
12074            }
12075            if (strings != null) {
12076                String flat = comp.flattenToString();
12077                for (int i=0; i<strings.size(); i++) {
12078                    if (flat.contains(strings.get(i))) {
12079                        return true;
12080                    }
12081                }
12082            }
12083            return false;
12084        }
12085    }
12086
12087    /**
12088     * There are three things that cmd can be:
12089     *  - a flattened component name that matches an existing activity
12090     *  - the cmd arg isn't the flattened component name of an existing activity:
12091     *    dump all activity whose component contains the cmd as a substring
12092     *  - A hex number of the ActivityRecord object instance.
12093     */
12094    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12095            int opti, boolean dumpAll) {
12096        ArrayList<ActivityRecord> activities;
12097
12098        synchronized (this) {
12099            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12100        }
12101
12102        if (activities.size() <= 0) {
12103            return false;
12104        }
12105
12106        String[] newArgs = new String[args.length - opti];
12107        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12108
12109        TaskRecord lastTask = null;
12110        boolean needSep = false;
12111        for (int i=activities.size()-1; i>=0; i--) {
12112            ActivityRecord r = activities.get(i);
12113            if (needSep) {
12114                pw.println();
12115            }
12116            needSep = true;
12117            synchronized (this) {
12118                if (lastTask != r.task) {
12119                    lastTask = r.task;
12120                    pw.print("TASK "); pw.print(lastTask.affinity);
12121                            pw.print(" id="); pw.println(lastTask.taskId);
12122                    if (dumpAll) {
12123                        lastTask.dump(pw, "  ");
12124                    }
12125                }
12126            }
12127            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12128        }
12129        return true;
12130    }
12131
12132    /**
12133     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12134     * there is a thread associated with the activity.
12135     */
12136    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12137            final ActivityRecord r, String[] args, boolean dumpAll) {
12138        String innerPrefix = prefix + "  ";
12139        synchronized (this) {
12140            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12141                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12142                    pw.print(" pid=");
12143                    if (r.app != null) pw.println(r.app.pid);
12144                    else pw.println("(not running)");
12145            if (dumpAll) {
12146                r.dump(pw, innerPrefix);
12147            }
12148        }
12149        if (r.app != null && r.app.thread != null) {
12150            // flush anything that is already in the PrintWriter since the thread is going
12151            // to write to the file descriptor directly
12152            pw.flush();
12153            try {
12154                TransferPipe tp = new TransferPipe();
12155                try {
12156                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12157                            r.appToken, innerPrefix, args);
12158                    tp.go(fd);
12159                } finally {
12160                    tp.kill();
12161                }
12162            } catch (IOException e) {
12163                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12164            } catch (RemoteException e) {
12165                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12166            }
12167        }
12168    }
12169
12170    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12171            int opti, boolean dumpAll, String dumpPackage) {
12172        boolean needSep = false;
12173        boolean onlyHistory = false;
12174        boolean printedAnything = false;
12175
12176        if ("history".equals(dumpPackage)) {
12177            if (opti < args.length && "-s".equals(args[opti])) {
12178                dumpAll = false;
12179            }
12180            onlyHistory = true;
12181            dumpPackage = null;
12182        }
12183
12184        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12185        if (!onlyHistory && dumpAll) {
12186            if (mRegisteredReceivers.size() > 0) {
12187                boolean printed = false;
12188                Iterator it = mRegisteredReceivers.values().iterator();
12189                while (it.hasNext()) {
12190                    ReceiverList r = (ReceiverList)it.next();
12191                    if (dumpPackage != null && (r.app == null ||
12192                            !dumpPackage.equals(r.app.info.packageName))) {
12193                        continue;
12194                    }
12195                    if (!printed) {
12196                        pw.println("  Registered Receivers:");
12197                        needSep = true;
12198                        printed = true;
12199                        printedAnything = true;
12200                    }
12201                    pw.print("  * "); pw.println(r);
12202                    r.dump(pw, "    ");
12203                }
12204            }
12205
12206            if (mReceiverResolver.dump(pw, needSep ?
12207                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12208                    "    ", dumpPackage, false)) {
12209                needSep = true;
12210                printedAnything = true;
12211            }
12212        }
12213
12214        for (BroadcastQueue q : mBroadcastQueues) {
12215            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12216            printedAnything |= needSep;
12217        }
12218
12219        needSep = true;
12220
12221        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12222            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12223                if (needSep) {
12224                    pw.println();
12225                }
12226                needSep = true;
12227                printedAnything = true;
12228                pw.print("  Sticky broadcasts for user ");
12229                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12230                StringBuilder sb = new StringBuilder(128);
12231                for (Map.Entry<String, ArrayList<Intent>> ent
12232                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12233                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12234                    if (dumpAll) {
12235                        pw.println(":");
12236                        ArrayList<Intent> intents = ent.getValue();
12237                        final int N = intents.size();
12238                        for (int i=0; i<N; i++) {
12239                            sb.setLength(0);
12240                            sb.append("    Intent: ");
12241                            intents.get(i).toShortString(sb, false, true, false, false);
12242                            pw.println(sb.toString());
12243                            Bundle bundle = intents.get(i).getExtras();
12244                            if (bundle != null) {
12245                                pw.print("      ");
12246                                pw.println(bundle.toString());
12247                            }
12248                        }
12249                    } else {
12250                        pw.println("");
12251                    }
12252                }
12253            }
12254        }
12255
12256        if (!onlyHistory && dumpAll) {
12257            pw.println();
12258            for (BroadcastQueue queue : mBroadcastQueues) {
12259                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12260                        + queue.mBroadcastsScheduled);
12261            }
12262            pw.println("  mHandler:");
12263            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12264            needSep = true;
12265            printedAnything = true;
12266        }
12267
12268        if (!printedAnything) {
12269            pw.println("  (nothing)");
12270        }
12271    }
12272
12273    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12274            int opti, boolean dumpAll, String dumpPackage) {
12275        boolean needSep;
12276        boolean printedAnything = false;
12277
12278        ItemMatcher matcher = new ItemMatcher();
12279        matcher.build(args, opti);
12280
12281        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12282
12283        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12284        printedAnything |= needSep;
12285
12286        if (mLaunchingProviders.size() > 0) {
12287            boolean printed = false;
12288            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12289                ContentProviderRecord r = mLaunchingProviders.get(i);
12290                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12291                    continue;
12292                }
12293                if (!printed) {
12294                    if (needSep) pw.println();
12295                    needSep = true;
12296                    pw.println("  Launching content providers:");
12297                    printed = true;
12298                    printedAnything = true;
12299                }
12300                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12301                        pw.println(r);
12302            }
12303        }
12304
12305        if (mGrantedUriPermissions.size() > 0) {
12306            boolean printed = false;
12307            int dumpUid = -2;
12308            if (dumpPackage != null) {
12309                try {
12310                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12311                } catch (NameNotFoundException e) {
12312                    dumpUid = -1;
12313                }
12314            }
12315            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12316                int uid = mGrantedUriPermissions.keyAt(i);
12317                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12318                    continue;
12319                }
12320                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12321                if (!printed) {
12322                    if (needSep) pw.println();
12323                    needSep = true;
12324                    pw.println("  Granted Uri Permissions:");
12325                    printed = true;
12326                    printedAnything = true;
12327                }
12328                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12329                for (UriPermission perm : perms.values()) {
12330                    pw.print("    "); pw.println(perm);
12331                    if (dumpAll) {
12332                        perm.dump(pw, "      ");
12333                    }
12334                }
12335            }
12336        }
12337
12338        if (!printedAnything) {
12339            pw.println("  (nothing)");
12340        }
12341    }
12342
12343    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12344            int opti, boolean dumpAll, String dumpPackage) {
12345        boolean printed = false;
12346
12347        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12348
12349        if (mIntentSenderRecords.size() > 0) {
12350            Iterator<WeakReference<PendingIntentRecord>> it
12351                    = mIntentSenderRecords.values().iterator();
12352            while (it.hasNext()) {
12353                WeakReference<PendingIntentRecord> ref = it.next();
12354                PendingIntentRecord rec = ref != null ? ref.get(): null;
12355                if (dumpPackage != null && (rec == null
12356                        || !dumpPackage.equals(rec.key.packageName))) {
12357                    continue;
12358                }
12359                printed = true;
12360                if (rec != null) {
12361                    pw.print("  * "); pw.println(rec);
12362                    if (dumpAll) {
12363                        rec.dump(pw, "    ");
12364                    }
12365                } else {
12366                    pw.print("  * "); pw.println(ref);
12367                }
12368            }
12369        }
12370
12371        if (!printed) {
12372            pw.println("  (nothing)");
12373        }
12374    }
12375
12376    private static final int dumpProcessList(PrintWriter pw,
12377            ActivityManagerService service, List list,
12378            String prefix, String normalLabel, String persistentLabel,
12379            String dumpPackage) {
12380        int numPers = 0;
12381        final int N = list.size()-1;
12382        for (int i=N; i>=0; i--) {
12383            ProcessRecord r = (ProcessRecord)list.get(i);
12384            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12385                continue;
12386            }
12387            pw.println(String.format("%s%s #%2d: %s",
12388                    prefix, (r.persistent ? persistentLabel : normalLabel),
12389                    i, r.toString()));
12390            if (r.persistent) {
12391                numPers++;
12392            }
12393        }
12394        return numPers;
12395    }
12396
12397    private static final boolean dumpProcessOomList(PrintWriter pw,
12398            ActivityManagerService service, List<ProcessRecord> origList,
12399            String prefix, String normalLabel, String persistentLabel,
12400            boolean inclDetails, String dumpPackage) {
12401
12402        ArrayList<Pair<ProcessRecord, Integer>> list
12403                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12404        for (int i=0; i<origList.size(); i++) {
12405            ProcessRecord r = origList.get(i);
12406            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12407                continue;
12408            }
12409            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12410        }
12411
12412        if (list.size() <= 0) {
12413            return false;
12414        }
12415
12416        Comparator<Pair<ProcessRecord, Integer>> comparator
12417                = new Comparator<Pair<ProcessRecord, Integer>>() {
12418            @Override
12419            public int compare(Pair<ProcessRecord, Integer> object1,
12420                    Pair<ProcessRecord, Integer> object2) {
12421                if (object1.first.setAdj != object2.first.setAdj) {
12422                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12423                }
12424                if (object1.second.intValue() != object2.second.intValue()) {
12425                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12426                }
12427                return 0;
12428            }
12429        };
12430
12431        Collections.sort(list, comparator);
12432
12433        final long curRealtime = SystemClock.elapsedRealtime();
12434        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12435        final long curUptime = SystemClock.uptimeMillis();
12436        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12437
12438        for (int i=list.size()-1; i>=0; i--) {
12439            ProcessRecord r = list.get(i).first;
12440            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12441            char schedGroup;
12442            switch (r.setSchedGroup) {
12443                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12444                    schedGroup = 'B';
12445                    break;
12446                case Process.THREAD_GROUP_DEFAULT:
12447                    schedGroup = 'F';
12448                    break;
12449                default:
12450                    schedGroup = '?';
12451                    break;
12452            }
12453            char foreground;
12454            if (r.foregroundActivities) {
12455                foreground = 'A';
12456            } else if (r.foregroundServices) {
12457                foreground = 'S';
12458            } else {
12459                foreground = ' ';
12460            }
12461            String procState = ProcessList.makeProcStateString(r.curProcState);
12462            pw.print(prefix);
12463            pw.print(r.persistent ? persistentLabel : normalLabel);
12464            pw.print(" #");
12465            int num = (origList.size()-1)-list.get(i).second;
12466            if (num < 10) pw.print(' ');
12467            pw.print(num);
12468            pw.print(": ");
12469            pw.print(oomAdj);
12470            pw.print(' ');
12471            pw.print(schedGroup);
12472            pw.print('/');
12473            pw.print(foreground);
12474            pw.print('/');
12475            pw.print(procState);
12476            pw.print(" trm:");
12477            if (r.trimMemoryLevel < 10) pw.print(' ');
12478            pw.print(r.trimMemoryLevel);
12479            pw.print(' ');
12480            pw.print(r.toShortString());
12481            pw.print(" (");
12482            pw.print(r.adjType);
12483            pw.println(')');
12484            if (r.adjSource != null || r.adjTarget != null) {
12485                pw.print(prefix);
12486                pw.print("    ");
12487                if (r.adjTarget instanceof ComponentName) {
12488                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12489                } else if (r.adjTarget != null) {
12490                    pw.print(r.adjTarget.toString());
12491                } else {
12492                    pw.print("{null}");
12493                }
12494                pw.print("<=");
12495                if (r.adjSource instanceof ProcessRecord) {
12496                    pw.print("Proc{");
12497                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12498                    pw.println("}");
12499                } else if (r.adjSource != null) {
12500                    pw.println(r.adjSource.toString());
12501                } else {
12502                    pw.println("{null}");
12503                }
12504            }
12505            if (inclDetails) {
12506                pw.print(prefix);
12507                pw.print("    ");
12508                pw.print("oom: max="); pw.print(r.maxAdj);
12509                pw.print(" curRaw="); pw.print(r.curRawAdj);
12510                pw.print(" setRaw="); pw.print(r.setRawAdj);
12511                pw.print(" cur="); pw.print(r.curAdj);
12512                pw.print(" set="); pw.println(r.setAdj);
12513                pw.print(prefix);
12514                pw.print("    ");
12515                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12516                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12517                pw.print(" lastPss="); pw.print(r.lastPss);
12518                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12519                pw.print(prefix);
12520                pw.print("    ");
12521                pw.print("cached="); pw.print(r.cached);
12522                pw.print(" empty="); pw.print(r.empty);
12523                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12524
12525                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12526                    if (r.lastWakeTime != 0) {
12527                        long wtime;
12528                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12529                        synchronized (stats) {
12530                            wtime = stats.getProcessWakeTime(r.info.uid,
12531                                    r.pid, curRealtime);
12532                        }
12533                        long timeUsed = wtime - r.lastWakeTime;
12534                        pw.print(prefix);
12535                        pw.print("    ");
12536                        pw.print("keep awake over ");
12537                        TimeUtils.formatDuration(realtimeSince, pw);
12538                        pw.print(" used ");
12539                        TimeUtils.formatDuration(timeUsed, pw);
12540                        pw.print(" (");
12541                        pw.print((timeUsed*100)/realtimeSince);
12542                        pw.println("%)");
12543                    }
12544                    if (r.lastCpuTime != 0) {
12545                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12546                        pw.print(prefix);
12547                        pw.print("    ");
12548                        pw.print("run cpu over ");
12549                        TimeUtils.formatDuration(uptimeSince, pw);
12550                        pw.print(" used ");
12551                        TimeUtils.formatDuration(timeUsed, pw);
12552                        pw.print(" (");
12553                        pw.print((timeUsed*100)/uptimeSince);
12554                        pw.println("%)");
12555                    }
12556                }
12557            }
12558        }
12559        return true;
12560    }
12561
12562    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12563        ArrayList<ProcessRecord> procs;
12564        synchronized (this) {
12565            if (args != null && args.length > start
12566                    && args[start].charAt(0) != '-') {
12567                procs = new ArrayList<ProcessRecord>();
12568                int pid = -1;
12569                try {
12570                    pid = Integer.parseInt(args[start]);
12571                } catch (NumberFormatException e) {
12572                }
12573                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12574                    ProcessRecord proc = mLruProcesses.get(i);
12575                    if (proc.pid == pid) {
12576                        procs.add(proc);
12577                    } else if (proc.processName.equals(args[start])) {
12578                        procs.add(proc);
12579                    }
12580                }
12581                if (procs.size() <= 0) {
12582                    return null;
12583                }
12584            } else {
12585                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12586            }
12587        }
12588        return procs;
12589    }
12590
12591    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12592            PrintWriter pw, String[] args) {
12593        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12594        if (procs == null) {
12595            pw.println("No process found for: " + args[0]);
12596            return;
12597        }
12598
12599        long uptime = SystemClock.uptimeMillis();
12600        long realtime = SystemClock.elapsedRealtime();
12601        pw.println("Applications Graphics Acceleration Info:");
12602        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12603
12604        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12605            ProcessRecord r = procs.get(i);
12606            if (r.thread != null) {
12607                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12608                pw.flush();
12609                try {
12610                    TransferPipe tp = new TransferPipe();
12611                    try {
12612                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12613                        tp.go(fd);
12614                    } finally {
12615                        tp.kill();
12616                    }
12617                } catch (IOException e) {
12618                    pw.println("Failure while dumping the app: " + r);
12619                    pw.flush();
12620                } catch (RemoteException e) {
12621                    pw.println("Got a RemoteException while dumping the app " + r);
12622                    pw.flush();
12623                }
12624            }
12625        }
12626    }
12627
12628    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12629        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12630        if (procs == null) {
12631            pw.println("No process found for: " + args[0]);
12632            return;
12633        }
12634
12635        pw.println("Applications Database Info:");
12636
12637        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12638            ProcessRecord r = procs.get(i);
12639            if (r.thread != null) {
12640                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12641                pw.flush();
12642                try {
12643                    TransferPipe tp = new TransferPipe();
12644                    try {
12645                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12646                        tp.go(fd);
12647                    } finally {
12648                        tp.kill();
12649                    }
12650                } catch (IOException e) {
12651                    pw.println("Failure while dumping the app: " + r);
12652                    pw.flush();
12653                } catch (RemoteException e) {
12654                    pw.println("Got a RemoteException while dumping the app " + r);
12655                    pw.flush();
12656                }
12657            }
12658        }
12659    }
12660
12661    final static class MemItem {
12662        final boolean isProc;
12663        final String label;
12664        final String shortLabel;
12665        final long pss;
12666        final int id;
12667        final boolean hasActivities;
12668        ArrayList<MemItem> subitems;
12669
12670        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12671                boolean _hasActivities) {
12672            isProc = true;
12673            label = _label;
12674            shortLabel = _shortLabel;
12675            pss = _pss;
12676            id = _id;
12677            hasActivities = _hasActivities;
12678        }
12679
12680        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12681            isProc = false;
12682            label = _label;
12683            shortLabel = _shortLabel;
12684            pss = _pss;
12685            id = _id;
12686            hasActivities = false;
12687        }
12688    }
12689
12690    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12691            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12692        if (sort && !isCompact) {
12693            Collections.sort(items, new Comparator<MemItem>() {
12694                @Override
12695                public int compare(MemItem lhs, MemItem rhs) {
12696                    if (lhs.pss < rhs.pss) {
12697                        return 1;
12698                    } else if (lhs.pss > rhs.pss) {
12699                        return -1;
12700                    }
12701                    return 0;
12702                }
12703            });
12704        }
12705
12706        for (int i=0; i<items.size(); i++) {
12707            MemItem mi = items.get(i);
12708            if (!isCompact) {
12709                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12710            } else if (mi.isProc) {
12711                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12712                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12713                pw.println(mi.hasActivities ? ",a" : ",e");
12714            } else {
12715                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12716                pw.println(mi.pss);
12717            }
12718            if (mi.subitems != null) {
12719                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12720                        true, isCompact);
12721            }
12722        }
12723    }
12724
12725    // These are in KB.
12726    static final long[] DUMP_MEM_BUCKETS = new long[] {
12727        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12728        120*1024, 160*1024, 200*1024,
12729        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12730        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12731    };
12732
12733    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12734            boolean stackLike) {
12735        int start = label.lastIndexOf('.');
12736        if (start >= 0) start++;
12737        else start = 0;
12738        int end = label.length();
12739        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12740            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12741                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12742                out.append(bucket);
12743                out.append(stackLike ? "MB." : "MB ");
12744                out.append(label, start, end);
12745                return;
12746            }
12747        }
12748        out.append(memKB/1024);
12749        out.append(stackLike ? "MB." : "MB ");
12750        out.append(label, start, end);
12751    }
12752
12753    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12754            ProcessList.NATIVE_ADJ,
12755            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12756            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12757            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12758            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12759            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12760    };
12761    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12762            "Native",
12763            "System", "Persistent", "Foreground",
12764            "Visible", "Perceptible",
12765            "Heavy Weight", "Backup",
12766            "A Services", "Home",
12767            "Previous", "B Services", "Cached"
12768    };
12769    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12770            "native",
12771            "sys", "pers", "fore",
12772            "vis", "percept",
12773            "heavy", "backup",
12774            "servicea", "home",
12775            "prev", "serviceb", "cached"
12776    };
12777
12778    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12779            long realtime, boolean isCheckinRequest, boolean isCompact) {
12780        if (isCheckinRequest || isCompact) {
12781            // short checkin version
12782            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12783        } else {
12784            pw.println("Applications Memory Usage (kB):");
12785            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12786        }
12787    }
12788
12789    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12790            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12791        boolean dumpDetails = false;
12792        boolean dumpFullDetails = false;
12793        boolean dumpDalvik = false;
12794        boolean oomOnly = false;
12795        boolean isCompact = false;
12796        boolean localOnly = false;
12797
12798        int opti = 0;
12799        while (opti < args.length) {
12800            String opt = args[opti];
12801            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12802                break;
12803            }
12804            opti++;
12805            if ("-a".equals(opt)) {
12806                dumpDetails = true;
12807                dumpFullDetails = true;
12808                dumpDalvik = true;
12809            } else if ("-d".equals(opt)) {
12810                dumpDalvik = true;
12811            } else if ("-c".equals(opt)) {
12812                isCompact = true;
12813            } else if ("--oom".equals(opt)) {
12814                oomOnly = true;
12815            } else if ("--local".equals(opt)) {
12816                localOnly = true;
12817            } else if ("-h".equals(opt)) {
12818                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12819                pw.println("  -a: include all available information for each process.");
12820                pw.println("  -d: include dalvik details when dumping process details.");
12821                pw.println("  -c: dump in a compact machine-parseable representation.");
12822                pw.println("  --oom: only show processes organized by oom adj.");
12823                pw.println("  --local: only collect details locally, don't call process.");
12824                pw.println("If [process] is specified it can be the name or ");
12825                pw.println("pid of a specific process to dump.");
12826                return;
12827            } else {
12828                pw.println("Unknown argument: " + opt + "; use -h for help");
12829            }
12830        }
12831
12832        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12833        long uptime = SystemClock.uptimeMillis();
12834        long realtime = SystemClock.elapsedRealtime();
12835        final long[] tmpLong = new long[1];
12836
12837        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12838        if (procs == null) {
12839            // No Java processes.  Maybe they want to print a native process.
12840            if (args != null && args.length > opti
12841                    && args[opti].charAt(0) != '-') {
12842                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12843                        = new ArrayList<ProcessCpuTracker.Stats>();
12844                updateCpuStatsNow();
12845                int findPid = -1;
12846                try {
12847                    findPid = Integer.parseInt(args[opti]);
12848                } catch (NumberFormatException e) {
12849                }
12850                synchronized (mProcessCpuThread) {
12851                    final int N = mProcessCpuTracker.countStats();
12852                    for (int i=0; i<N; i++) {
12853                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12854                        if (st.pid == findPid || (st.baseName != null
12855                                && st.baseName.equals(args[opti]))) {
12856                            nativeProcs.add(st);
12857                        }
12858                    }
12859                }
12860                if (nativeProcs.size() > 0) {
12861                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12862                            isCompact);
12863                    Debug.MemoryInfo mi = null;
12864                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12865                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12866                        final int pid = r.pid;
12867                        if (!isCheckinRequest && dumpDetails) {
12868                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12869                        }
12870                        if (mi == null) {
12871                            mi = new Debug.MemoryInfo();
12872                        }
12873                        if (dumpDetails || (!brief && !oomOnly)) {
12874                            Debug.getMemoryInfo(pid, mi);
12875                        } else {
12876                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12877                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12878                        }
12879                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12880                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12881                        if (isCheckinRequest) {
12882                            pw.println();
12883                        }
12884                    }
12885                    return;
12886                }
12887            }
12888            pw.println("No process found for: " + args[opti]);
12889            return;
12890        }
12891
12892        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12893            dumpDetails = true;
12894        }
12895
12896        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12897
12898        String[] innerArgs = new String[args.length-opti];
12899        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12900
12901        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12902        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12903        long nativePss=0, dalvikPss=0, otherPss=0;
12904        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12905
12906        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12907        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12908                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12909
12910        long totalPss = 0;
12911        long cachedPss = 0;
12912
12913        Debug.MemoryInfo mi = null;
12914        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12915            final ProcessRecord r = procs.get(i);
12916            final IApplicationThread thread;
12917            final int pid;
12918            final int oomAdj;
12919            final boolean hasActivities;
12920            synchronized (this) {
12921                thread = r.thread;
12922                pid = r.pid;
12923                oomAdj = r.getSetAdjWithServices();
12924                hasActivities = r.activities.size() > 0;
12925            }
12926            if (thread != null) {
12927                if (!isCheckinRequest && dumpDetails) {
12928                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12929                }
12930                if (mi == null) {
12931                    mi = new Debug.MemoryInfo();
12932                }
12933                if (dumpDetails || (!brief && !oomOnly)) {
12934                    Debug.getMemoryInfo(pid, mi);
12935                } else {
12936                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12937                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12938                }
12939                if (dumpDetails) {
12940                    if (localOnly) {
12941                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12942                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12943                        if (isCheckinRequest) {
12944                            pw.println();
12945                        }
12946                    } else {
12947                        try {
12948                            pw.flush();
12949                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12950                                    dumpDalvik, innerArgs);
12951                        } catch (RemoteException e) {
12952                            if (!isCheckinRequest) {
12953                                pw.println("Got RemoteException!");
12954                                pw.flush();
12955                            }
12956                        }
12957                    }
12958                }
12959
12960                final long myTotalPss = mi.getTotalPss();
12961                final long myTotalUss = mi.getTotalUss();
12962
12963                synchronized (this) {
12964                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12965                        // Record this for posterity if the process has been stable.
12966                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12967                    }
12968                }
12969
12970                if (!isCheckinRequest && mi != null) {
12971                    totalPss += myTotalPss;
12972                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12973                            (hasActivities ? " / activities)" : ")"),
12974                            r.processName, myTotalPss, pid, hasActivities);
12975                    procMems.add(pssItem);
12976                    procMemsMap.put(pid, pssItem);
12977
12978                    nativePss += mi.nativePss;
12979                    dalvikPss += mi.dalvikPss;
12980                    otherPss += mi.otherPss;
12981                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12982                        long mem = mi.getOtherPss(j);
12983                        miscPss[j] += mem;
12984                        otherPss -= mem;
12985                    }
12986
12987                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12988                        cachedPss += myTotalPss;
12989                    }
12990
12991                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12992                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12993                                || oomIndex == (oomPss.length-1)) {
12994                            oomPss[oomIndex] += myTotalPss;
12995                            if (oomProcs[oomIndex] == null) {
12996                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12997                            }
12998                            oomProcs[oomIndex].add(pssItem);
12999                            break;
13000                        }
13001                    }
13002                }
13003            }
13004        }
13005
13006        long nativeProcTotalPss = 0;
13007
13008        if (!isCheckinRequest && procs.size() > 1) {
13009            // If we are showing aggregations, also look for native processes to
13010            // include so that our aggregations are more accurate.
13011            updateCpuStatsNow();
13012            synchronized (mProcessCpuThread) {
13013                final int N = mProcessCpuTracker.countStats();
13014                for (int i=0; i<N; i++) {
13015                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13016                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13017                        if (mi == null) {
13018                            mi = new Debug.MemoryInfo();
13019                        }
13020                        if (!brief && !oomOnly) {
13021                            Debug.getMemoryInfo(st.pid, mi);
13022                        } else {
13023                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13024                            mi.nativePrivateDirty = (int)tmpLong[0];
13025                        }
13026
13027                        final long myTotalPss = mi.getTotalPss();
13028                        totalPss += myTotalPss;
13029                        nativeProcTotalPss += myTotalPss;
13030
13031                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13032                                st.name, myTotalPss, st.pid, false);
13033                        procMems.add(pssItem);
13034
13035                        nativePss += mi.nativePss;
13036                        dalvikPss += mi.dalvikPss;
13037                        otherPss += mi.otherPss;
13038                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13039                            long mem = mi.getOtherPss(j);
13040                            miscPss[j] += mem;
13041                            otherPss -= mem;
13042                        }
13043                        oomPss[0] += myTotalPss;
13044                        if (oomProcs[0] == null) {
13045                            oomProcs[0] = new ArrayList<MemItem>();
13046                        }
13047                        oomProcs[0].add(pssItem);
13048                    }
13049                }
13050            }
13051
13052            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13053
13054            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13055            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13056            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13057            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13058                String label = Debug.MemoryInfo.getOtherLabel(j);
13059                catMems.add(new MemItem(label, label, miscPss[j], j));
13060            }
13061
13062            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13063            for (int j=0; j<oomPss.length; j++) {
13064                if (oomPss[j] != 0) {
13065                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13066                            : DUMP_MEM_OOM_LABEL[j];
13067                    MemItem item = new MemItem(label, label, oomPss[j],
13068                            DUMP_MEM_OOM_ADJ[j]);
13069                    item.subitems = oomProcs[j];
13070                    oomMems.add(item);
13071                }
13072            }
13073
13074            if (!brief && !oomOnly && !isCompact) {
13075                pw.println();
13076                pw.println("Total PSS by process:");
13077                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13078                pw.println();
13079            }
13080            if (!isCompact) {
13081                pw.println("Total PSS by OOM adjustment:");
13082            }
13083            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13084            if (!brief && !oomOnly) {
13085                PrintWriter out = categoryPw != null ? categoryPw : pw;
13086                if (!isCompact) {
13087                    out.println();
13088                    out.println("Total PSS by category:");
13089                }
13090                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13091            }
13092            if (!isCompact) {
13093                pw.println();
13094            }
13095            MemInfoReader memInfo = new MemInfoReader();
13096            memInfo.readMemInfo();
13097            if (nativeProcTotalPss > 0) {
13098                synchronized (this) {
13099                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13100                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13101                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13102                            nativeProcTotalPss);
13103                }
13104            }
13105            if (!brief) {
13106                if (!isCompact) {
13107                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13108                    pw.print(" kB (status ");
13109                    switch (mLastMemoryLevel) {
13110                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13111                            pw.println("normal)");
13112                            break;
13113                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13114                            pw.println("moderate)");
13115                            break;
13116                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13117                            pw.println("low)");
13118                            break;
13119                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13120                            pw.println("critical)");
13121                            break;
13122                        default:
13123                            pw.print(mLastMemoryLevel);
13124                            pw.println(")");
13125                            break;
13126                    }
13127                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13128                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13129                            pw.print(cachedPss); pw.print(" cached pss + ");
13130                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13131                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13132                } else {
13133                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13134                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13135                            + memInfo.getFreeSizeKb()); pw.print(",");
13136                    pw.println(totalPss - cachedPss);
13137                }
13138            }
13139            if (!isCompact) {
13140                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13141                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13142                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13143                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13144                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13145                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13146                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13147                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13148                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13149                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13150                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13151            }
13152            if (!brief) {
13153                if (memInfo.getZramTotalSizeKb() != 0) {
13154                    if (!isCompact) {
13155                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13156                                pw.print(" kB physical used for ");
13157                                pw.print(memInfo.getSwapTotalSizeKb()
13158                                        - memInfo.getSwapFreeSizeKb());
13159                                pw.print(" kB in swap (");
13160                                pw.print(memInfo.getSwapTotalSizeKb());
13161                                pw.println(" kB total swap)");
13162                    } else {
13163                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13164                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13165                                pw.println(memInfo.getSwapFreeSizeKb());
13166                    }
13167                }
13168                final int[] SINGLE_LONG_FORMAT = new int[] {
13169                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13170                };
13171                long[] longOut = new long[1];
13172                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13173                        SINGLE_LONG_FORMAT, null, longOut, null);
13174                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13175                longOut[0] = 0;
13176                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13177                        SINGLE_LONG_FORMAT, null, longOut, null);
13178                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13179                longOut[0] = 0;
13180                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13181                        SINGLE_LONG_FORMAT, null, longOut, null);
13182                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13183                longOut[0] = 0;
13184                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13185                        SINGLE_LONG_FORMAT, null, longOut, null);
13186                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13187                if (!isCompact) {
13188                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13189                        pw.print("      KSM: "); pw.print(sharing);
13190                                pw.print(" kB saved from shared ");
13191                                pw.print(shared); pw.println(" kB");
13192                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13193                                pw.print(voltile); pw.println(" kB volatile");
13194                    }
13195                    pw.print("   Tuning: ");
13196                    pw.print(ActivityManager.staticGetMemoryClass());
13197                    pw.print(" (large ");
13198                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13199                    pw.print("), oom ");
13200                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13201                    pw.print(" kB");
13202                    pw.print(", restore limit ");
13203                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13204                    pw.print(" kB");
13205                    if (ActivityManager.isLowRamDeviceStatic()) {
13206                        pw.print(" (low-ram)");
13207                    }
13208                    if (ActivityManager.isHighEndGfx()) {
13209                        pw.print(" (high-end-gfx)");
13210                    }
13211                    pw.println();
13212                } else {
13213                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13214                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13215                    pw.println(voltile);
13216                    pw.print("tuning,");
13217                    pw.print(ActivityManager.staticGetMemoryClass());
13218                    pw.print(',');
13219                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13220                    pw.print(',');
13221                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13222                    if (ActivityManager.isLowRamDeviceStatic()) {
13223                        pw.print(",low-ram");
13224                    }
13225                    if (ActivityManager.isHighEndGfx()) {
13226                        pw.print(",high-end-gfx");
13227                    }
13228                    pw.println();
13229                }
13230            }
13231        }
13232    }
13233
13234    /**
13235     * Searches array of arguments for the specified string
13236     * @param args array of argument strings
13237     * @param value value to search for
13238     * @return true if the value is contained in the array
13239     */
13240    private static boolean scanArgs(String[] args, String value) {
13241        if (args != null) {
13242            for (String arg : args) {
13243                if (value.equals(arg)) {
13244                    return true;
13245                }
13246            }
13247        }
13248        return false;
13249    }
13250
13251    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13252            ContentProviderRecord cpr, boolean always) {
13253        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13254
13255        if (!inLaunching || always) {
13256            synchronized (cpr) {
13257                cpr.launchingApp = null;
13258                cpr.notifyAll();
13259            }
13260            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13261            String names[] = cpr.info.authority.split(";");
13262            for (int j = 0; j < names.length; j++) {
13263                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13264            }
13265        }
13266
13267        for (int i=0; i<cpr.connections.size(); i++) {
13268            ContentProviderConnection conn = cpr.connections.get(i);
13269            if (conn.waiting) {
13270                // If this connection is waiting for the provider, then we don't
13271                // need to mess with its process unless we are always removing
13272                // or for some reason the provider is not currently launching.
13273                if (inLaunching && !always) {
13274                    continue;
13275                }
13276            }
13277            ProcessRecord capp = conn.client;
13278            conn.dead = true;
13279            if (conn.stableCount > 0) {
13280                if (!capp.persistent && capp.thread != null
13281                        && capp.pid != 0
13282                        && capp.pid != MY_PID) {
13283                    killUnneededProcessLocked(capp, "depends on provider "
13284                            + cpr.name.flattenToShortString()
13285                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13286                }
13287            } else if (capp.thread != null && conn.provider.provider != null) {
13288                try {
13289                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13290                } catch (RemoteException e) {
13291                }
13292                // In the protocol here, we don't expect the client to correctly
13293                // clean up this connection, we'll just remove it.
13294                cpr.connections.remove(i);
13295                conn.client.conProviders.remove(conn);
13296            }
13297        }
13298
13299        if (inLaunching && always) {
13300            mLaunchingProviders.remove(cpr);
13301        }
13302        return inLaunching;
13303    }
13304
13305    /**
13306     * Main code for cleaning up a process when it has gone away.  This is
13307     * called both as a result of the process dying, or directly when stopping
13308     * a process when running in single process mode.
13309     */
13310    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13311            boolean restarting, boolean allowRestart, int index) {
13312        if (index >= 0) {
13313            removeLruProcessLocked(app);
13314            ProcessList.remove(app.pid);
13315        }
13316
13317        mProcessesToGc.remove(app);
13318        mPendingPssProcesses.remove(app);
13319
13320        // Dismiss any open dialogs.
13321        if (app.crashDialog != null && !app.forceCrashReport) {
13322            app.crashDialog.dismiss();
13323            app.crashDialog = null;
13324        }
13325        if (app.anrDialog != null) {
13326            app.anrDialog.dismiss();
13327            app.anrDialog = null;
13328        }
13329        if (app.waitDialog != null) {
13330            app.waitDialog.dismiss();
13331            app.waitDialog = null;
13332        }
13333
13334        app.crashing = false;
13335        app.notResponding = false;
13336
13337        app.resetPackageList(mProcessStats);
13338        app.unlinkDeathRecipient();
13339        app.makeInactive(mProcessStats);
13340        app.waitingToKill = null;
13341        app.forcingToForeground = null;
13342        updateProcessForegroundLocked(app, false, false);
13343        app.foregroundActivities = false;
13344        app.hasShownUi = false;
13345        app.treatLikeActivity = false;
13346        app.hasAboveClient = false;
13347        app.hasClientActivities = false;
13348
13349        mServices.killServicesLocked(app, allowRestart);
13350
13351        boolean restart = false;
13352
13353        // Remove published content providers.
13354        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13355            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13356            final boolean always = app.bad || !allowRestart;
13357            if (removeDyingProviderLocked(app, cpr, always) || always) {
13358                // We left the provider in the launching list, need to
13359                // restart it.
13360                restart = true;
13361            }
13362
13363            cpr.provider = null;
13364            cpr.proc = null;
13365        }
13366        app.pubProviders.clear();
13367
13368        // Take care of any launching providers waiting for this process.
13369        if (checkAppInLaunchingProvidersLocked(app, false)) {
13370            restart = true;
13371        }
13372
13373        // Unregister from connected content providers.
13374        if (!app.conProviders.isEmpty()) {
13375            for (int i=0; i<app.conProviders.size(); i++) {
13376                ContentProviderConnection conn = app.conProviders.get(i);
13377                conn.provider.connections.remove(conn);
13378            }
13379            app.conProviders.clear();
13380        }
13381
13382        // At this point there may be remaining entries in mLaunchingProviders
13383        // where we were the only one waiting, so they are no longer of use.
13384        // Look for these and clean up if found.
13385        // XXX Commented out for now.  Trying to figure out a way to reproduce
13386        // the actual situation to identify what is actually going on.
13387        if (false) {
13388            for (int i=0; i<mLaunchingProviders.size(); i++) {
13389                ContentProviderRecord cpr = (ContentProviderRecord)
13390                        mLaunchingProviders.get(i);
13391                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13392                    synchronized (cpr) {
13393                        cpr.launchingApp = null;
13394                        cpr.notifyAll();
13395                    }
13396                }
13397            }
13398        }
13399
13400        skipCurrentReceiverLocked(app);
13401
13402        // Unregister any receivers.
13403        for (int i=app.receivers.size()-1; i>=0; i--) {
13404            removeReceiverLocked(app.receivers.valueAt(i));
13405        }
13406        app.receivers.clear();
13407
13408        // If the app is undergoing backup, tell the backup manager about it
13409        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13410            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13411                    + mBackupTarget.appInfo + " died during backup");
13412            try {
13413                IBackupManager bm = IBackupManager.Stub.asInterface(
13414                        ServiceManager.getService(Context.BACKUP_SERVICE));
13415                bm.agentDisconnected(app.info.packageName);
13416            } catch (RemoteException e) {
13417                // can't happen; backup manager is local
13418            }
13419        }
13420
13421        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13422            ProcessChangeItem item = mPendingProcessChanges.get(i);
13423            if (item.pid == app.pid) {
13424                mPendingProcessChanges.remove(i);
13425                mAvailProcessChanges.add(item);
13426            }
13427        }
13428        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13429
13430        // If the caller is restarting this app, then leave it in its
13431        // current lists and let the caller take care of it.
13432        if (restarting) {
13433            return;
13434        }
13435
13436        if (!app.persistent || app.isolated) {
13437            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13438                    "Removing non-persistent process during cleanup: " + app);
13439            mProcessNames.remove(app.processName, app.uid);
13440            mIsolatedProcesses.remove(app.uid);
13441            if (mHeavyWeightProcess == app) {
13442                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13443                        mHeavyWeightProcess.userId, 0));
13444                mHeavyWeightProcess = null;
13445            }
13446        } else if (!app.removed) {
13447            // This app is persistent, so we need to keep its record around.
13448            // If it is not already on the pending app list, add it there
13449            // and start a new process for it.
13450            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13451                mPersistentStartingProcesses.add(app);
13452                restart = true;
13453            }
13454        }
13455        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13456                "Clean-up removing on hold: " + app);
13457        mProcessesOnHold.remove(app);
13458
13459        if (app == mHomeProcess) {
13460            mHomeProcess = null;
13461        }
13462        if (app == mPreviousProcess) {
13463            mPreviousProcess = null;
13464        }
13465
13466        if (restart && !app.isolated) {
13467            // We have components that still need to be running in the
13468            // process, so re-launch it.
13469            mProcessNames.put(app.processName, app.uid, app);
13470            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13471        } else if (app.pid > 0 && app.pid != MY_PID) {
13472            // Goodbye!
13473            boolean removed;
13474            synchronized (mPidsSelfLocked) {
13475                mPidsSelfLocked.remove(app.pid);
13476                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13477            }
13478            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13479            if (app.isolated) {
13480                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13481            }
13482            app.setPid(0);
13483        }
13484    }
13485
13486    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13487        // Look through the content providers we are waiting to have launched,
13488        // and if any run in this process then either schedule a restart of
13489        // the process or kill the client waiting for it if this process has
13490        // gone bad.
13491        int NL = mLaunchingProviders.size();
13492        boolean restart = false;
13493        for (int i=0; i<NL; i++) {
13494            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13495            if (cpr.launchingApp == app) {
13496                if (!alwaysBad && !app.bad) {
13497                    restart = true;
13498                } else {
13499                    removeDyingProviderLocked(app, cpr, true);
13500                    // cpr should have been removed from mLaunchingProviders
13501                    NL = mLaunchingProviders.size();
13502                    i--;
13503                }
13504            }
13505        }
13506        return restart;
13507    }
13508
13509    // =========================================================
13510    // SERVICES
13511    // =========================================================
13512
13513    @Override
13514    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13515            int flags) {
13516        enforceNotIsolatedCaller("getServices");
13517        synchronized (this) {
13518            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13519        }
13520    }
13521
13522    @Override
13523    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13524        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13525        synchronized (this) {
13526            return mServices.getRunningServiceControlPanelLocked(name);
13527        }
13528    }
13529
13530    @Override
13531    public ComponentName startService(IApplicationThread caller, Intent service,
13532            String resolvedType, int userId) {
13533        enforceNotIsolatedCaller("startService");
13534        // Refuse possible leaked file descriptors
13535        if (service != null && service.hasFileDescriptors() == true) {
13536            throw new IllegalArgumentException("File descriptors passed in Intent");
13537        }
13538
13539        if (DEBUG_SERVICE)
13540            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13541        synchronized(this) {
13542            final int callingPid = Binder.getCallingPid();
13543            final int callingUid = Binder.getCallingUid();
13544            final long origId = Binder.clearCallingIdentity();
13545            ComponentName res = mServices.startServiceLocked(caller, service,
13546                    resolvedType, callingPid, callingUid, userId);
13547            Binder.restoreCallingIdentity(origId);
13548            return res;
13549        }
13550    }
13551
13552    ComponentName startServiceInPackage(int uid,
13553            Intent service, String resolvedType, int userId) {
13554        synchronized(this) {
13555            if (DEBUG_SERVICE)
13556                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13557            final long origId = Binder.clearCallingIdentity();
13558            ComponentName res = mServices.startServiceLocked(null, service,
13559                    resolvedType, -1, uid, userId);
13560            Binder.restoreCallingIdentity(origId);
13561            return res;
13562        }
13563    }
13564
13565    @Override
13566    public int stopService(IApplicationThread caller, Intent service,
13567            String resolvedType, int userId) {
13568        enforceNotIsolatedCaller("stopService");
13569        // Refuse possible leaked file descriptors
13570        if (service != null && service.hasFileDescriptors() == true) {
13571            throw new IllegalArgumentException("File descriptors passed in Intent");
13572        }
13573
13574        synchronized(this) {
13575            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13576        }
13577    }
13578
13579    @Override
13580    public IBinder peekService(Intent service, String resolvedType) {
13581        enforceNotIsolatedCaller("peekService");
13582        // Refuse possible leaked file descriptors
13583        if (service != null && service.hasFileDescriptors() == true) {
13584            throw new IllegalArgumentException("File descriptors passed in Intent");
13585        }
13586        synchronized(this) {
13587            return mServices.peekServiceLocked(service, resolvedType);
13588        }
13589    }
13590
13591    @Override
13592    public boolean stopServiceToken(ComponentName className, IBinder token,
13593            int startId) {
13594        synchronized(this) {
13595            return mServices.stopServiceTokenLocked(className, token, startId);
13596        }
13597    }
13598
13599    @Override
13600    public void setServiceForeground(ComponentName className, IBinder token,
13601            int id, Notification notification, boolean removeNotification) {
13602        synchronized(this) {
13603            mServices.setServiceForegroundLocked(className, token, id, notification,
13604                    removeNotification);
13605        }
13606    }
13607
13608    @Override
13609    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13610            boolean requireFull, String name, String callerPackage) {
13611        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13612                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13613    }
13614
13615    int unsafeConvertIncomingUser(int userId) {
13616        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13617                ? mCurrentUserId : userId;
13618    }
13619
13620    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13621            int allowMode, String name, String callerPackage) {
13622        final int callingUserId = UserHandle.getUserId(callingUid);
13623        if (callingUserId == userId) {
13624            return userId;
13625        }
13626
13627        // Note that we may be accessing mCurrentUserId outside of a lock...
13628        // shouldn't be a big deal, if this is being called outside
13629        // of a locked context there is intrinsically a race with
13630        // the value the caller will receive and someone else changing it.
13631        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13632        // we will switch to the calling user if access to the current user fails.
13633        int targetUserId = unsafeConvertIncomingUser(userId);
13634
13635        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13636            final boolean allow;
13637            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13638                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13639                // If the caller has this permission, they always pass go.  And collect $200.
13640                allow = true;
13641            } else if (allowMode == ALLOW_FULL_ONLY) {
13642                // We require full access, sucks to be you.
13643                allow = false;
13644            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13645                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13646                // If the caller does not have either permission, they are always doomed.
13647                allow = false;
13648            } else if (allowMode == ALLOW_NON_FULL) {
13649                // We are blanket allowing non-full access, you lucky caller!
13650                allow = true;
13651            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13652                // We may or may not allow this depending on whether the two users are
13653                // in the same profile.
13654                synchronized (mUserProfileGroupIdsSelfLocked) {
13655                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13656                            UserInfo.NO_PROFILE_GROUP_ID);
13657                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13658                            UserInfo.NO_PROFILE_GROUP_ID);
13659                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13660                            && callingProfile == targetProfile;
13661                }
13662            } else {
13663                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13664            }
13665            if (!allow) {
13666                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13667                    // In this case, they would like to just execute as their
13668                    // owner user instead of failing.
13669                    targetUserId = callingUserId;
13670                } else {
13671                    StringBuilder builder = new StringBuilder(128);
13672                    builder.append("Permission Denial: ");
13673                    builder.append(name);
13674                    if (callerPackage != null) {
13675                        builder.append(" from ");
13676                        builder.append(callerPackage);
13677                    }
13678                    builder.append(" asks to run as user ");
13679                    builder.append(userId);
13680                    builder.append(" but is calling from user ");
13681                    builder.append(UserHandle.getUserId(callingUid));
13682                    builder.append("; this requires ");
13683                    builder.append(INTERACT_ACROSS_USERS_FULL);
13684                    if (allowMode != ALLOW_FULL_ONLY) {
13685                        builder.append(" or ");
13686                        builder.append(INTERACT_ACROSS_USERS);
13687                    }
13688                    String msg = builder.toString();
13689                    Slog.w(TAG, msg);
13690                    throw new SecurityException(msg);
13691                }
13692            }
13693        }
13694        if (!allowAll && targetUserId < 0) {
13695            throw new IllegalArgumentException(
13696                    "Call does not support special user #" + targetUserId);
13697        }
13698        return targetUserId;
13699    }
13700
13701    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13702            String className, int flags) {
13703        boolean result = false;
13704        // For apps that don't have pre-defined UIDs, check for permission
13705        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13706            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13707                if (ActivityManager.checkUidPermission(
13708                        INTERACT_ACROSS_USERS,
13709                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13710                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13711                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13712                            + " requests FLAG_SINGLE_USER, but app does not hold "
13713                            + INTERACT_ACROSS_USERS;
13714                    Slog.w(TAG, msg);
13715                    throw new SecurityException(msg);
13716                }
13717                // Permission passed
13718                result = true;
13719            }
13720        } else if ("system".equals(componentProcessName)) {
13721            result = true;
13722        } else {
13723            // App with pre-defined UID, check if it's a persistent app
13724            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13725        }
13726        if (DEBUG_MU) {
13727            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13728                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13729        }
13730        return result;
13731    }
13732
13733    /**
13734     * Checks to see if the caller is in the same app as the singleton
13735     * component, or the component is in a special app. It allows special apps
13736     * to export singleton components but prevents exporting singleton
13737     * components for regular apps.
13738     */
13739    boolean isValidSingletonCall(int callingUid, int componentUid) {
13740        int componentAppId = UserHandle.getAppId(componentUid);
13741        return UserHandle.isSameApp(callingUid, componentUid)
13742                || componentAppId == Process.SYSTEM_UID
13743                || componentAppId == Process.PHONE_UID
13744                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13745                        == PackageManager.PERMISSION_GRANTED;
13746    }
13747
13748    public int bindService(IApplicationThread caller, IBinder token,
13749            Intent service, String resolvedType,
13750            IServiceConnection connection, int flags, int userId) {
13751        enforceNotIsolatedCaller("bindService");
13752        // Refuse possible leaked file descriptors
13753        if (service != null && service.hasFileDescriptors() == true) {
13754            throw new IllegalArgumentException("File descriptors passed in Intent");
13755        }
13756
13757        synchronized(this) {
13758            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13759                    connection, flags, userId);
13760        }
13761    }
13762
13763    public boolean unbindService(IServiceConnection connection) {
13764        synchronized (this) {
13765            return mServices.unbindServiceLocked(connection);
13766        }
13767    }
13768
13769    public void publishService(IBinder token, Intent intent, IBinder service) {
13770        // Refuse possible leaked file descriptors
13771        if (intent != null && intent.hasFileDescriptors() == true) {
13772            throw new IllegalArgumentException("File descriptors passed in Intent");
13773        }
13774
13775        synchronized(this) {
13776            if (!(token instanceof ServiceRecord)) {
13777                throw new IllegalArgumentException("Invalid service token");
13778            }
13779            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13780        }
13781    }
13782
13783    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13784        // Refuse possible leaked file descriptors
13785        if (intent != null && intent.hasFileDescriptors() == true) {
13786            throw new IllegalArgumentException("File descriptors passed in Intent");
13787        }
13788
13789        synchronized(this) {
13790            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13791        }
13792    }
13793
13794    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13795        synchronized(this) {
13796            if (!(token instanceof ServiceRecord)) {
13797                throw new IllegalArgumentException("Invalid service token");
13798            }
13799            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13800        }
13801    }
13802
13803    // =========================================================
13804    // BACKUP AND RESTORE
13805    // =========================================================
13806
13807    // Cause the target app to be launched if necessary and its backup agent
13808    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13809    // activity manager to announce its creation.
13810    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13811        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13812        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13813
13814        synchronized(this) {
13815            // !!! TODO: currently no check here that we're already bound
13816            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13817            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13818            synchronized (stats) {
13819                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13820            }
13821
13822            // Backup agent is now in use, its package can't be stopped.
13823            try {
13824                AppGlobals.getPackageManager().setPackageStoppedState(
13825                        app.packageName, false, UserHandle.getUserId(app.uid));
13826            } catch (RemoteException e) {
13827            } catch (IllegalArgumentException e) {
13828                Slog.w(TAG, "Failed trying to unstop package "
13829                        + app.packageName + ": " + e);
13830            }
13831
13832            BackupRecord r = new BackupRecord(ss, app, backupMode);
13833            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13834                    ? new ComponentName(app.packageName, app.backupAgentName)
13835                    : new ComponentName("android", "FullBackupAgent");
13836            // startProcessLocked() returns existing proc's record if it's already running
13837            ProcessRecord proc = startProcessLocked(app.processName, app,
13838                    false, 0, "backup", hostingName, false, false, false);
13839            if (proc == null) {
13840                Slog.e(TAG, "Unable to start backup agent process " + r);
13841                return false;
13842            }
13843
13844            r.app = proc;
13845            mBackupTarget = r;
13846            mBackupAppName = app.packageName;
13847
13848            // Try not to kill the process during backup
13849            updateOomAdjLocked(proc);
13850
13851            // If the process is already attached, schedule the creation of the backup agent now.
13852            // If it is not yet live, this will be done when it attaches to the framework.
13853            if (proc.thread != null) {
13854                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13855                try {
13856                    proc.thread.scheduleCreateBackupAgent(app,
13857                            compatibilityInfoForPackageLocked(app), backupMode);
13858                } catch (RemoteException e) {
13859                    // Will time out on the backup manager side
13860                }
13861            } else {
13862                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13863            }
13864            // Invariants: at this point, the target app process exists and the application
13865            // is either already running or in the process of coming up.  mBackupTarget and
13866            // mBackupAppName describe the app, so that when it binds back to the AM we
13867            // know that it's scheduled for a backup-agent operation.
13868        }
13869
13870        return true;
13871    }
13872
13873    @Override
13874    public void clearPendingBackup() {
13875        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13876        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13877
13878        synchronized (this) {
13879            mBackupTarget = null;
13880            mBackupAppName = null;
13881        }
13882    }
13883
13884    // A backup agent has just come up
13885    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13886        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13887                + " = " + agent);
13888
13889        synchronized(this) {
13890            if (!agentPackageName.equals(mBackupAppName)) {
13891                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13892                return;
13893            }
13894        }
13895
13896        long oldIdent = Binder.clearCallingIdentity();
13897        try {
13898            IBackupManager bm = IBackupManager.Stub.asInterface(
13899                    ServiceManager.getService(Context.BACKUP_SERVICE));
13900            bm.agentConnected(agentPackageName, agent);
13901        } catch (RemoteException e) {
13902            // can't happen; the backup manager service is local
13903        } catch (Exception e) {
13904            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13905            e.printStackTrace();
13906        } finally {
13907            Binder.restoreCallingIdentity(oldIdent);
13908        }
13909    }
13910
13911    // done with this agent
13912    public void unbindBackupAgent(ApplicationInfo appInfo) {
13913        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13914        if (appInfo == null) {
13915            Slog.w(TAG, "unbind backup agent for null app");
13916            return;
13917        }
13918
13919        synchronized(this) {
13920            try {
13921                if (mBackupAppName == null) {
13922                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13923                    return;
13924                }
13925
13926                if (!mBackupAppName.equals(appInfo.packageName)) {
13927                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13928                    return;
13929                }
13930
13931                // Not backing this app up any more; reset its OOM adjustment
13932                final ProcessRecord proc = mBackupTarget.app;
13933                updateOomAdjLocked(proc);
13934
13935                // If the app crashed during backup, 'thread' will be null here
13936                if (proc.thread != null) {
13937                    try {
13938                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13939                                compatibilityInfoForPackageLocked(appInfo));
13940                    } catch (Exception e) {
13941                        Slog.e(TAG, "Exception when unbinding backup agent:");
13942                        e.printStackTrace();
13943                    }
13944                }
13945            } finally {
13946                mBackupTarget = null;
13947                mBackupAppName = null;
13948            }
13949        }
13950    }
13951    // =========================================================
13952    // BROADCASTS
13953    // =========================================================
13954
13955    private final List getStickiesLocked(String action, IntentFilter filter,
13956            List cur, int userId) {
13957        final ContentResolver resolver = mContext.getContentResolver();
13958        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13959        if (stickies == null) {
13960            return cur;
13961        }
13962        final ArrayList<Intent> list = stickies.get(action);
13963        if (list == null) {
13964            return cur;
13965        }
13966        int N = list.size();
13967        for (int i=0; i<N; i++) {
13968            Intent intent = list.get(i);
13969            if (filter.match(resolver, intent, true, TAG) >= 0) {
13970                if (cur == null) {
13971                    cur = new ArrayList<Intent>();
13972                }
13973                cur.add(intent);
13974            }
13975        }
13976        return cur;
13977    }
13978
13979    boolean isPendingBroadcastProcessLocked(int pid) {
13980        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13981                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13982    }
13983
13984    void skipPendingBroadcastLocked(int pid) {
13985            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13986            for (BroadcastQueue queue : mBroadcastQueues) {
13987                queue.skipPendingBroadcastLocked(pid);
13988            }
13989    }
13990
13991    // The app just attached; send any pending broadcasts that it should receive
13992    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13993        boolean didSomething = false;
13994        for (BroadcastQueue queue : mBroadcastQueues) {
13995            didSomething |= queue.sendPendingBroadcastsLocked(app);
13996        }
13997        return didSomething;
13998    }
13999
14000    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14001            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14002        enforceNotIsolatedCaller("registerReceiver");
14003        int callingUid;
14004        int callingPid;
14005        synchronized(this) {
14006            ProcessRecord callerApp = null;
14007            if (caller != null) {
14008                callerApp = getRecordForAppLocked(caller);
14009                if (callerApp == null) {
14010                    throw new SecurityException(
14011                            "Unable to find app for caller " + caller
14012                            + " (pid=" + Binder.getCallingPid()
14013                            + ") when registering receiver " + receiver);
14014                }
14015                if (callerApp.info.uid != Process.SYSTEM_UID &&
14016                        !callerApp.pkgList.containsKey(callerPackage) &&
14017                        !"android".equals(callerPackage)) {
14018                    throw new SecurityException("Given caller package " + callerPackage
14019                            + " is not running in process " + callerApp);
14020                }
14021                callingUid = callerApp.info.uid;
14022                callingPid = callerApp.pid;
14023            } else {
14024                callerPackage = null;
14025                callingUid = Binder.getCallingUid();
14026                callingPid = Binder.getCallingPid();
14027            }
14028
14029            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14030                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14031
14032            List allSticky = null;
14033
14034            // Look for any matching sticky broadcasts...
14035            Iterator actions = filter.actionsIterator();
14036            if (actions != null) {
14037                while (actions.hasNext()) {
14038                    String action = (String)actions.next();
14039                    allSticky = getStickiesLocked(action, filter, allSticky,
14040                            UserHandle.USER_ALL);
14041                    allSticky = getStickiesLocked(action, filter, allSticky,
14042                            UserHandle.getUserId(callingUid));
14043                }
14044            } else {
14045                allSticky = getStickiesLocked(null, filter, allSticky,
14046                        UserHandle.USER_ALL);
14047                allSticky = getStickiesLocked(null, filter, allSticky,
14048                        UserHandle.getUserId(callingUid));
14049            }
14050
14051            // The first sticky in the list is returned directly back to
14052            // the client.
14053            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14054
14055            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14056                    + ": " + sticky);
14057
14058            if (receiver == null) {
14059                return sticky;
14060            }
14061
14062            ReceiverList rl
14063                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14064            if (rl == null) {
14065                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14066                        userId, receiver);
14067                if (rl.app != null) {
14068                    rl.app.receivers.add(rl);
14069                } else {
14070                    try {
14071                        receiver.asBinder().linkToDeath(rl, 0);
14072                    } catch (RemoteException e) {
14073                        return sticky;
14074                    }
14075                    rl.linkedToDeath = true;
14076                }
14077                mRegisteredReceivers.put(receiver.asBinder(), rl);
14078            } else if (rl.uid != callingUid) {
14079                throw new IllegalArgumentException(
14080                        "Receiver requested to register for uid " + callingUid
14081                        + " was previously registered for uid " + rl.uid);
14082            } else if (rl.pid != callingPid) {
14083                throw new IllegalArgumentException(
14084                        "Receiver requested to register for pid " + callingPid
14085                        + " was previously registered for pid " + rl.pid);
14086            } else if (rl.userId != userId) {
14087                throw new IllegalArgumentException(
14088                        "Receiver requested to register for user " + userId
14089                        + " was previously registered for user " + rl.userId);
14090            }
14091            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14092                    permission, callingUid, userId);
14093            rl.add(bf);
14094            if (!bf.debugCheck()) {
14095                Slog.w(TAG, "==> For Dynamic broadast");
14096            }
14097            mReceiverResolver.addFilter(bf);
14098
14099            // Enqueue broadcasts for all existing stickies that match
14100            // this filter.
14101            if (allSticky != null) {
14102                ArrayList receivers = new ArrayList();
14103                receivers.add(bf);
14104
14105                int N = allSticky.size();
14106                for (int i=0; i<N; i++) {
14107                    Intent intent = (Intent)allSticky.get(i);
14108                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14109                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14110                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14111                            null, null, false, true, true, -1);
14112                    queue.enqueueParallelBroadcastLocked(r);
14113                    queue.scheduleBroadcastsLocked();
14114                }
14115            }
14116
14117            return sticky;
14118        }
14119    }
14120
14121    public void unregisterReceiver(IIntentReceiver receiver) {
14122        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14123
14124        final long origId = Binder.clearCallingIdentity();
14125        try {
14126            boolean doTrim = false;
14127
14128            synchronized(this) {
14129                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14130                if (rl != null) {
14131                    if (rl.curBroadcast != null) {
14132                        BroadcastRecord r = rl.curBroadcast;
14133                        final boolean doNext = finishReceiverLocked(
14134                                receiver.asBinder(), r.resultCode, r.resultData,
14135                                r.resultExtras, r.resultAbort);
14136                        if (doNext) {
14137                            doTrim = true;
14138                            r.queue.processNextBroadcast(false);
14139                        }
14140                    }
14141
14142                    if (rl.app != null) {
14143                        rl.app.receivers.remove(rl);
14144                    }
14145                    removeReceiverLocked(rl);
14146                    if (rl.linkedToDeath) {
14147                        rl.linkedToDeath = false;
14148                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14149                    }
14150                }
14151            }
14152
14153            // If we actually concluded any broadcasts, we might now be able
14154            // to trim the recipients' apps from our working set
14155            if (doTrim) {
14156                trimApplications();
14157                return;
14158            }
14159
14160        } finally {
14161            Binder.restoreCallingIdentity(origId);
14162        }
14163    }
14164
14165    void removeReceiverLocked(ReceiverList rl) {
14166        mRegisteredReceivers.remove(rl.receiver.asBinder());
14167        int N = rl.size();
14168        for (int i=0; i<N; i++) {
14169            mReceiverResolver.removeFilter(rl.get(i));
14170        }
14171    }
14172
14173    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14174        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14175            ProcessRecord r = mLruProcesses.get(i);
14176            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14177                try {
14178                    r.thread.dispatchPackageBroadcast(cmd, packages);
14179                } catch (RemoteException ex) {
14180                }
14181            }
14182        }
14183    }
14184
14185    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14186            int[] users) {
14187        List<ResolveInfo> receivers = null;
14188        try {
14189            HashSet<ComponentName> singleUserReceivers = null;
14190            boolean scannedFirstReceivers = false;
14191            for (int user : users) {
14192                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14193                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14194                if (user != 0 && newReceivers != null) {
14195                    // If this is not the primary user, we need to check for
14196                    // any receivers that should be filtered out.
14197                    for (int i=0; i<newReceivers.size(); i++) {
14198                        ResolveInfo ri = newReceivers.get(i);
14199                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14200                            newReceivers.remove(i);
14201                            i--;
14202                        }
14203                    }
14204                }
14205                if (newReceivers != null && newReceivers.size() == 0) {
14206                    newReceivers = null;
14207                }
14208                if (receivers == null) {
14209                    receivers = newReceivers;
14210                } else if (newReceivers != null) {
14211                    // We need to concatenate the additional receivers
14212                    // found with what we have do far.  This would be easy,
14213                    // but we also need to de-dup any receivers that are
14214                    // singleUser.
14215                    if (!scannedFirstReceivers) {
14216                        // Collect any single user receivers we had already retrieved.
14217                        scannedFirstReceivers = true;
14218                        for (int i=0; i<receivers.size(); i++) {
14219                            ResolveInfo ri = receivers.get(i);
14220                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14221                                ComponentName cn = new ComponentName(
14222                                        ri.activityInfo.packageName, ri.activityInfo.name);
14223                                if (singleUserReceivers == null) {
14224                                    singleUserReceivers = new HashSet<ComponentName>();
14225                                }
14226                                singleUserReceivers.add(cn);
14227                            }
14228                        }
14229                    }
14230                    // Add the new results to the existing results, tracking
14231                    // and de-dupping single user receivers.
14232                    for (int i=0; i<newReceivers.size(); i++) {
14233                        ResolveInfo ri = newReceivers.get(i);
14234                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14235                            ComponentName cn = new ComponentName(
14236                                    ri.activityInfo.packageName, ri.activityInfo.name);
14237                            if (singleUserReceivers == null) {
14238                                singleUserReceivers = new HashSet<ComponentName>();
14239                            }
14240                            if (!singleUserReceivers.contains(cn)) {
14241                                singleUserReceivers.add(cn);
14242                                receivers.add(ri);
14243                            }
14244                        } else {
14245                            receivers.add(ri);
14246                        }
14247                    }
14248                }
14249            }
14250        } catch (RemoteException ex) {
14251            // pm is in same process, this will never happen.
14252        }
14253        return receivers;
14254    }
14255
14256    private final int broadcastIntentLocked(ProcessRecord callerApp,
14257            String callerPackage, Intent intent, String resolvedType,
14258            IIntentReceiver resultTo, int resultCode, String resultData,
14259            Bundle map, String requiredPermission, int appOp,
14260            boolean ordered, boolean sticky, int callingPid, int callingUid,
14261            int userId) {
14262        intent = new Intent(intent);
14263
14264        // By default broadcasts do not go to stopped apps.
14265        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14266
14267        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14268            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14269            + " ordered=" + ordered + " userid=" + userId);
14270        if ((resultTo != null) && !ordered) {
14271            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14272        }
14273
14274        userId = handleIncomingUser(callingPid, callingUid, userId,
14275                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14276
14277        // Make sure that the user who is receiving this broadcast is started.
14278        // If not, we will just skip it.
14279
14280
14281        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14282            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14283                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14284                Slog.w(TAG, "Skipping broadcast of " + intent
14285                        + ": user " + userId + " is stopped");
14286                return ActivityManager.BROADCAST_SUCCESS;
14287            }
14288        }
14289
14290        /*
14291         * Prevent non-system code (defined here to be non-persistent
14292         * processes) from sending protected broadcasts.
14293         */
14294        int callingAppId = UserHandle.getAppId(callingUid);
14295        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14296            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14297            || callingAppId == Process.NFC_UID || callingUid == 0) {
14298            // Always okay.
14299        } else if (callerApp == null || !callerApp.persistent) {
14300            try {
14301                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14302                        intent.getAction())) {
14303                    String msg = "Permission Denial: not allowed to send broadcast "
14304                            + intent.getAction() + " from pid="
14305                            + callingPid + ", uid=" + callingUid;
14306                    Slog.w(TAG, msg);
14307                    throw new SecurityException(msg);
14308                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14309                    // Special case for compatibility: we don't want apps to send this,
14310                    // but historically it has not been protected and apps may be using it
14311                    // to poke their own app widget.  So, instead of making it protected,
14312                    // just limit it to the caller.
14313                    if (callerApp == null) {
14314                        String msg = "Permission Denial: not allowed to send broadcast "
14315                                + intent.getAction() + " from unknown caller.";
14316                        Slog.w(TAG, msg);
14317                        throw new SecurityException(msg);
14318                    } else if (intent.getComponent() != null) {
14319                        // They are good enough to send to an explicit component...  verify
14320                        // it is being sent to the calling app.
14321                        if (!intent.getComponent().getPackageName().equals(
14322                                callerApp.info.packageName)) {
14323                            String msg = "Permission Denial: not allowed to send broadcast "
14324                                    + intent.getAction() + " to "
14325                                    + intent.getComponent().getPackageName() + " from "
14326                                    + callerApp.info.packageName;
14327                            Slog.w(TAG, msg);
14328                            throw new SecurityException(msg);
14329                        }
14330                    } else {
14331                        // Limit broadcast to their own package.
14332                        intent.setPackage(callerApp.info.packageName);
14333                    }
14334                }
14335            } catch (RemoteException e) {
14336                Slog.w(TAG, "Remote exception", e);
14337                return ActivityManager.BROADCAST_SUCCESS;
14338            }
14339        }
14340
14341        // Handle special intents: if this broadcast is from the package
14342        // manager about a package being removed, we need to remove all of
14343        // its activities from the history stack.
14344        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14345                intent.getAction());
14346        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14347                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14348                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14349                || uidRemoved) {
14350            if (checkComponentPermission(
14351                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14352                    callingPid, callingUid, -1, true)
14353                    == PackageManager.PERMISSION_GRANTED) {
14354                if (uidRemoved) {
14355                    final Bundle intentExtras = intent.getExtras();
14356                    final int uid = intentExtras != null
14357                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14358                    if (uid >= 0) {
14359                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14360                        synchronized (bs) {
14361                            bs.removeUidStatsLocked(uid);
14362                        }
14363                        mAppOpsService.uidRemoved(uid);
14364                    }
14365                } else {
14366                    // If resources are unavailable just force stop all
14367                    // those packages and flush the attribute cache as well.
14368                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14369                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14370                        if (list != null && (list.length > 0)) {
14371                            for (String pkg : list) {
14372                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14373                                        "storage unmount");
14374                            }
14375                            sendPackageBroadcastLocked(
14376                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14377                        }
14378                    } else {
14379                        Uri data = intent.getData();
14380                        String ssp;
14381                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14382                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14383                                    intent.getAction());
14384                            boolean fullUninstall = removed &&
14385                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14386                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14387                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14388                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14389                                        false, fullUninstall, userId,
14390                                        removed ? "pkg removed" : "pkg changed");
14391                            }
14392                            if (removed) {
14393                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14394                                        new String[] {ssp}, userId);
14395                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14396                                    mAppOpsService.packageRemoved(
14397                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14398
14399                                    // Remove all permissions granted from/to this package
14400                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14401                                }
14402                            }
14403                        }
14404                    }
14405                }
14406            } else {
14407                String msg = "Permission Denial: " + intent.getAction()
14408                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14409                        + ", uid=" + callingUid + ")"
14410                        + " requires "
14411                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14412                Slog.w(TAG, msg);
14413                throw new SecurityException(msg);
14414            }
14415
14416        // Special case for adding a package: by default turn on compatibility
14417        // mode.
14418        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14419            Uri data = intent.getData();
14420            String ssp;
14421            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14422                mCompatModePackages.handlePackageAddedLocked(ssp,
14423                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14424            }
14425        }
14426
14427        /*
14428         * If this is the time zone changed action, queue up a message that will reset the timezone
14429         * of all currently running processes. This message will get queued up before the broadcast
14430         * happens.
14431         */
14432        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14433            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14434        }
14435
14436        /*
14437         * If the user set the time, let all running processes know.
14438         */
14439        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14440            final int is24Hour = intent.getBooleanExtra(
14441                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14442            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14443        }
14444
14445        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14446            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14447        }
14448
14449        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14450            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14451            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14452        }
14453
14454        // Add to the sticky list if requested.
14455        if (sticky) {
14456            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14457                    callingPid, callingUid)
14458                    != PackageManager.PERMISSION_GRANTED) {
14459                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14460                        + callingPid + ", uid=" + callingUid
14461                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14462                Slog.w(TAG, msg);
14463                throw new SecurityException(msg);
14464            }
14465            if (requiredPermission != null) {
14466                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14467                        + " and enforce permission " + requiredPermission);
14468                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14469            }
14470            if (intent.getComponent() != null) {
14471                throw new SecurityException(
14472                        "Sticky broadcasts can't target a specific component");
14473            }
14474            // We use userId directly here, since the "all" target is maintained
14475            // as a separate set of sticky broadcasts.
14476            if (userId != UserHandle.USER_ALL) {
14477                // But first, if this is not a broadcast to all users, then
14478                // make sure it doesn't conflict with an existing broadcast to
14479                // all users.
14480                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14481                        UserHandle.USER_ALL);
14482                if (stickies != null) {
14483                    ArrayList<Intent> list = stickies.get(intent.getAction());
14484                    if (list != null) {
14485                        int N = list.size();
14486                        int i;
14487                        for (i=0; i<N; i++) {
14488                            if (intent.filterEquals(list.get(i))) {
14489                                throw new IllegalArgumentException(
14490                                        "Sticky broadcast " + intent + " for user "
14491                                        + userId + " conflicts with existing global broadcast");
14492                            }
14493                        }
14494                    }
14495                }
14496            }
14497            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14498            if (stickies == null) {
14499                stickies = new ArrayMap<String, ArrayList<Intent>>();
14500                mStickyBroadcasts.put(userId, stickies);
14501            }
14502            ArrayList<Intent> list = stickies.get(intent.getAction());
14503            if (list == null) {
14504                list = new ArrayList<Intent>();
14505                stickies.put(intent.getAction(), list);
14506            }
14507            int N = list.size();
14508            int i;
14509            for (i=0; i<N; i++) {
14510                if (intent.filterEquals(list.get(i))) {
14511                    // This sticky already exists, replace it.
14512                    list.set(i, new Intent(intent));
14513                    break;
14514                }
14515            }
14516            if (i >= N) {
14517                list.add(new Intent(intent));
14518            }
14519        }
14520
14521        int[] users;
14522        if (userId == UserHandle.USER_ALL) {
14523            // Caller wants broadcast to go to all started users.
14524            users = mStartedUserArray;
14525        } else {
14526            // Caller wants broadcast to go to one specific user.
14527            users = new int[] {userId};
14528        }
14529
14530        // Figure out who all will receive this broadcast.
14531        List receivers = null;
14532        List<BroadcastFilter> registeredReceivers = null;
14533        // Need to resolve the intent to interested receivers...
14534        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14535                 == 0) {
14536            receivers = collectReceiverComponents(intent, resolvedType, users);
14537        }
14538        if (intent.getComponent() == null) {
14539            registeredReceivers = mReceiverResolver.queryIntent(intent,
14540                    resolvedType, false, userId);
14541        }
14542
14543        final boolean replacePending =
14544                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14545
14546        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14547                + " replacePending=" + replacePending);
14548
14549        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14550        if (!ordered && NR > 0) {
14551            // If we are not serializing this broadcast, then send the
14552            // registered receivers separately so they don't wait for the
14553            // components to be launched.
14554            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14555            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14556                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14557                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14558                    ordered, sticky, false, userId);
14559            if (DEBUG_BROADCAST) Slog.v(
14560                    TAG, "Enqueueing parallel broadcast " + r);
14561            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14562            if (!replaced) {
14563                queue.enqueueParallelBroadcastLocked(r);
14564                queue.scheduleBroadcastsLocked();
14565            }
14566            registeredReceivers = null;
14567            NR = 0;
14568        }
14569
14570        // Merge into one list.
14571        int ir = 0;
14572        if (receivers != null) {
14573            // A special case for PACKAGE_ADDED: do not allow the package
14574            // being added to see this broadcast.  This prevents them from
14575            // using this as a back door to get run as soon as they are
14576            // installed.  Maybe in the future we want to have a special install
14577            // broadcast or such for apps, but we'd like to deliberately make
14578            // this decision.
14579            String skipPackages[] = null;
14580            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14581                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14582                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14583                Uri data = intent.getData();
14584                if (data != null) {
14585                    String pkgName = data.getSchemeSpecificPart();
14586                    if (pkgName != null) {
14587                        skipPackages = new String[] { pkgName };
14588                    }
14589                }
14590            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14591                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14592            }
14593            if (skipPackages != null && (skipPackages.length > 0)) {
14594                for (String skipPackage : skipPackages) {
14595                    if (skipPackage != null) {
14596                        int NT = receivers.size();
14597                        for (int it=0; it<NT; it++) {
14598                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14599                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14600                                receivers.remove(it);
14601                                it--;
14602                                NT--;
14603                            }
14604                        }
14605                    }
14606                }
14607            }
14608
14609            int NT = receivers != null ? receivers.size() : 0;
14610            int it = 0;
14611            ResolveInfo curt = null;
14612            BroadcastFilter curr = null;
14613            while (it < NT && ir < NR) {
14614                if (curt == null) {
14615                    curt = (ResolveInfo)receivers.get(it);
14616                }
14617                if (curr == null) {
14618                    curr = registeredReceivers.get(ir);
14619                }
14620                if (curr.getPriority() >= curt.priority) {
14621                    // Insert this broadcast record into the final list.
14622                    receivers.add(it, curr);
14623                    ir++;
14624                    curr = null;
14625                    it++;
14626                    NT++;
14627                } else {
14628                    // Skip to the next ResolveInfo in the final list.
14629                    it++;
14630                    curt = null;
14631                }
14632            }
14633        }
14634        while (ir < NR) {
14635            if (receivers == null) {
14636                receivers = new ArrayList();
14637            }
14638            receivers.add(registeredReceivers.get(ir));
14639            ir++;
14640        }
14641
14642        if ((receivers != null && receivers.size() > 0)
14643                || resultTo != null) {
14644            BroadcastQueue queue = broadcastQueueForIntent(intent);
14645            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14646                    callerPackage, callingPid, callingUid, resolvedType,
14647                    requiredPermission, appOp, receivers, resultTo, resultCode,
14648                    resultData, map, ordered, sticky, false, userId);
14649            if (DEBUG_BROADCAST) Slog.v(
14650                    TAG, "Enqueueing ordered broadcast " + r
14651                    + ": prev had " + queue.mOrderedBroadcasts.size());
14652            if (DEBUG_BROADCAST) {
14653                int seq = r.intent.getIntExtra("seq", -1);
14654                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14655            }
14656            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14657            if (!replaced) {
14658                queue.enqueueOrderedBroadcastLocked(r);
14659                queue.scheduleBroadcastsLocked();
14660            }
14661        }
14662
14663        return ActivityManager.BROADCAST_SUCCESS;
14664    }
14665
14666    final Intent verifyBroadcastLocked(Intent intent) {
14667        // Refuse possible leaked file descriptors
14668        if (intent != null && intent.hasFileDescriptors() == true) {
14669            throw new IllegalArgumentException("File descriptors passed in Intent");
14670        }
14671
14672        int flags = intent.getFlags();
14673
14674        if (!mProcessesReady) {
14675            // if the caller really truly claims to know what they're doing, go
14676            // ahead and allow the broadcast without launching any receivers
14677            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14678                intent = new Intent(intent);
14679                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14680            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14681                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14682                        + " before boot completion");
14683                throw new IllegalStateException("Cannot broadcast before boot completed");
14684            }
14685        }
14686
14687        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14688            throw new IllegalArgumentException(
14689                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14690        }
14691
14692        return intent;
14693    }
14694
14695    public final int broadcastIntent(IApplicationThread caller,
14696            Intent intent, String resolvedType, IIntentReceiver resultTo,
14697            int resultCode, String resultData, Bundle map,
14698            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14699        enforceNotIsolatedCaller("broadcastIntent");
14700        synchronized(this) {
14701            intent = verifyBroadcastLocked(intent);
14702
14703            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14704            final int callingPid = Binder.getCallingPid();
14705            final int callingUid = Binder.getCallingUid();
14706            final long origId = Binder.clearCallingIdentity();
14707            int res = broadcastIntentLocked(callerApp,
14708                    callerApp != null ? callerApp.info.packageName : null,
14709                    intent, resolvedType, resultTo,
14710                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14711                    callingPid, callingUid, userId);
14712            Binder.restoreCallingIdentity(origId);
14713            return res;
14714        }
14715    }
14716
14717    int broadcastIntentInPackage(String packageName, int uid,
14718            Intent intent, String resolvedType, IIntentReceiver resultTo,
14719            int resultCode, String resultData, Bundle map,
14720            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14721        synchronized(this) {
14722            intent = verifyBroadcastLocked(intent);
14723
14724            final long origId = Binder.clearCallingIdentity();
14725            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14726                    resultTo, resultCode, resultData, map, requiredPermission,
14727                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14728            Binder.restoreCallingIdentity(origId);
14729            return res;
14730        }
14731    }
14732
14733    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14734        // Refuse possible leaked file descriptors
14735        if (intent != null && intent.hasFileDescriptors() == true) {
14736            throw new IllegalArgumentException("File descriptors passed in Intent");
14737        }
14738
14739        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14740                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14741
14742        synchronized(this) {
14743            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14744                    != PackageManager.PERMISSION_GRANTED) {
14745                String msg = "Permission Denial: unbroadcastIntent() from pid="
14746                        + Binder.getCallingPid()
14747                        + ", uid=" + Binder.getCallingUid()
14748                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14749                Slog.w(TAG, msg);
14750                throw new SecurityException(msg);
14751            }
14752            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14753            if (stickies != null) {
14754                ArrayList<Intent> list = stickies.get(intent.getAction());
14755                if (list != null) {
14756                    int N = list.size();
14757                    int i;
14758                    for (i=0; i<N; i++) {
14759                        if (intent.filterEquals(list.get(i))) {
14760                            list.remove(i);
14761                            break;
14762                        }
14763                    }
14764                    if (list.size() <= 0) {
14765                        stickies.remove(intent.getAction());
14766                    }
14767                }
14768                if (stickies.size() <= 0) {
14769                    mStickyBroadcasts.remove(userId);
14770                }
14771            }
14772        }
14773    }
14774
14775    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14776            String resultData, Bundle resultExtras, boolean resultAbort) {
14777        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14778        if (r == null) {
14779            Slog.w(TAG, "finishReceiver called but not found on queue");
14780            return false;
14781        }
14782
14783        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14784    }
14785
14786    void backgroundServicesFinishedLocked(int userId) {
14787        for (BroadcastQueue queue : mBroadcastQueues) {
14788            queue.backgroundServicesFinishedLocked(userId);
14789        }
14790    }
14791
14792    public void finishReceiver(IBinder who, int resultCode, String resultData,
14793            Bundle resultExtras, boolean resultAbort) {
14794        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14795
14796        // Refuse possible leaked file descriptors
14797        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14798            throw new IllegalArgumentException("File descriptors passed in Bundle");
14799        }
14800
14801        final long origId = Binder.clearCallingIdentity();
14802        try {
14803            boolean doNext = false;
14804            BroadcastRecord r;
14805
14806            synchronized(this) {
14807                r = broadcastRecordForReceiverLocked(who);
14808                if (r != null) {
14809                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14810                        resultData, resultExtras, resultAbort, true);
14811                }
14812            }
14813
14814            if (doNext) {
14815                r.queue.processNextBroadcast(false);
14816            }
14817            trimApplications();
14818        } finally {
14819            Binder.restoreCallingIdentity(origId);
14820        }
14821    }
14822
14823    // =========================================================
14824    // INSTRUMENTATION
14825    // =========================================================
14826
14827    public boolean startInstrumentation(ComponentName className,
14828            String profileFile, int flags, Bundle arguments,
14829            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14830            int userId, String abiOverride) {
14831        enforceNotIsolatedCaller("startInstrumentation");
14832        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14833                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14834        // Refuse possible leaked file descriptors
14835        if (arguments != null && arguments.hasFileDescriptors()) {
14836            throw new IllegalArgumentException("File descriptors passed in Bundle");
14837        }
14838
14839        synchronized(this) {
14840            InstrumentationInfo ii = null;
14841            ApplicationInfo ai = null;
14842            try {
14843                ii = mContext.getPackageManager().getInstrumentationInfo(
14844                    className, STOCK_PM_FLAGS);
14845                ai = AppGlobals.getPackageManager().getApplicationInfo(
14846                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14847            } catch (PackageManager.NameNotFoundException e) {
14848            } catch (RemoteException e) {
14849            }
14850            if (ii == null) {
14851                reportStartInstrumentationFailure(watcher, className,
14852                        "Unable to find instrumentation info for: " + className);
14853                return false;
14854            }
14855            if (ai == null) {
14856                reportStartInstrumentationFailure(watcher, className,
14857                        "Unable to find instrumentation target package: " + ii.targetPackage);
14858                return false;
14859            }
14860
14861            int match = mContext.getPackageManager().checkSignatures(
14862                    ii.targetPackage, ii.packageName);
14863            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14864                String msg = "Permission Denial: starting instrumentation "
14865                        + className + " from pid="
14866                        + Binder.getCallingPid()
14867                        + ", uid=" + Binder.getCallingPid()
14868                        + " not allowed because package " + ii.packageName
14869                        + " does not have a signature matching the target "
14870                        + ii.targetPackage;
14871                reportStartInstrumentationFailure(watcher, className, msg);
14872                throw new SecurityException(msg);
14873            }
14874
14875            final long origId = Binder.clearCallingIdentity();
14876            // Instrumentation can kill and relaunch even persistent processes
14877            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14878                    "start instr");
14879            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14880            app.instrumentationClass = className;
14881            app.instrumentationInfo = ai;
14882            app.instrumentationProfileFile = profileFile;
14883            app.instrumentationArguments = arguments;
14884            app.instrumentationWatcher = watcher;
14885            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14886            app.instrumentationResultClass = className;
14887            Binder.restoreCallingIdentity(origId);
14888        }
14889
14890        return true;
14891    }
14892
14893    /**
14894     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14895     * error to the logs, but if somebody is watching, send the report there too.  This enables
14896     * the "am" command to report errors with more information.
14897     *
14898     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14899     * @param cn The component name of the instrumentation.
14900     * @param report The error report.
14901     */
14902    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14903            ComponentName cn, String report) {
14904        Slog.w(TAG, report);
14905        try {
14906            if (watcher != null) {
14907                Bundle results = new Bundle();
14908                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14909                results.putString("Error", report);
14910                watcher.instrumentationStatus(cn, -1, results);
14911            }
14912        } catch (RemoteException e) {
14913            Slog.w(TAG, e);
14914        }
14915    }
14916
14917    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14918        if (app.instrumentationWatcher != null) {
14919            try {
14920                // NOTE:  IInstrumentationWatcher *must* be oneway here
14921                app.instrumentationWatcher.instrumentationFinished(
14922                    app.instrumentationClass,
14923                    resultCode,
14924                    results);
14925            } catch (RemoteException e) {
14926            }
14927        }
14928        if (app.instrumentationUiAutomationConnection != null) {
14929            try {
14930                app.instrumentationUiAutomationConnection.shutdown();
14931            } catch (RemoteException re) {
14932                /* ignore */
14933            }
14934            // Only a UiAutomation can set this flag and now that
14935            // it is finished we make sure it is reset to its default.
14936            mUserIsMonkey = false;
14937        }
14938        app.instrumentationWatcher = null;
14939        app.instrumentationUiAutomationConnection = null;
14940        app.instrumentationClass = null;
14941        app.instrumentationInfo = null;
14942        app.instrumentationProfileFile = null;
14943        app.instrumentationArguments = null;
14944
14945        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14946                "finished inst");
14947    }
14948
14949    public void finishInstrumentation(IApplicationThread target,
14950            int resultCode, Bundle results) {
14951        int userId = UserHandle.getCallingUserId();
14952        // Refuse possible leaked file descriptors
14953        if (results != null && results.hasFileDescriptors()) {
14954            throw new IllegalArgumentException("File descriptors passed in Intent");
14955        }
14956
14957        synchronized(this) {
14958            ProcessRecord app = getRecordForAppLocked(target);
14959            if (app == null) {
14960                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14961                return;
14962            }
14963            final long origId = Binder.clearCallingIdentity();
14964            finishInstrumentationLocked(app, resultCode, results);
14965            Binder.restoreCallingIdentity(origId);
14966        }
14967    }
14968
14969    // =========================================================
14970    // CONFIGURATION
14971    // =========================================================
14972
14973    public ConfigurationInfo getDeviceConfigurationInfo() {
14974        ConfigurationInfo config = new ConfigurationInfo();
14975        synchronized (this) {
14976            config.reqTouchScreen = mConfiguration.touchscreen;
14977            config.reqKeyboardType = mConfiguration.keyboard;
14978            config.reqNavigation = mConfiguration.navigation;
14979            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14980                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14981                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14982            }
14983            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14984                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14985                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14986            }
14987            config.reqGlEsVersion = GL_ES_VERSION;
14988        }
14989        return config;
14990    }
14991
14992    ActivityStack getFocusedStack() {
14993        return mStackSupervisor.getFocusedStack();
14994    }
14995
14996    public Configuration getConfiguration() {
14997        Configuration ci;
14998        synchronized(this) {
14999            ci = new Configuration(mConfiguration);
15000        }
15001        return ci;
15002    }
15003
15004    public void updatePersistentConfiguration(Configuration values) {
15005        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15006                "updateConfiguration()");
15007        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15008                "updateConfiguration()");
15009        if (values == null) {
15010            throw new NullPointerException("Configuration must not be null");
15011        }
15012
15013        synchronized(this) {
15014            final long origId = Binder.clearCallingIdentity();
15015            updateConfigurationLocked(values, null, true, false);
15016            Binder.restoreCallingIdentity(origId);
15017        }
15018    }
15019
15020    public void updateConfiguration(Configuration values) {
15021        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15022                "updateConfiguration()");
15023
15024        synchronized(this) {
15025            if (values == null && mWindowManager != null) {
15026                // sentinel: fetch the current configuration from the window manager
15027                values = mWindowManager.computeNewConfiguration();
15028            }
15029
15030            if (mWindowManager != null) {
15031                mProcessList.applyDisplaySize(mWindowManager);
15032            }
15033
15034            final long origId = Binder.clearCallingIdentity();
15035            if (values != null) {
15036                Settings.System.clearConfiguration(values);
15037            }
15038            updateConfigurationLocked(values, null, false, false);
15039            Binder.restoreCallingIdentity(origId);
15040        }
15041    }
15042
15043    /**
15044     * Do either or both things: (1) change the current configuration, and (2)
15045     * make sure the given activity is running with the (now) current
15046     * configuration.  Returns true if the activity has been left running, or
15047     * false if <var>starting</var> is being destroyed to match the new
15048     * configuration.
15049     * @param persistent TODO
15050     */
15051    boolean updateConfigurationLocked(Configuration values,
15052            ActivityRecord starting, boolean persistent, boolean initLocale) {
15053        int changes = 0;
15054
15055        if (values != null) {
15056            Configuration newConfig = new Configuration(mConfiguration);
15057            changes = newConfig.updateFrom(values);
15058            if (changes != 0) {
15059                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15060                    Slog.i(TAG, "Updating configuration to: " + values);
15061                }
15062
15063                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15064
15065                if (values.locale != null && !initLocale) {
15066                    saveLocaleLocked(values.locale,
15067                                     !values.locale.equals(mConfiguration.locale),
15068                                     values.userSetLocale);
15069                }
15070
15071                mConfigurationSeq++;
15072                if (mConfigurationSeq <= 0) {
15073                    mConfigurationSeq = 1;
15074                }
15075                newConfig.seq = mConfigurationSeq;
15076                mConfiguration = newConfig;
15077                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15078                //mUsageStatsService.noteStartConfig(newConfig);
15079
15080                final Configuration configCopy = new Configuration(mConfiguration);
15081
15082                // TODO: If our config changes, should we auto dismiss any currently
15083                // showing dialogs?
15084                mShowDialogs = shouldShowDialogs(newConfig);
15085
15086                AttributeCache ac = AttributeCache.instance();
15087                if (ac != null) {
15088                    ac.updateConfiguration(configCopy);
15089                }
15090
15091                // Make sure all resources in our process are updated
15092                // right now, so that anyone who is going to retrieve
15093                // resource values after we return will be sure to get
15094                // the new ones.  This is especially important during
15095                // boot, where the first config change needs to guarantee
15096                // all resources have that config before following boot
15097                // code is executed.
15098                mSystemThread.applyConfigurationToResources(configCopy);
15099
15100                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15101                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15102                    msg.obj = new Configuration(configCopy);
15103                    mHandler.sendMessage(msg);
15104                }
15105
15106                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15107                    ProcessRecord app = mLruProcesses.get(i);
15108                    try {
15109                        if (app.thread != null) {
15110                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15111                                    + app.processName + " new config " + mConfiguration);
15112                            app.thread.scheduleConfigurationChanged(configCopy);
15113                        }
15114                    } catch (Exception e) {
15115                    }
15116                }
15117                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15118                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15119                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15120                        | Intent.FLAG_RECEIVER_FOREGROUND);
15121                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15122                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15123                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15124                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15125                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15126                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15127                    broadcastIntentLocked(null, null, intent,
15128                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15129                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15130                }
15131            }
15132        }
15133
15134        boolean kept = true;
15135        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15136        // mainStack is null during startup.
15137        if (mainStack != null) {
15138            if (changes != 0 && starting == null) {
15139                // If the configuration changed, and the caller is not already
15140                // in the process of starting an activity, then find the top
15141                // activity to check if its configuration needs to change.
15142                starting = mainStack.topRunningActivityLocked(null);
15143            }
15144
15145            if (starting != null) {
15146                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15147                // And we need to make sure at this point that all other activities
15148                // are made visible with the correct configuration.
15149                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15150            }
15151        }
15152
15153        if (values != null && mWindowManager != null) {
15154            mWindowManager.setNewConfiguration(mConfiguration);
15155        }
15156
15157        return kept;
15158    }
15159
15160    /**
15161     * Decide based on the configuration whether we should shouw the ANR,
15162     * crash, etc dialogs.  The idea is that if there is no affordnace to
15163     * press the on-screen buttons, we shouldn't show the dialog.
15164     *
15165     * A thought: SystemUI might also want to get told about this, the Power
15166     * dialog / global actions also might want different behaviors.
15167     */
15168    private static final boolean shouldShowDialogs(Configuration config) {
15169        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15170                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15171    }
15172
15173    /**
15174     * Save the locale.  You must be inside a synchronized (this) block.
15175     */
15176    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15177        if(isDiff) {
15178            SystemProperties.set("user.language", l.getLanguage());
15179            SystemProperties.set("user.region", l.getCountry());
15180        }
15181
15182        if(isPersist) {
15183            SystemProperties.set("persist.sys.language", l.getLanguage());
15184            SystemProperties.set("persist.sys.country", l.getCountry());
15185            SystemProperties.set("persist.sys.localevar", l.getVariant());
15186        }
15187    }
15188
15189    @Override
15190    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15191        ActivityRecord srec = ActivityRecord.forToken(token);
15192        return srec != null && srec.task.affinity != null &&
15193                srec.task.affinity.equals(destAffinity);
15194    }
15195
15196    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15197            Intent resultData) {
15198
15199        synchronized (this) {
15200            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15201            if (stack != null) {
15202                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15203            }
15204            return false;
15205        }
15206    }
15207
15208    public int getLaunchedFromUid(IBinder activityToken) {
15209        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15210        if (srec == null) {
15211            return -1;
15212        }
15213        return srec.launchedFromUid;
15214    }
15215
15216    public String getLaunchedFromPackage(IBinder activityToken) {
15217        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15218        if (srec == null) {
15219            return null;
15220        }
15221        return srec.launchedFromPackage;
15222    }
15223
15224    // =========================================================
15225    // LIFETIME MANAGEMENT
15226    // =========================================================
15227
15228    // Returns which broadcast queue the app is the current [or imminent] receiver
15229    // on, or 'null' if the app is not an active broadcast recipient.
15230    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15231        BroadcastRecord r = app.curReceiver;
15232        if (r != null) {
15233            return r.queue;
15234        }
15235
15236        // It's not the current receiver, but it might be starting up to become one
15237        synchronized (this) {
15238            for (BroadcastQueue queue : mBroadcastQueues) {
15239                r = queue.mPendingBroadcast;
15240                if (r != null && r.curApp == app) {
15241                    // found it; report which queue it's in
15242                    return queue;
15243                }
15244            }
15245        }
15246
15247        return null;
15248    }
15249
15250    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15251            boolean doingAll, long now) {
15252        if (mAdjSeq == app.adjSeq) {
15253            // This adjustment has already been computed.
15254            return app.curRawAdj;
15255        }
15256
15257        if (app.thread == null) {
15258            app.adjSeq = mAdjSeq;
15259            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15260            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15261            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15262        }
15263
15264        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15265        app.adjSource = null;
15266        app.adjTarget = null;
15267        app.empty = false;
15268        app.cached = false;
15269
15270        final int activitiesSize = app.activities.size();
15271
15272        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15273            // The max adjustment doesn't allow this app to be anything
15274            // below foreground, so it is not worth doing work for it.
15275            app.adjType = "fixed";
15276            app.adjSeq = mAdjSeq;
15277            app.curRawAdj = app.maxAdj;
15278            app.foregroundActivities = false;
15279            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15280            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15281            // System processes can do UI, and when they do we want to have
15282            // them trim their memory after the user leaves the UI.  To
15283            // facilitate this, here we need to determine whether or not it
15284            // is currently showing UI.
15285            app.systemNoUi = true;
15286            if (app == TOP_APP) {
15287                app.systemNoUi = false;
15288            } else if (activitiesSize > 0) {
15289                for (int j = 0; j < activitiesSize; j++) {
15290                    final ActivityRecord r = app.activities.get(j);
15291                    if (r.visible) {
15292                        app.systemNoUi = false;
15293                    }
15294                }
15295            }
15296            if (!app.systemNoUi) {
15297                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15298            }
15299            return (app.curAdj=app.maxAdj);
15300        }
15301
15302        app.systemNoUi = false;
15303
15304        // Determine the importance of the process, starting with most
15305        // important to least, and assign an appropriate OOM adjustment.
15306        int adj;
15307        int schedGroup;
15308        int procState;
15309        boolean foregroundActivities = false;
15310        BroadcastQueue queue;
15311        if (app == TOP_APP) {
15312            // The last app on the list is the foreground app.
15313            adj = ProcessList.FOREGROUND_APP_ADJ;
15314            schedGroup = Process.THREAD_GROUP_DEFAULT;
15315            app.adjType = "top-activity";
15316            foregroundActivities = true;
15317            procState = ActivityManager.PROCESS_STATE_TOP;
15318        } else if (app.instrumentationClass != null) {
15319            // Don't want to kill running instrumentation.
15320            adj = ProcessList.FOREGROUND_APP_ADJ;
15321            schedGroup = Process.THREAD_GROUP_DEFAULT;
15322            app.adjType = "instrumentation";
15323            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15324        } else if ((queue = isReceivingBroadcast(app)) != null) {
15325            // An app that is currently receiving a broadcast also
15326            // counts as being in the foreground for OOM killer purposes.
15327            // It's placed in a sched group based on the nature of the
15328            // broadcast as reflected by which queue it's active in.
15329            adj = ProcessList.FOREGROUND_APP_ADJ;
15330            schedGroup = (queue == mFgBroadcastQueue)
15331                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15332            app.adjType = "broadcast";
15333            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15334        } else if (app.executingServices.size() > 0) {
15335            // An app that is currently executing a service callback also
15336            // counts as being in the foreground.
15337            adj = ProcessList.FOREGROUND_APP_ADJ;
15338            schedGroup = app.execServicesFg ?
15339                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15340            app.adjType = "exec-service";
15341            procState = ActivityManager.PROCESS_STATE_SERVICE;
15342            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15343        } else {
15344            // As far as we know the process is empty.  We may change our mind later.
15345            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15346            // At this point we don't actually know the adjustment.  Use the cached adj
15347            // value that the caller wants us to.
15348            adj = cachedAdj;
15349            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15350            app.cached = true;
15351            app.empty = true;
15352            app.adjType = "cch-empty";
15353        }
15354
15355        // Examine all activities if not already foreground.
15356        if (!foregroundActivities && activitiesSize > 0) {
15357            for (int j = 0; j < activitiesSize; j++) {
15358                final ActivityRecord r = app.activities.get(j);
15359                if (r.app != app) {
15360                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15361                            + app + "?!?");
15362                    continue;
15363                }
15364                if (r.visible) {
15365                    // App has a visible activity; only upgrade adjustment.
15366                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15367                        adj = ProcessList.VISIBLE_APP_ADJ;
15368                        app.adjType = "visible";
15369                    }
15370                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15371                        procState = ActivityManager.PROCESS_STATE_TOP;
15372                    }
15373                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15374                    app.cached = false;
15375                    app.empty = false;
15376                    foregroundActivities = true;
15377                    break;
15378                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15379                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15380                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15381                        app.adjType = "pausing";
15382                    }
15383                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15384                        procState = ActivityManager.PROCESS_STATE_TOP;
15385                    }
15386                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15387                    app.cached = false;
15388                    app.empty = false;
15389                    foregroundActivities = true;
15390                } else if (r.state == ActivityState.STOPPING) {
15391                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15392                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15393                        app.adjType = "stopping";
15394                    }
15395                    // For the process state, we will at this point consider the
15396                    // process to be cached.  It will be cached either as an activity
15397                    // or empty depending on whether the activity is finishing.  We do
15398                    // this so that we can treat the process as cached for purposes of
15399                    // memory trimming (determing current memory level, trim command to
15400                    // send to process) since there can be an arbitrary number of stopping
15401                    // processes and they should soon all go into the cached state.
15402                    if (!r.finishing) {
15403                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15404                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15405                        }
15406                    }
15407                    app.cached = false;
15408                    app.empty = false;
15409                    foregroundActivities = true;
15410                } else {
15411                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15412                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15413                        app.adjType = "cch-act";
15414                    }
15415                }
15416            }
15417        }
15418
15419        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15420            if (app.foregroundServices) {
15421                // The user is aware of this app, so make it visible.
15422                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15423                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15424                app.cached = false;
15425                app.adjType = "fg-service";
15426                schedGroup = Process.THREAD_GROUP_DEFAULT;
15427            } else if (app.forcingToForeground != null) {
15428                // The user is aware of this app, so make it visible.
15429                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15430                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15431                app.cached = false;
15432                app.adjType = "force-fg";
15433                app.adjSource = app.forcingToForeground;
15434                schedGroup = Process.THREAD_GROUP_DEFAULT;
15435            }
15436        }
15437
15438        if (app == mHeavyWeightProcess) {
15439            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15440                // We don't want to kill the current heavy-weight process.
15441                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15442                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15443                app.cached = false;
15444                app.adjType = "heavy";
15445            }
15446            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15447                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15448            }
15449        }
15450
15451        if (app == mHomeProcess) {
15452            if (adj > ProcessList.HOME_APP_ADJ) {
15453                // This process is hosting what we currently consider to be the
15454                // home app, so we don't want to let it go into the background.
15455                adj = ProcessList.HOME_APP_ADJ;
15456                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15457                app.cached = false;
15458                app.adjType = "home";
15459            }
15460            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15461                procState = ActivityManager.PROCESS_STATE_HOME;
15462            }
15463        }
15464
15465        if (app == mPreviousProcess && app.activities.size() > 0) {
15466            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15467                // This was the previous process that showed UI to the user.
15468                // We want to try to keep it around more aggressively, to give
15469                // a good experience around switching between two apps.
15470                adj = ProcessList.PREVIOUS_APP_ADJ;
15471                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15472                app.cached = false;
15473                app.adjType = "previous";
15474            }
15475            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15476                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15477            }
15478        }
15479
15480        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15481                + " reason=" + app.adjType);
15482
15483        // By default, we use the computed adjustment.  It may be changed if
15484        // there are applications dependent on our services or providers, but
15485        // this gives us a baseline and makes sure we don't get into an
15486        // infinite recursion.
15487        app.adjSeq = mAdjSeq;
15488        app.curRawAdj = adj;
15489        app.hasStartedServices = false;
15490
15491        if (mBackupTarget != null && app == mBackupTarget.app) {
15492            // If possible we want to avoid killing apps while they're being backed up
15493            if (adj > ProcessList.BACKUP_APP_ADJ) {
15494                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15495                adj = ProcessList.BACKUP_APP_ADJ;
15496                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15497                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15498                }
15499                app.adjType = "backup";
15500                app.cached = false;
15501            }
15502            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15503                procState = ActivityManager.PROCESS_STATE_BACKUP;
15504            }
15505        }
15506
15507        boolean mayBeTop = false;
15508
15509        for (int is = app.services.size()-1;
15510                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15511                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15512                        || procState > ActivityManager.PROCESS_STATE_TOP);
15513                is--) {
15514            ServiceRecord s = app.services.valueAt(is);
15515            if (s.startRequested) {
15516                app.hasStartedServices = true;
15517                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15518                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15519                }
15520                if (app.hasShownUi && app != mHomeProcess) {
15521                    // If this process has shown some UI, let it immediately
15522                    // go to the LRU list because it may be pretty heavy with
15523                    // UI stuff.  We'll tag it with a label just to help
15524                    // debug and understand what is going on.
15525                    if (adj > ProcessList.SERVICE_ADJ) {
15526                        app.adjType = "cch-started-ui-services";
15527                    }
15528                } else {
15529                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15530                        // This service has seen some activity within
15531                        // recent memory, so we will keep its process ahead
15532                        // of the background processes.
15533                        if (adj > ProcessList.SERVICE_ADJ) {
15534                            adj = ProcessList.SERVICE_ADJ;
15535                            app.adjType = "started-services";
15536                            app.cached = false;
15537                        }
15538                    }
15539                    // If we have let the service slide into the background
15540                    // state, still have some text describing what it is doing
15541                    // even though the service no longer has an impact.
15542                    if (adj > ProcessList.SERVICE_ADJ) {
15543                        app.adjType = "cch-started-services";
15544                    }
15545                }
15546            }
15547            for (int conni = s.connections.size()-1;
15548                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15549                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15550                            || procState > ActivityManager.PROCESS_STATE_TOP);
15551                    conni--) {
15552                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15553                for (int i = 0;
15554                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15555                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15556                                || procState > ActivityManager.PROCESS_STATE_TOP);
15557                        i++) {
15558                    // XXX should compute this based on the max of
15559                    // all connected clients.
15560                    ConnectionRecord cr = clist.get(i);
15561                    if (cr.binding.client == app) {
15562                        // Binding to ourself is not interesting.
15563                        continue;
15564                    }
15565                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15566                        ProcessRecord client = cr.binding.client;
15567                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15568                                TOP_APP, doingAll, now);
15569                        int clientProcState = client.curProcState;
15570                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15571                            // If the other app is cached for any reason, for purposes here
15572                            // we are going to consider it empty.  The specific cached state
15573                            // doesn't propagate except under certain conditions.
15574                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15575                        }
15576                        String adjType = null;
15577                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15578                            // Not doing bind OOM management, so treat
15579                            // this guy more like a started service.
15580                            if (app.hasShownUi && app != mHomeProcess) {
15581                                // If this process has shown some UI, let it immediately
15582                                // go to the LRU list because it may be pretty heavy with
15583                                // UI stuff.  We'll tag it with a label just to help
15584                                // debug and understand what is going on.
15585                                if (adj > clientAdj) {
15586                                    adjType = "cch-bound-ui-services";
15587                                }
15588                                app.cached = false;
15589                                clientAdj = adj;
15590                                clientProcState = procState;
15591                            } else {
15592                                if (now >= (s.lastActivity
15593                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15594                                    // This service has not seen activity within
15595                                    // recent memory, so allow it to drop to the
15596                                    // LRU list if there is no other reason to keep
15597                                    // it around.  We'll also tag it with a label just
15598                                    // to help debug and undertand what is going on.
15599                                    if (adj > clientAdj) {
15600                                        adjType = "cch-bound-services";
15601                                    }
15602                                    clientAdj = adj;
15603                                }
15604                            }
15605                        }
15606                        if (adj > clientAdj) {
15607                            // If this process has recently shown UI, and
15608                            // the process that is binding to it is less
15609                            // important than being visible, then we don't
15610                            // care about the binding as much as we care
15611                            // about letting this process get into the LRU
15612                            // list to be killed and restarted if needed for
15613                            // memory.
15614                            if (app.hasShownUi && app != mHomeProcess
15615                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15616                                adjType = "cch-bound-ui-services";
15617                            } else {
15618                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15619                                        |Context.BIND_IMPORTANT)) != 0) {
15620                                    adj = clientAdj;
15621                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15622                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15623                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15624                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15625                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15626                                    adj = clientAdj;
15627                                } else {
15628                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15629                                        adj = ProcessList.VISIBLE_APP_ADJ;
15630                                    }
15631                                }
15632                                if (!client.cached) {
15633                                    app.cached = false;
15634                                }
15635                                adjType = "service";
15636                            }
15637                        }
15638                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15639                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15640                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15641                            }
15642                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15643                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15644                                    // Special handling of clients who are in the top state.
15645                                    // We *may* want to consider this process to be in the
15646                                    // top state as well, but only if there is not another
15647                                    // reason for it to be running.  Being on the top is a
15648                                    // special state, meaning you are specifically running
15649                                    // for the current top app.  If the process is already
15650                                    // running in the background for some other reason, it
15651                                    // is more important to continue considering it to be
15652                                    // in the background state.
15653                                    mayBeTop = true;
15654                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15655                                } else {
15656                                    // Special handling for above-top states (persistent
15657                                    // processes).  These should not bring the current process
15658                                    // into the top state, since they are not on top.  Instead
15659                                    // give them the best state after that.
15660                                    clientProcState =
15661                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15662                                }
15663                            }
15664                        } else {
15665                            if (clientProcState <
15666                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15667                                clientProcState =
15668                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15669                            }
15670                        }
15671                        if (procState > clientProcState) {
15672                            procState = clientProcState;
15673                        }
15674                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15675                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15676                            app.pendingUiClean = true;
15677                        }
15678                        if (adjType != null) {
15679                            app.adjType = adjType;
15680                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15681                                    .REASON_SERVICE_IN_USE;
15682                            app.adjSource = cr.binding.client;
15683                            app.adjSourceProcState = clientProcState;
15684                            app.adjTarget = s.name;
15685                        }
15686                    }
15687                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15688                        app.treatLikeActivity = true;
15689                    }
15690                    final ActivityRecord a = cr.activity;
15691                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15692                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15693                                (a.visible || a.state == ActivityState.RESUMED
15694                                 || a.state == ActivityState.PAUSING)) {
15695                            adj = ProcessList.FOREGROUND_APP_ADJ;
15696                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15697                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15698                            }
15699                            app.cached = false;
15700                            app.adjType = "service";
15701                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15702                                    .REASON_SERVICE_IN_USE;
15703                            app.adjSource = a;
15704                            app.adjSourceProcState = procState;
15705                            app.adjTarget = s.name;
15706                        }
15707                    }
15708                }
15709            }
15710        }
15711
15712        for (int provi = app.pubProviders.size()-1;
15713                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15714                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15715                        || procState > ActivityManager.PROCESS_STATE_TOP);
15716                provi--) {
15717            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15718            for (int i = cpr.connections.size()-1;
15719                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15720                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15721                            || procState > ActivityManager.PROCESS_STATE_TOP);
15722                    i--) {
15723                ContentProviderConnection conn = cpr.connections.get(i);
15724                ProcessRecord client = conn.client;
15725                if (client == app) {
15726                    // Being our own client is not interesting.
15727                    continue;
15728                }
15729                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15730                int clientProcState = client.curProcState;
15731                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15732                    // If the other app is cached for any reason, for purposes here
15733                    // we are going to consider it empty.
15734                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15735                }
15736                if (adj > clientAdj) {
15737                    if (app.hasShownUi && app != mHomeProcess
15738                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15739                        app.adjType = "cch-ui-provider";
15740                    } else {
15741                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15742                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15743                        app.adjType = "provider";
15744                    }
15745                    app.cached &= client.cached;
15746                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15747                            .REASON_PROVIDER_IN_USE;
15748                    app.adjSource = client;
15749                    app.adjSourceProcState = clientProcState;
15750                    app.adjTarget = cpr.name;
15751                }
15752                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15753                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15754                        // Special handling of clients who are in the top state.
15755                        // We *may* want to consider this process to be in the
15756                        // top state as well, but only if there is not another
15757                        // reason for it to be running.  Being on the top is a
15758                        // special state, meaning you are specifically running
15759                        // for the current top app.  If the process is already
15760                        // running in the background for some other reason, it
15761                        // is more important to continue considering it to be
15762                        // in the background state.
15763                        mayBeTop = true;
15764                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15765                    } else {
15766                        // Special handling for above-top states (persistent
15767                        // processes).  These should not bring the current process
15768                        // into the top state, since they are not on top.  Instead
15769                        // give them the best state after that.
15770                        clientProcState =
15771                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15772                    }
15773                }
15774                if (procState > clientProcState) {
15775                    procState = clientProcState;
15776                }
15777                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15778                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15779                }
15780            }
15781            // If the provider has external (non-framework) process
15782            // dependencies, ensure that its adjustment is at least
15783            // FOREGROUND_APP_ADJ.
15784            if (cpr.hasExternalProcessHandles()) {
15785                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15786                    adj = ProcessList.FOREGROUND_APP_ADJ;
15787                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15788                    app.cached = false;
15789                    app.adjType = "provider";
15790                    app.adjTarget = cpr.name;
15791                }
15792                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15793                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15794                }
15795            }
15796        }
15797
15798        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15799            // A client of one of our services or providers is in the top state.  We
15800            // *may* want to be in the top state, but not if we are already running in
15801            // the background for some other reason.  For the decision here, we are going
15802            // to pick out a few specific states that we want to remain in when a client
15803            // is top (states that tend to be longer-term) and otherwise allow it to go
15804            // to the top state.
15805            switch (procState) {
15806                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15807                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15808                case ActivityManager.PROCESS_STATE_SERVICE:
15809                    // These all are longer-term states, so pull them up to the top
15810                    // of the background states, but not all the way to the top state.
15811                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15812                    break;
15813                default:
15814                    // Otherwise, top is a better choice, so take it.
15815                    procState = ActivityManager.PROCESS_STATE_TOP;
15816                    break;
15817            }
15818        }
15819
15820        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15821            if (app.hasClientActivities) {
15822                // This is a cached process, but with client activities.  Mark it so.
15823                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15824                app.adjType = "cch-client-act";
15825            } else if (app.treatLikeActivity) {
15826                // This is a cached process, but somebody wants us to treat it like it has
15827                // an activity, okay!
15828                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15829                app.adjType = "cch-as-act";
15830            }
15831        }
15832
15833        if (adj == ProcessList.SERVICE_ADJ) {
15834            if (doingAll) {
15835                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15836                mNewNumServiceProcs++;
15837                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15838                if (!app.serviceb) {
15839                    // This service isn't far enough down on the LRU list to
15840                    // normally be a B service, but if we are low on RAM and it
15841                    // is large we want to force it down since we would prefer to
15842                    // keep launcher over it.
15843                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15844                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15845                        app.serviceHighRam = true;
15846                        app.serviceb = true;
15847                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15848                    } else {
15849                        mNewNumAServiceProcs++;
15850                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15851                    }
15852                } else {
15853                    app.serviceHighRam = false;
15854                }
15855            }
15856            if (app.serviceb) {
15857                adj = ProcessList.SERVICE_B_ADJ;
15858            }
15859        }
15860
15861        app.curRawAdj = adj;
15862
15863        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15864        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15865        if (adj > app.maxAdj) {
15866            adj = app.maxAdj;
15867            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15868                schedGroup = Process.THREAD_GROUP_DEFAULT;
15869            }
15870        }
15871
15872        // Do final modification to adj.  Everything we do between here and applying
15873        // the final setAdj must be done in this function, because we will also use
15874        // it when computing the final cached adj later.  Note that we don't need to
15875        // worry about this for max adj above, since max adj will always be used to
15876        // keep it out of the cached vaues.
15877        app.curAdj = app.modifyRawOomAdj(adj);
15878        app.curSchedGroup = schedGroup;
15879        app.curProcState = procState;
15880        app.foregroundActivities = foregroundActivities;
15881
15882        return app.curRawAdj;
15883    }
15884
15885    /**
15886     * Schedule PSS collection of a process.
15887     */
15888    void requestPssLocked(ProcessRecord proc, int procState) {
15889        if (mPendingPssProcesses.contains(proc)) {
15890            return;
15891        }
15892        if (mPendingPssProcesses.size() == 0) {
15893            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15894        }
15895        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15896        proc.pssProcState = procState;
15897        mPendingPssProcesses.add(proc);
15898    }
15899
15900    /**
15901     * Schedule PSS collection of all processes.
15902     */
15903    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15904        if (!always) {
15905            if (now < (mLastFullPssTime +
15906                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15907                return;
15908            }
15909        }
15910        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15911        mLastFullPssTime = now;
15912        mFullPssPending = true;
15913        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15914        mPendingPssProcesses.clear();
15915        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15916            ProcessRecord app = mLruProcesses.get(i);
15917            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15918                app.pssProcState = app.setProcState;
15919                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15920                        isSleeping(), now);
15921                mPendingPssProcesses.add(app);
15922            }
15923        }
15924        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15925    }
15926
15927    /**
15928     * Ask a given process to GC right now.
15929     */
15930    final void performAppGcLocked(ProcessRecord app) {
15931        try {
15932            app.lastRequestedGc = SystemClock.uptimeMillis();
15933            if (app.thread != null) {
15934                if (app.reportLowMemory) {
15935                    app.reportLowMemory = false;
15936                    app.thread.scheduleLowMemory();
15937                } else {
15938                    app.thread.processInBackground();
15939                }
15940            }
15941        } catch (Exception e) {
15942            // whatever.
15943        }
15944    }
15945
15946    /**
15947     * Returns true if things are idle enough to perform GCs.
15948     */
15949    private final boolean canGcNowLocked() {
15950        boolean processingBroadcasts = false;
15951        for (BroadcastQueue q : mBroadcastQueues) {
15952            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15953                processingBroadcasts = true;
15954            }
15955        }
15956        return !processingBroadcasts
15957                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15958    }
15959
15960    /**
15961     * Perform GCs on all processes that are waiting for it, but only
15962     * if things are idle.
15963     */
15964    final void performAppGcsLocked() {
15965        final int N = mProcessesToGc.size();
15966        if (N <= 0) {
15967            return;
15968        }
15969        if (canGcNowLocked()) {
15970            while (mProcessesToGc.size() > 0) {
15971                ProcessRecord proc = mProcessesToGc.remove(0);
15972                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15973                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15974                            <= SystemClock.uptimeMillis()) {
15975                        // To avoid spamming the system, we will GC processes one
15976                        // at a time, waiting a few seconds between each.
15977                        performAppGcLocked(proc);
15978                        scheduleAppGcsLocked();
15979                        return;
15980                    } else {
15981                        // It hasn't been long enough since we last GCed this
15982                        // process...  put it in the list to wait for its time.
15983                        addProcessToGcListLocked(proc);
15984                        break;
15985                    }
15986                }
15987            }
15988
15989            scheduleAppGcsLocked();
15990        }
15991    }
15992
15993    /**
15994     * If all looks good, perform GCs on all processes waiting for them.
15995     */
15996    final void performAppGcsIfAppropriateLocked() {
15997        if (canGcNowLocked()) {
15998            performAppGcsLocked();
15999            return;
16000        }
16001        // Still not idle, wait some more.
16002        scheduleAppGcsLocked();
16003    }
16004
16005    /**
16006     * Schedule the execution of all pending app GCs.
16007     */
16008    final void scheduleAppGcsLocked() {
16009        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16010
16011        if (mProcessesToGc.size() > 0) {
16012            // Schedule a GC for the time to the next process.
16013            ProcessRecord proc = mProcessesToGc.get(0);
16014            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16015
16016            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16017            long now = SystemClock.uptimeMillis();
16018            if (when < (now+GC_TIMEOUT)) {
16019                when = now + GC_TIMEOUT;
16020            }
16021            mHandler.sendMessageAtTime(msg, when);
16022        }
16023    }
16024
16025    /**
16026     * Add a process to the array of processes waiting to be GCed.  Keeps the
16027     * list in sorted order by the last GC time.  The process can't already be
16028     * on the list.
16029     */
16030    final void addProcessToGcListLocked(ProcessRecord proc) {
16031        boolean added = false;
16032        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16033            if (mProcessesToGc.get(i).lastRequestedGc <
16034                    proc.lastRequestedGc) {
16035                added = true;
16036                mProcessesToGc.add(i+1, proc);
16037                break;
16038            }
16039        }
16040        if (!added) {
16041            mProcessesToGc.add(0, proc);
16042        }
16043    }
16044
16045    /**
16046     * Set up to ask a process to GC itself.  This will either do it
16047     * immediately, or put it on the list of processes to gc the next
16048     * time things are idle.
16049     */
16050    final void scheduleAppGcLocked(ProcessRecord app) {
16051        long now = SystemClock.uptimeMillis();
16052        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16053            return;
16054        }
16055        if (!mProcessesToGc.contains(app)) {
16056            addProcessToGcListLocked(app);
16057            scheduleAppGcsLocked();
16058        }
16059    }
16060
16061    final void checkExcessivePowerUsageLocked(boolean doKills) {
16062        updateCpuStatsNow();
16063
16064        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16065        boolean doWakeKills = doKills;
16066        boolean doCpuKills = doKills;
16067        if (mLastPowerCheckRealtime == 0) {
16068            doWakeKills = false;
16069        }
16070        if (mLastPowerCheckUptime == 0) {
16071            doCpuKills = false;
16072        }
16073        if (stats.isScreenOn()) {
16074            doWakeKills = false;
16075        }
16076        final long curRealtime = SystemClock.elapsedRealtime();
16077        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16078        final long curUptime = SystemClock.uptimeMillis();
16079        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16080        mLastPowerCheckRealtime = curRealtime;
16081        mLastPowerCheckUptime = curUptime;
16082        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16083            doWakeKills = false;
16084        }
16085        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16086            doCpuKills = false;
16087        }
16088        int i = mLruProcesses.size();
16089        while (i > 0) {
16090            i--;
16091            ProcessRecord app = mLruProcesses.get(i);
16092            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16093                long wtime;
16094                synchronized (stats) {
16095                    wtime = stats.getProcessWakeTime(app.info.uid,
16096                            app.pid, curRealtime);
16097                }
16098                long wtimeUsed = wtime - app.lastWakeTime;
16099                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16100                if (DEBUG_POWER) {
16101                    StringBuilder sb = new StringBuilder(128);
16102                    sb.append("Wake for ");
16103                    app.toShortString(sb);
16104                    sb.append(": over ");
16105                    TimeUtils.formatDuration(realtimeSince, sb);
16106                    sb.append(" used ");
16107                    TimeUtils.formatDuration(wtimeUsed, sb);
16108                    sb.append(" (");
16109                    sb.append((wtimeUsed*100)/realtimeSince);
16110                    sb.append("%)");
16111                    Slog.i(TAG, sb.toString());
16112                    sb.setLength(0);
16113                    sb.append("CPU for ");
16114                    app.toShortString(sb);
16115                    sb.append(": over ");
16116                    TimeUtils.formatDuration(uptimeSince, sb);
16117                    sb.append(" used ");
16118                    TimeUtils.formatDuration(cputimeUsed, sb);
16119                    sb.append(" (");
16120                    sb.append((cputimeUsed*100)/uptimeSince);
16121                    sb.append("%)");
16122                    Slog.i(TAG, sb.toString());
16123                }
16124                // If a process has held a wake lock for more
16125                // than 50% of the time during this period,
16126                // that sounds bad.  Kill!
16127                if (doWakeKills && realtimeSince > 0
16128                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16129                    synchronized (stats) {
16130                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16131                                realtimeSince, wtimeUsed);
16132                    }
16133                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16134                            + " during " + realtimeSince);
16135                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16136                } else if (doCpuKills && uptimeSince > 0
16137                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16138                    synchronized (stats) {
16139                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16140                                uptimeSince, cputimeUsed);
16141                    }
16142                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16143                            + " during " + uptimeSince);
16144                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16145                } else {
16146                    app.lastWakeTime = wtime;
16147                    app.lastCpuTime = app.curCpuTime;
16148                }
16149            }
16150        }
16151    }
16152
16153    private final boolean applyOomAdjLocked(ProcessRecord app,
16154            ProcessRecord TOP_APP, boolean doingAll, long now) {
16155        boolean success = true;
16156
16157        if (app.curRawAdj != app.setRawAdj) {
16158            app.setRawAdj = app.curRawAdj;
16159        }
16160
16161        int changes = 0;
16162
16163        if (app.curAdj != app.setAdj) {
16164            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16165            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16166                TAG, "Set " + app.pid + " " + app.processName +
16167                " adj " + app.curAdj + ": " + app.adjType);
16168            app.setAdj = app.curAdj;
16169        }
16170
16171        if (app.setSchedGroup != app.curSchedGroup) {
16172            app.setSchedGroup = app.curSchedGroup;
16173            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16174                    "Setting process group of " + app.processName
16175                    + " to " + app.curSchedGroup);
16176            if (app.waitingToKill != null &&
16177                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16178                killUnneededProcessLocked(app, app.waitingToKill);
16179                success = false;
16180            } else {
16181                if (true) {
16182                    long oldId = Binder.clearCallingIdentity();
16183                    try {
16184                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16185                    } catch (Exception e) {
16186                        Slog.w(TAG, "Failed setting process group of " + app.pid
16187                                + " to " + app.curSchedGroup);
16188                        e.printStackTrace();
16189                    } finally {
16190                        Binder.restoreCallingIdentity(oldId);
16191                    }
16192                } else {
16193                    if (app.thread != null) {
16194                        try {
16195                            app.thread.setSchedulingGroup(app.curSchedGroup);
16196                        } catch (RemoteException e) {
16197                        }
16198                    }
16199                }
16200                Process.setSwappiness(app.pid,
16201                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16202            }
16203        }
16204        if (app.repForegroundActivities != app.foregroundActivities) {
16205            app.repForegroundActivities = app.foregroundActivities;
16206            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16207        }
16208        if (app.repProcState != app.curProcState) {
16209            app.repProcState = app.curProcState;
16210            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16211            if (app.thread != null) {
16212                try {
16213                    if (false) {
16214                        //RuntimeException h = new RuntimeException("here");
16215                        Slog.i(TAG, "Sending new process state " + app.repProcState
16216                                + " to " + app /*, h*/);
16217                    }
16218                    app.thread.setProcessState(app.repProcState);
16219                } catch (RemoteException e) {
16220                }
16221            }
16222        }
16223        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16224                app.setProcState)) {
16225            app.lastStateTime = now;
16226            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16227                    isSleeping(), now);
16228            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16229                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16230                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16231                    + (app.nextPssTime-now) + ": " + app);
16232        } else {
16233            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16234                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16235                requestPssLocked(app, app.setProcState);
16236                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16237                        isSleeping(), now);
16238            } else if (false && DEBUG_PSS) {
16239                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16240            }
16241        }
16242        if (app.setProcState != app.curProcState) {
16243            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16244                    "Proc state change of " + app.processName
16245                    + " to " + app.curProcState);
16246            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16247            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16248            if (setImportant && !curImportant) {
16249                // This app is no longer something we consider important enough to allow to
16250                // use arbitrary amounts of battery power.  Note
16251                // its current wake lock time to later know to kill it if
16252                // it is not behaving well.
16253                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16254                synchronized (stats) {
16255                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16256                            app.pid, SystemClock.elapsedRealtime());
16257                }
16258                app.lastCpuTime = app.curCpuTime;
16259
16260            }
16261            app.setProcState = app.curProcState;
16262            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16263                app.notCachedSinceIdle = false;
16264            }
16265            if (!doingAll) {
16266                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16267            } else {
16268                app.procStateChanged = true;
16269            }
16270        }
16271
16272        if (changes != 0) {
16273            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16274            int i = mPendingProcessChanges.size()-1;
16275            ProcessChangeItem item = null;
16276            while (i >= 0) {
16277                item = mPendingProcessChanges.get(i);
16278                if (item.pid == app.pid) {
16279                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16280                    break;
16281                }
16282                i--;
16283            }
16284            if (i < 0) {
16285                // No existing item in pending changes; need a new one.
16286                final int NA = mAvailProcessChanges.size();
16287                if (NA > 0) {
16288                    item = mAvailProcessChanges.remove(NA-1);
16289                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16290                } else {
16291                    item = new ProcessChangeItem();
16292                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16293                }
16294                item.changes = 0;
16295                item.pid = app.pid;
16296                item.uid = app.info.uid;
16297                if (mPendingProcessChanges.size() == 0) {
16298                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16299                            "*** Enqueueing dispatch processes changed!");
16300                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16301                }
16302                mPendingProcessChanges.add(item);
16303            }
16304            item.changes |= changes;
16305            item.processState = app.repProcState;
16306            item.foregroundActivities = app.repForegroundActivities;
16307            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16308                    + Integer.toHexString(System.identityHashCode(item))
16309                    + " " + app.toShortString() + ": changes=" + item.changes
16310                    + " procState=" + item.processState
16311                    + " foreground=" + item.foregroundActivities
16312                    + " type=" + app.adjType + " source=" + app.adjSource
16313                    + " target=" + app.adjTarget);
16314        }
16315
16316        return success;
16317    }
16318
16319    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16320        if (proc.thread != null) {
16321            if (proc.baseProcessTracker != null) {
16322                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16323            }
16324            if (proc.repProcState >= 0) {
16325                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16326                        proc.repProcState);
16327            }
16328        }
16329    }
16330
16331    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16332            ProcessRecord TOP_APP, boolean doingAll, long now) {
16333        if (app.thread == null) {
16334            return false;
16335        }
16336
16337        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16338
16339        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16340    }
16341
16342    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16343            boolean oomAdj) {
16344        if (isForeground != proc.foregroundServices) {
16345            proc.foregroundServices = isForeground;
16346            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16347                    proc.info.uid);
16348            if (isForeground) {
16349                if (curProcs == null) {
16350                    curProcs = new ArrayList<ProcessRecord>();
16351                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16352                }
16353                if (!curProcs.contains(proc)) {
16354                    curProcs.add(proc);
16355                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16356                            proc.info.packageName, proc.info.uid);
16357                }
16358            } else {
16359                if (curProcs != null) {
16360                    if (curProcs.remove(proc)) {
16361                        mBatteryStatsService.noteEvent(
16362                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16363                                proc.info.packageName, proc.info.uid);
16364                        if (curProcs.size() <= 0) {
16365                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16366                        }
16367                    }
16368                }
16369            }
16370            if (oomAdj) {
16371                updateOomAdjLocked();
16372            }
16373        }
16374    }
16375
16376    private final ActivityRecord resumedAppLocked() {
16377        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16378        String pkg;
16379        int uid;
16380        if (act != null) {
16381            pkg = act.packageName;
16382            uid = act.info.applicationInfo.uid;
16383        } else {
16384            pkg = null;
16385            uid = -1;
16386        }
16387        // Has the UID or resumed package name changed?
16388        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16389                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16390            if (mCurResumedPackage != null) {
16391                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16392                        mCurResumedPackage, mCurResumedUid);
16393            }
16394            mCurResumedPackage = pkg;
16395            mCurResumedUid = uid;
16396            if (mCurResumedPackage != null) {
16397                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16398                        mCurResumedPackage, mCurResumedUid);
16399            }
16400        }
16401        return act;
16402    }
16403
16404    final boolean updateOomAdjLocked(ProcessRecord app) {
16405        final ActivityRecord TOP_ACT = resumedAppLocked();
16406        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16407        final boolean wasCached = app.cached;
16408
16409        mAdjSeq++;
16410
16411        // This is the desired cached adjusment we want to tell it to use.
16412        // If our app is currently cached, we know it, and that is it.  Otherwise,
16413        // we don't know it yet, and it needs to now be cached we will then
16414        // need to do a complete oom adj.
16415        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16416                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16417        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16418                SystemClock.uptimeMillis());
16419        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16420            // Changed to/from cached state, so apps after it in the LRU
16421            // list may also be changed.
16422            updateOomAdjLocked();
16423        }
16424        return success;
16425    }
16426
16427    final void updateOomAdjLocked() {
16428        final ActivityRecord TOP_ACT = resumedAppLocked();
16429        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16430        final long now = SystemClock.uptimeMillis();
16431        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16432        final int N = mLruProcesses.size();
16433
16434        if (false) {
16435            RuntimeException e = new RuntimeException();
16436            e.fillInStackTrace();
16437            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16438        }
16439
16440        mAdjSeq++;
16441        mNewNumServiceProcs = 0;
16442        mNewNumAServiceProcs = 0;
16443
16444        final int emptyProcessLimit;
16445        final int cachedProcessLimit;
16446        if (mProcessLimit <= 0) {
16447            emptyProcessLimit = cachedProcessLimit = 0;
16448        } else if (mProcessLimit == 1) {
16449            emptyProcessLimit = 1;
16450            cachedProcessLimit = 0;
16451        } else {
16452            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16453            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16454        }
16455
16456        // Let's determine how many processes we have running vs.
16457        // how many slots we have for background processes; we may want
16458        // to put multiple processes in a slot of there are enough of
16459        // them.
16460        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16461                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16462        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16463        if (numEmptyProcs > cachedProcessLimit) {
16464            // If there are more empty processes than our limit on cached
16465            // processes, then use the cached process limit for the factor.
16466            // This ensures that the really old empty processes get pushed
16467            // down to the bottom, so if we are running low on memory we will
16468            // have a better chance at keeping around more cached processes
16469            // instead of a gazillion empty processes.
16470            numEmptyProcs = cachedProcessLimit;
16471        }
16472        int emptyFactor = numEmptyProcs/numSlots;
16473        if (emptyFactor < 1) emptyFactor = 1;
16474        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16475        if (cachedFactor < 1) cachedFactor = 1;
16476        int stepCached = 0;
16477        int stepEmpty = 0;
16478        int numCached = 0;
16479        int numEmpty = 0;
16480        int numTrimming = 0;
16481
16482        mNumNonCachedProcs = 0;
16483        mNumCachedHiddenProcs = 0;
16484
16485        // First update the OOM adjustment for each of the
16486        // application processes based on their current state.
16487        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16488        int nextCachedAdj = curCachedAdj+1;
16489        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16490        int nextEmptyAdj = curEmptyAdj+2;
16491        for (int i=N-1; i>=0; i--) {
16492            ProcessRecord app = mLruProcesses.get(i);
16493            if (!app.killedByAm && app.thread != null) {
16494                app.procStateChanged = false;
16495                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16496
16497                // If we haven't yet assigned the final cached adj
16498                // to the process, do that now.
16499                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16500                    switch (app.curProcState) {
16501                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16502                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16503                            // This process is a cached process holding activities...
16504                            // assign it the next cached value for that type, and then
16505                            // step that cached level.
16506                            app.curRawAdj = curCachedAdj;
16507                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16508                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16509                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16510                                    + ")");
16511                            if (curCachedAdj != nextCachedAdj) {
16512                                stepCached++;
16513                                if (stepCached >= cachedFactor) {
16514                                    stepCached = 0;
16515                                    curCachedAdj = nextCachedAdj;
16516                                    nextCachedAdj += 2;
16517                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16518                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16519                                    }
16520                                }
16521                            }
16522                            break;
16523                        default:
16524                            // For everything else, assign next empty cached process
16525                            // level and bump that up.  Note that this means that
16526                            // long-running services that have dropped down to the
16527                            // cached level will be treated as empty (since their process
16528                            // state is still as a service), which is what we want.
16529                            app.curRawAdj = curEmptyAdj;
16530                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16531                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16532                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16533                                    + ")");
16534                            if (curEmptyAdj != nextEmptyAdj) {
16535                                stepEmpty++;
16536                                if (stepEmpty >= emptyFactor) {
16537                                    stepEmpty = 0;
16538                                    curEmptyAdj = nextEmptyAdj;
16539                                    nextEmptyAdj += 2;
16540                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16541                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16542                                    }
16543                                }
16544                            }
16545                            break;
16546                    }
16547                }
16548
16549                applyOomAdjLocked(app, TOP_APP, true, now);
16550
16551                // Count the number of process types.
16552                switch (app.curProcState) {
16553                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16554                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16555                        mNumCachedHiddenProcs++;
16556                        numCached++;
16557                        if (numCached > cachedProcessLimit) {
16558                            killUnneededProcessLocked(app, "cached #" + numCached);
16559                        }
16560                        break;
16561                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16562                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16563                                && app.lastActivityTime < oldTime) {
16564                            killUnneededProcessLocked(app, "empty for "
16565                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16566                                    / 1000) + "s");
16567                        } else {
16568                            numEmpty++;
16569                            if (numEmpty > emptyProcessLimit) {
16570                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16571                            }
16572                        }
16573                        break;
16574                    default:
16575                        mNumNonCachedProcs++;
16576                        break;
16577                }
16578
16579                if (app.isolated && app.services.size() <= 0) {
16580                    // If this is an isolated process, and there are no
16581                    // services running in it, then the process is no longer
16582                    // needed.  We agressively kill these because we can by
16583                    // definition not re-use the same process again, and it is
16584                    // good to avoid having whatever code was running in them
16585                    // left sitting around after no longer needed.
16586                    killUnneededProcessLocked(app, "isolated not needed");
16587                }
16588
16589                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16590                        && !app.killedByAm) {
16591                    numTrimming++;
16592                }
16593            }
16594        }
16595
16596        mNumServiceProcs = mNewNumServiceProcs;
16597
16598        // Now determine the memory trimming level of background processes.
16599        // Unfortunately we need to start at the back of the list to do this
16600        // properly.  We only do this if the number of background apps we
16601        // are managing to keep around is less than half the maximum we desire;
16602        // if we are keeping a good number around, we'll let them use whatever
16603        // memory they want.
16604        final int numCachedAndEmpty = numCached + numEmpty;
16605        int memFactor;
16606        if (numCached <= ProcessList.TRIM_CACHED_APPS
16607                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16608            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16609                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16610            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16611                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16612            } else {
16613                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16614            }
16615        } else {
16616            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16617        }
16618        // We always allow the memory level to go up (better).  We only allow it to go
16619        // down if we are in a state where that is allowed, *and* the total number of processes
16620        // has gone down since last time.
16621        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16622                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16623                + " last=" + mLastNumProcesses);
16624        if (memFactor > mLastMemoryLevel) {
16625            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16626                memFactor = mLastMemoryLevel;
16627                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16628            }
16629        }
16630        mLastMemoryLevel = memFactor;
16631        mLastNumProcesses = mLruProcesses.size();
16632        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16633        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16634        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16635            if (mLowRamStartTime == 0) {
16636                mLowRamStartTime = now;
16637            }
16638            int step = 0;
16639            int fgTrimLevel;
16640            switch (memFactor) {
16641                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16642                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16643                    break;
16644                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16645                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16646                    break;
16647                default:
16648                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16649                    break;
16650            }
16651            int factor = numTrimming/3;
16652            int minFactor = 2;
16653            if (mHomeProcess != null) minFactor++;
16654            if (mPreviousProcess != null) minFactor++;
16655            if (factor < minFactor) factor = minFactor;
16656            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16657            for (int i=N-1; i>=0; i--) {
16658                ProcessRecord app = mLruProcesses.get(i);
16659                if (allChanged || app.procStateChanged) {
16660                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16661                    app.procStateChanged = false;
16662                }
16663                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16664                        && !app.killedByAm) {
16665                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16666                        try {
16667                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16668                                    "Trimming memory of " + app.processName
16669                                    + " to " + curLevel);
16670                            app.thread.scheduleTrimMemory(curLevel);
16671                        } catch (RemoteException e) {
16672                        }
16673                        if (false) {
16674                            // For now we won't do this; our memory trimming seems
16675                            // to be good enough at this point that destroying
16676                            // activities causes more harm than good.
16677                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16678                                    && app != mHomeProcess && app != mPreviousProcess) {
16679                                // Need to do this on its own message because the stack may not
16680                                // be in a consistent state at this point.
16681                                // For these apps we will also finish their activities
16682                                // to help them free memory.
16683                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16684                            }
16685                        }
16686                    }
16687                    app.trimMemoryLevel = curLevel;
16688                    step++;
16689                    if (step >= factor) {
16690                        step = 0;
16691                        switch (curLevel) {
16692                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16693                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16694                                break;
16695                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16696                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16697                                break;
16698                        }
16699                    }
16700                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16701                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16702                            && app.thread != null) {
16703                        try {
16704                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16705                                    "Trimming memory of heavy-weight " + app.processName
16706                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16707                            app.thread.scheduleTrimMemory(
16708                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16709                        } catch (RemoteException e) {
16710                        }
16711                    }
16712                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16713                } else {
16714                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16715                            || app.systemNoUi) && app.pendingUiClean) {
16716                        // If this application is now in the background and it
16717                        // had done UI, then give it the special trim level to
16718                        // have it free UI resources.
16719                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16720                        if (app.trimMemoryLevel < level && app.thread != null) {
16721                            try {
16722                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16723                                        "Trimming memory of bg-ui " + app.processName
16724                                        + " to " + level);
16725                                app.thread.scheduleTrimMemory(level);
16726                            } catch (RemoteException e) {
16727                            }
16728                        }
16729                        app.pendingUiClean = false;
16730                    }
16731                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16732                        try {
16733                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16734                                    "Trimming memory of fg " + app.processName
16735                                    + " to " + fgTrimLevel);
16736                            app.thread.scheduleTrimMemory(fgTrimLevel);
16737                        } catch (RemoteException e) {
16738                        }
16739                    }
16740                    app.trimMemoryLevel = fgTrimLevel;
16741                }
16742            }
16743        } else {
16744            if (mLowRamStartTime != 0) {
16745                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16746                mLowRamStartTime = 0;
16747            }
16748            for (int i=N-1; i>=0; i--) {
16749                ProcessRecord app = mLruProcesses.get(i);
16750                if (allChanged || app.procStateChanged) {
16751                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16752                    app.procStateChanged = false;
16753                }
16754                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16755                        || app.systemNoUi) && app.pendingUiClean) {
16756                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16757                            && app.thread != null) {
16758                        try {
16759                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16760                                    "Trimming memory of ui hidden " + app.processName
16761                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16762                            app.thread.scheduleTrimMemory(
16763                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16764                        } catch (RemoteException e) {
16765                        }
16766                    }
16767                    app.pendingUiClean = false;
16768                }
16769                app.trimMemoryLevel = 0;
16770            }
16771        }
16772
16773        if (mAlwaysFinishActivities) {
16774            // Need to do this on its own message because the stack may not
16775            // be in a consistent state at this point.
16776            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16777        }
16778
16779        if (allChanged) {
16780            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16781        }
16782
16783        if (mProcessStats.shouldWriteNowLocked(now)) {
16784            mHandler.post(new Runnable() {
16785                @Override public void run() {
16786                    synchronized (ActivityManagerService.this) {
16787                        mProcessStats.writeStateAsyncLocked();
16788                    }
16789                }
16790            });
16791        }
16792
16793        if (DEBUG_OOM_ADJ) {
16794            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16795        }
16796    }
16797
16798    final void trimApplications() {
16799        synchronized (this) {
16800            int i;
16801
16802            // First remove any unused application processes whose package
16803            // has been removed.
16804            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16805                final ProcessRecord app = mRemovedProcesses.get(i);
16806                if (app.activities.size() == 0
16807                        && app.curReceiver == null && app.services.size() == 0) {
16808                    Slog.i(
16809                        TAG, "Exiting empty application process "
16810                        + app.processName + " ("
16811                        + (app.thread != null ? app.thread.asBinder() : null)
16812                        + ")\n");
16813                    if (app.pid > 0 && app.pid != MY_PID) {
16814                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16815                                app.processName, app.setAdj, "empty");
16816                        app.killedByAm = true;
16817                        Process.killProcessQuiet(app.pid);
16818                        Process.killProcessGroup(app.info.uid, app.pid);
16819                    } else {
16820                        try {
16821                            app.thread.scheduleExit();
16822                        } catch (Exception e) {
16823                            // Ignore exceptions.
16824                        }
16825                    }
16826                    cleanUpApplicationRecordLocked(app, false, true, -1);
16827                    mRemovedProcesses.remove(i);
16828
16829                    if (app.persistent) {
16830                        addAppLocked(app.info, false, null /* ABI override */);
16831                    }
16832                }
16833            }
16834
16835            // Now update the oom adj for all processes.
16836            updateOomAdjLocked();
16837        }
16838    }
16839
16840    /** This method sends the specified signal to each of the persistent apps */
16841    public void signalPersistentProcesses(int sig) throws RemoteException {
16842        if (sig != Process.SIGNAL_USR1) {
16843            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16844        }
16845
16846        synchronized (this) {
16847            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16848                    != PackageManager.PERMISSION_GRANTED) {
16849                throw new SecurityException("Requires permission "
16850                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16851            }
16852
16853            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16854                ProcessRecord r = mLruProcesses.get(i);
16855                if (r.thread != null && r.persistent) {
16856                    Process.sendSignal(r.pid, sig);
16857                }
16858            }
16859        }
16860    }
16861
16862    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16863        if (proc == null || proc == mProfileProc) {
16864            proc = mProfileProc;
16865            path = mProfileFile;
16866            profileType = mProfileType;
16867            clearProfilerLocked();
16868        }
16869        if (proc == null) {
16870            return;
16871        }
16872        try {
16873            proc.thread.profilerControl(false, path, null, profileType);
16874        } catch (RemoteException e) {
16875            throw new IllegalStateException("Process disappeared");
16876        }
16877    }
16878
16879    private void clearProfilerLocked() {
16880        if (mProfileFd != null) {
16881            try {
16882                mProfileFd.close();
16883            } catch (IOException e) {
16884            }
16885        }
16886        mProfileApp = null;
16887        mProfileProc = null;
16888        mProfileFile = null;
16889        mProfileType = 0;
16890        mAutoStopProfiler = false;
16891    }
16892
16893    public boolean profileControl(String process, int userId, boolean start,
16894            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16895
16896        try {
16897            synchronized (this) {
16898                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16899                // its own permission.
16900                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16901                        != PackageManager.PERMISSION_GRANTED) {
16902                    throw new SecurityException("Requires permission "
16903                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16904                }
16905
16906                if (start && fd == null) {
16907                    throw new IllegalArgumentException("null fd");
16908                }
16909
16910                ProcessRecord proc = null;
16911                if (process != null) {
16912                    proc = findProcessLocked(process, userId, "profileControl");
16913                }
16914
16915                if (start && (proc == null || proc.thread == null)) {
16916                    throw new IllegalArgumentException("Unknown process: " + process);
16917                }
16918
16919                if (start) {
16920                    stopProfilerLocked(null, null, 0);
16921                    setProfileApp(proc.info, proc.processName, path, fd, false);
16922                    mProfileProc = proc;
16923                    mProfileType = profileType;
16924                    try {
16925                        fd = fd.dup();
16926                    } catch (IOException e) {
16927                        fd = null;
16928                    }
16929                    proc.thread.profilerControl(start, path, fd, profileType);
16930                    fd = null;
16931                    mProfileFd = null;
16932                } else {
16933                    stopProfilerLocked(proc, path, profileType);
16934                    if (fd != null) {
16935                        try {
16936                            fd.close();
16937                        } catch (IOException e) {
16938                        }
16939                    }
16940                }
16941
16942                return true;
16943            }
16944        } catch (RemoteException e) {
16945            throw new IllegalStateException("Process disappeared");
16946        } finally {
16947            if (fd != null) {
16948                try {
16949                    fd.close();
16950                } catch (IOException e) {
16951                }
16952            }
16953        }
16954    }
16955
16956    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16957        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16958                userId, true, ALLOW_FULL_ONLY, callName, null);
16959        ProcessRecord proc = null;
16960        try {
16961            int pid = Integer.parseInt(process);
16962            synchronized (mPidsSelfLocked) {
16963                proc = mPidsSelfLocked.get(pid);
16964            }
16965        } catch (NumberFormatException e) {
16966        }
16967
16968        if (proc == null) {
16969            ArrayMap<String, SparseArray<ProcessRecord>> all
16970                    = mProcessNames.getMap();
16971            SparseArray<ProcessRecord> procs = all.get(process);
16972            if (procs != null && procs.size() > 0) {
16973                proc = procs.valueAt(0);
16974                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16975                    for (int i=1; i<procs.size(); i++) {
16976                        ProcessRecord thisProc = procs.valueAt(i);
16977                        if (thisProc.userId == userId) {
16978                            proc = thisProc;
16979                            break;
16980                        }
16981                    }
16982                }
16983            }
16984        }
16985
16986        return proc;
16987    }
16988
16989    public boolean dumpHeap(String process, int userId, boolean managed,
16990            String path, ParcelFileDescriptor fd) throws RemoteException {
16991
16992        try {
16993            synchronized (this) {
16994                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16995                // its own permission (same as profileControl).
16996                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16997                        != PackageManager.PERMISSION_GRANTED) {
16998                    throw new SecurityException("Requires permission "
16999                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17000                }
17001
17002                if (fd == null) {
17003                    throw new IllegalArgumentException("null fd");
17004                }
17005
17006                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17007                if (proc == null || proc.thread == null) {
17008                    throw new IllegalArgumentException("Unknown process: " + process);
17009                }
17010
17011                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17012                if (!isDebuggable) {
17013                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17014                        throw new SecurityException("Process not debuggable: " + proc);
17015                    }
17016                }
17017
17018                proc.thread.dumpHeap(managed, path, fd);
17019                fd = null;
17020                return true;
17021            }
17022        } catch (RemoteException e) {
17023            throw new IllegalStateException("Process disappeared");
17024        } finally {
17025            if (fd != null) {
17026                try {
17027                    fd.close();
17028                } catch (IOException e) {
17029                }
17030            }
17031        }
17032    }
17033
17034    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17035    public void monitor() {
17036        synchronized (this) { }
17037    }
17038
17039    void onCoreSettingsChange(Bundle settings) {
17040        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17041            ProcessRecord processRecord = mLruProcesses.get(i);
17042            try {
17043                if (processRecord.thread != null) {
17044                    processRecord.thread.setCoreSettings(settings);
17045                }
17046            } catch (RemoteException re) {
17047                /* ignore */
17048            }
17049        }
17050    }
17051
17052    // Multi-user methods
17053
17054    /**
17055     * Start user, if its not already running, but don't bring it to foreground.
17056     */
17057    @Override
17058    public boolean startUserInBackground(final int userId) {
17059        return startUser(userId, /* foreground */ false);
17060    }
17061
17062    /**
17063     * Refreshes the list of users related to the current user when either a
17064     * user switch happens or when a new related user is started in the
17065     * background.
17066     */
17067    private void updateCurrentProfileIdsLocked() {
17068        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17069                mCurrentUserId, false /* enabledOnly */);
17070        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17071        for (int i = 0; i < currentProfileIds.length; i++) {
17072            currentProfileIds[i] = profiles.get(i).id;
17073        }
17074        mCurrentProfileIds = currentProfileIds;
17075
17076        synchronized (mUserProfileGroupIdsSelfLocked) {
17077            mUserProfileGroupIdsSelfLocked.clear();
17078            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17079            for (int i = 0; i < users.size(); i++) {
17080                UserInfo user = users.get(i);
17081                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17082                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17083                }
17084            }
17085        }
17086    }
17087
17088    private Set getProfileIdsLocked(int userId) {
17089        Set userIds = new HashSet<Integer>();
17090        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17091                userId, false /* enabledOnly */);
17092        for (UserInfo user : profiles) {
17093            userIds.add(Integer.valueOf(user.id));
17094        }
17095        return userIds;
17096    }
17097
17098    @Override
17099    public boolean switchUser(final int userId) {
17100        return startUser(userId, /* foregound */ true);
17101    }
17102
17103    private boolean startUser(final int userId, boolean foreground) {
17104        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17105                != PackageManager.PERMISSION_GRANTED) {
17106            String msg = "Permission Denial: switchUser() from pid="
17107                    + Binder.getCallingPid()
17108                    + ", uid=" + Binder.getCallingUid()
17109                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17110            Slog.w(TAG, msg);
17111            throw new SecurityException(msg);
17112        }
17113
17114        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17115
17116        final long ident = Binder.clearCallingIdentity();
17117        try {
17118            synchronized (this) {
17119                final int oldUserId = mCurrentUserId;
17120                if (oldUserId == userId) {
17121                    return true;
17122                }
17123
17124                mStackSupervisor.setLockTaskModeLocked(null, false);
17125
17126                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17127                if (userInfo == null) {
17128                    Slog.w(TAG, "No user info for user #" + userId);
17129                    return false;
17130                }
17131
17132                if (foreground) {
17133                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17134                            R.anim.screen_user_enter);
17135                }
17136
17137                boolean needStart = false;
17138
17139                // If the user we are switching to is not currently started, then
17140                // we need to start it now.
17141                if (mStartedUsers.get(userId) == null) {
17142                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17143                    updateStartedUserArrayLocked();
17144                    needStart = true;
17145                }
17146
17147                final Integer userIdInt = Integer.valueOf(userId);
17148                mUserLru.remove(userIdInt);
17149                mUserLru.add(userIdInt);
17150
17151                if (foreground) {
17152                    mCurrentUserId = userId;
17153                    updateCurrentProfileIdsLocked();
17154                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17155                    // Once the internal notion of the active user has switched, we lock the device
17156                    // with the option to show the user switcher on the keyguard.
17157                    mWindowManager.lockNow(null);
17158                } else {
17159                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17160                    updateCurrentProfileIdsLocked();
17161                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17162                    mUserLru.remove(currentUserIdInt);
17163                    mUserLru.add(currentUserIdInt);
17164                }
17165
17166                final UserStartedState uss = mStartedUsers.get(userId);
17167
17168                // Make sure user is in the started state.  If it is currently
17169                // stopping, we need to knock that off.
17170                if (uss.mState == UserStartedState.STATE_STOPPING) {
17171                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17172                    // so we can just fairly silently bring the user back from
17173                    // the almost-dead.
17174                    uss.mState = UserStartedState.STATE_RUNNING;
17175                    updateStartedUserArrayLocked();
17176                    needStart = true;
17177                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17178                    // This means ACTION_SHUTDOWN has been sent, so we will
17179                    // need to treat this as a new boot of the user.
17180                    uss.mState = UserStartedState.STATE_BOOTING;
17181                    updateStartedUserArrayLocked();
17182                    needStart = true;
17183                }
17184
17185                if (uss.mState == UserStartedState.STATE_BOOTING) {
17186                    // Booting up a new user, need to tell system services about it.
17187                    // Note that this is on the same handler as scheduling of broadcasts,
17188                    // which is important because it needs to go first.
17189                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
17190                }
17191
17192                if (foreground) {
17193                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17194                            oldUserId));
17195                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17196                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17197                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17198                            oldUserId, userId, uss));
17199                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17200                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17201                }
17202
17203                if (needStart) {
17204                    // Send USER_STARTED broadcast
17205                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17206                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17207                            | Intent.FLAG_RECEIVER_FOREGROUND);
17208                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17209                    broadcastIntentLocked(null, null, intent,
17210                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17211                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17212                }
17213
17214                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17215                    if (userId != UserHandle.USER_OWNER) {
17216                        // Send PRE_BOOT_COMPLETED broadcasts for this new user
17217                        final ArrayList<ComponentName> doneReceivers
17218                                = new ArrayList<ComponentName>();
17219                        deliverPreBootCompleted(null, doneReceivers, userId);
17220
17221                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17222                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17223                        broadcastIntentLocked(null, null, intent, null,
17224                                new IIntentReceiver.Stub() {
17225                                    public void performReceive(Intent intent, int resultCode,
17226                                            String data, Bundle extras, boolean ordered,
17227                                            boolean sticky, int sendingUser) {
17228                                        userInitialized(uss, userId);
17229                                    }
17230                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17231                                true, false, MY_PID, Process.SYSTEM_UID,
17232                                userId);
17233                        uss.initializing = true;
17234                    } else {
17235                        getUserManagerLocked().makeInitialized(userInfo.id);
17236                    }
17237                }
17238
17239                if (foreground) {
17240                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17241                    if (homeInFront) {
17242                        startHomeActivityLocked(userId);
17243                    } else {
17244                        mStackSupervisor.resumeTopActivitiesLocked();
17245                    }
17246                    EventLogTags.writeAmSwitchUser(userId);
17247                    getUserManagerLocked().userForeground(userId);
17248                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17249                } else {
17250                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17251                }
17252
17253                if (needStart) {
17254                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17255                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17256                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17257                    broadcastIntentLocked(null, null, intent,
17258                            null, new IIntentReceiver.Stub() {
17259                                @Override
17260                                public void performReceive(Intent intent, int resultCode, String data,
17261                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17262                                        throws RemoteException {
17263                                }
17264                            }, 0, null, null,
17265                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17266                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17267                }
17268            }
17269        } finally {
17270            Binder.restoreCallingIdentity(ident);
17271        }
17272
17273        return true;
17274    }
17275
17276    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17277        long ident = Binder.clearCallingIdentity();
17278        try {
17279            Intent intent;
17280            if (oldUserId >= 0) {
17281                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17282                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17283                int count = profiles.size();
17284                for (int i = 0; i < count; i++) {
17285                    int profileUserId = profiles.get(i).id;
17286                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17287                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17288                            | Intent.FLAG_RECEIVER_FOREGROUND);
17289                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17290                    broadcastIntentLocked(null, null, intent,
17291                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17292                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17293                }
17294            }
17295            if (newUserId >= 0) {
17296                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17297                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17298                int count = profiles.size();
17299                for (int i = 0; i < count; i++) {
17300                    int profileUserId = profiles.get(i).id;
17301                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17302                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17303                            | Intent.FLAG_RECEIVER_FOREGROUND);
17304                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17305                    broadcastIntentLocked(null, null, intent,
17306                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17307                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17308                }
17309                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17310                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17311                        | Intent.FLAG_RECEIVER_FOREGROUND);
17312                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17313                broadcastIntentLocked(null, null, intent,
17314                        null, null, 0, null, null,
17315                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17316                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17317            }
17318        } finally {
17319            Binder.restoreCallingIdentity(ident);
17320        }
17321    }
17322
17323    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17324            final int newUserId) {
17325        final int N = mUserSwitchObservers.beginBroadcast();
17326        if (N > 0) {
17327            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17328                int mCount = 0;
17329                @Override
17330                public void sendResult(Bundle data) throws RemoteException {
17331                    synchronized (ActivityManagerService.this) {
17332                        if (mCurUserSwitchCallback == this) {
17333                            mCount++;
17334                            if (mCount == N) {
17335                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17336                            }
17337                        }
17338                    }
17339                }
17340            };
17341            synchronized (this) {
17342                uss.switching = true;
17343                mCurUserSwitchCallback = callback;
17344            }
17345            for (int i=0; i<N; i++) {
17346                try {
17347                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17348                            newUserId, callback);
17349                } catch (RemoteException e) {
17350                }
17351            }
17352        } else {
17353            synchronized (this) {
17354                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17355            }
17356        }
17357        mUserSwitchObservers.finishBroadcast();
17358    }
17359
17360    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17361        synchronized (this) {
17362            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17363            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17364        }
17365    }
17366
17367    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17368        mCurUserSwitchCallback = null;
17369        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17370        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17371                oldUserId, newUserId, uss));
17372    }
17373
17374    void userInitialized(UserStartedState uss, int newUserId) {
17375        completeSwitchAndInitalize(uss, newUserId, true, false);
17376    }
17377
17378    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17379        completeSwitchAndInitalize(uss, newUserId, false, true);
17380    }
17381
17382    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17383            boolean clearInitializing, boolean clearSwitching) {
17384        boolean unfrozen = false;
17385        synchronized (this) {
17386            if (clearInitializing) {
17387                uss.initializing = false;
17388                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17389            }
17390            if (clearSwitching) {
17391                uss.switching = false;
17392            }
17393            if (!uss.switching && !uss.initializing) {
17394                mWindowManager.stopFreezingScreen();
17395                unfrozen = true;
17396            }
17397        }
17398        if (unfrozen) {
17399            final int N = mUserSwitchObservers.beginBroadcast();
17400            for (int i=0; i<N; i++) {
17401                try {
17402                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17403                } catch (RemoteException e) {
17404                }
17405            }
17406            mUserSwitchObservers.finishBroadcast();
17407        }
17408    }
17409
17410    void scheduleStartProfilesLocked() {
17411        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17412            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17413                    DateUtils.SECOND_IN_MILLIS);
17414        }
17415    }
17416
17417    void startProfilesLocked() {
17418        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17419        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17420                mCurrentUserId, false /* enabledOnly */);
17421        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17422        for (UserInfo user : profiles) {
17423            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17424                    && user.id != mCurrentUserId) {
17425                toStart.add(user);
17426            }
17427        }
17428        final int n = toStart.size();
17429        int i = 0;
17430        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17431            startUserInBackground(toStart.get(i).id);
17432        }
17433        if (i < n) {
17434            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17435        }
17436    }
17437
17438    void finishUserBoot(UserStartedState uss) {
17439        synchronized (this) {
17440            if (uss.mState == UserStartedState.STATE_BOOTING
17441                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17442                uss.mState = UserStartedState.STATE_RUNNING;
17443                final int userId = uss.mHandle.getIdentifier();
17444                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17445                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17446                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17447                broadcastIntentLocked(null, null, intent,
17448                        null, null, 0, null, null,
17449                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17450                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17451            }
17452        }
17453    }
17454
17455    void finishUserSwitch(UserStartedState uss) {
17456        synchronized (this) {
17457            finishUserBoot(uss);
17458
17459            startProfilesLocked();
17460
17461            int num = mUserLru.size();
17462            int i = 0;
17463            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17464                Integer oldUserId = mUserLru.get(i);
17465                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17466                if (oldUss == null) {
17467                    // Shouldn't happen, but be sane if it does.
17468                    mUserLru.remove(i);
17469                    num--;
17470                    continue;
17471                }
17472                if (oldUss.mState == UserStartedState.STATE_STOPPING
17473                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17474                    // This user is already stopping, doesn't count.
17475                    num--;
17476                    i++;
17477                    continue;
17478                }
17479                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17480                    // Owner and current can't be stopped, but count as running.
17481                    i++;
17482                    continue;
17483                }
17484                // This is a user to be stopped.
17485                stopUserLocked(oldUserId, null);
17486                num--;
17487                i++;
17488            }
17489        }
17490    }
17491
17492    @Override
17493    public int stopUser(final int userId, final IStopUserCallback callback) {
17494        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17495                != PackageManager.PERMISSION_GRANTED) {
17496            String msg = "Permission Denial: switchUser() from pid="
17497                    + Binder.getCallingPid()
17498                    + ", uid=" + Binder.getCallingUid()
17499                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17500            Slog.w(TAG, msg);
17501            throw new SecurityException(msg);
17502        }
17503        if (userId <= 0) {
17504            throw new IllegalArgumentException("Can't stop primary user " + userId);
17505        }
17506        synchronized (this) {
17507            return stopUserLocked(userId, callback);
17508        }
17509    }
17510
17511    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17512        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17513        if (mCurrentUserId == userId) {
17514            return ActivityManager.USER_OP_IS_CURRENT;
17515        }
17516
17517        final UserStartedState uss = mStartedUsers.get(userId);
17518        if (uss == null) {
17519            // User is not started, nothing to do...  but we do need to
17520            // callback if requested.
17521            if (callback != null) {
17522                mHandler.post(new Runnable() {
17523                    @Override
17524                    public void run() {
17525                        try {
17526                            callback.userStopped(userId);
17527                        } catch (RemoteException e) {
17528                        }
17529                    }
17530                });
17531            }
17532            return ActivityManager.USER_OP_SUCCESS;
17533        }
17534
17535        if (callback != null) {
17536            uss.mStopCallbacks.add(callback);
17537        }
17538
17539        if (uss.mState != UserStartedState.STATE_STOPPING
17540                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17541            uss.mState = UserStartedState.STATE_STOPPING;
17542            updateStartedUserArrayLocked();
17543
17544            long ident = Binder.clearCallingIdentity();
17545            try {
17546                // We are going to broadcast ACTION_USER_STOPPING and then
17547                // once that is done send a final ACTION_SHUTDOWN and then
17548                // stop the user.
17549                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17550                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17551                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17552                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17553                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17554                // This is the result receiver for the final shutdown broadcast.
17555                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17556                    @Override
17557                    public void performReceive(Intent intent, int resultCode, String data,
17558                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17559                        finishUserStop(uss);
17560                    }
17561                };
17562                // This is the result receiver for the initial stopping broadcast.
17563                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17564                    @Override
17565                    public void performReceive(Intent intent, int resultCode, String data,
17566                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17567                        // On to the next.
17568                        synchronized (ActivityManagerService.this) {
17569                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17570                                // Whoops, we are being started back up.  Abort, abort!
17571                                return;
17572                            }
17573                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17574                        }
17575                        mBatteryStatsService.noteEvent(
17576                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17577                                Integer.toString(userId), userId);
17578                        mSystemServiceManager.stopUser(userId);
17579                        broadcastIntentLocked(null, null, shutdownIntent,
17580                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17581                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17582                    }
17583                };
17584                // Kick things off.
17585                broadcastIntentLocked(null, null, stoppingIntent,
17586                        null, stoppingReceiver, 0, null, null,
17587                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17588                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17589            } finally {
17590                Binder.restoreCallingIdentity(ident);
17591            }
17592        }
17593
17594        return ActivityManager.USER_OP_SUCCESS;
17595    }
17596
17597    void finishUserStop(UserStartedState uss) {
17598        final int userId = uss.mHandle.getIdentifier();
17599        boolean stopped;
17600        ArrayList<IStopUserCallback> callbacks;
17601        synchronized (this) {
17602            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17603            if (mStartedUsers.get(userId) != uss) {
17604                stopped = false;
17605            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17606                stopped = false;
17607            } else {
17608                stopped = true;
17609                // User can no longer run.
17610                mStartedUsers.remove(userId);
17611                mUserLru.remove(Integer.valueOf(userId));
17612                updateStartedUserArrayLocked();
17613
17614                // Clean up all state and processes associated with the user.
17615                // Kill all the processes for the user.
17616                forceStopUserLocked(userId, "finish user");
17617            }
17618        }
17619
17620        for (int i=0; i<callbacks.size(); i++) {
17621            try {
17622                if (stopped) callbacks.get(i).userStopped(userId);
17623                else callbacks.get(i).userStopAborted(userId);
17624            } catch (RemoteException e) {
17625            }
17626        }
17627
17628        if (stopped) {
17629            mSystemServiceManager.cleanupUser(userId);
17630            synchronized (this) {
17631                mStackSupervisor.removeUserLocked(userId);
17632            }
17633        }
17634    }
17635
17636    @Override
17637    public UserInfo getCurrentUser() {
17638        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17639                != PackageManager.PERMISSION_GRANTED) && (
17640                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17641                != PackageManager.PERMISSION_GRANTED)) {
17642            String msg = "Permission Denial: getCurrentUser() from pid="
17643                    + Binder.getCallingPid()
17644                    + ", uid=" + Binder.getCallingUid()
17645                    + " requires " + INTERACT_ACROSS_USERS;
17646            Slog.w(TAG, msg);
17647            throw new SecurityException(msg);
17648        }
17649        synchronized (this) {
17650            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17651        }
17652    }
17653
17654    int getCurrentUserIdLocked() {
17655        return mCurrentUserId;
17656    }
17657
17658    @Override
17659    public boolean isUserRunning(int userId, boolean orStopped) {
17660        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17661                != PackageManager.PERMISSION_GRANTED) {
17662            String msg = "Permission Denial: isUserRunning() from pid="
17663                    + Binder.getCallingPid()
17664                    + ", uid=" + Binder.getCallingUid()
17665                    + " requires " + INTERACT_ACROSS_USERS;
17666            Slog.w(TAG, msg);
17667            throw new SecurityException(msg);
17668        }
17669        synchronized (this) {
17670            return isUserRunningLocked(userId, orStopped);
17671        }
17672    }
17673
17674    boolean isUserRunningLocked(int userId, boolean orStopped) {
17675        UserStartedState state = mStartedUsers.get(userId);
17676        if (state == null) {
17677            return false;
17678        }
17679        if (orStopped) {
17680            return true;
17681        }
17682        return state.mState != UserStartedState.STATE_STOPPING
17683                && state.mState != UserStartedState.STATE_SHUTDOWN;
17684    }
17685
17686    @Override
17687    public int[] getRunningUserIds() {
17688        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17689                != PackageManager.PERMISSION_GRANTED) {
17690            String msg = "Permission Denial: isUserRunning() from pid="
17691                    + Binder.getCallingPid()
17692                    + ", uid=" + Binder.getCallingUid()
17693                    + " requires " + INTERACT_ACROSS_USERS;
17694            Slog.w(TAG, msg);
17695            throw new SecurityException(msg);
17696        }
17697        synchronized (this) {
17698            return mStartedUserArray;
17699        }
17700    }
17701
17702    private void updateStartedUserArrayLocked() {
17703        int num = 0;
17704        for (int i=0; i<mStartedUsers.size();  i++) {
17705            UserStartedState uss = mStartedUsers.valueAt(i);
17706            // This list does not include stopping users.
17707            if (uss.mState != UserStartedState.STATE_STOPPING
17708                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17709                num++;
17710            }
17711        }
17712        mStartedUserArray = new int[num];
17713        num = 0;
17714        for (int i=0; i<mStartedUsers.size();  i++) {
17715            UserStartedState uss = mStartedUsers.valueAt(i);
17716            if (uss.mState != UserStartedState.STATE_STOPPING
17717                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17718                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17719                num++;
17720            }
17721        }
17722    }
17723
17724    @Override
17725    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17726        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17727                != PackageManager.PERMISSION_GRANTED) {
17728            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17729                    + Binder.getCallingPid()
17730                    + ", uid=" + Binder.getCallingUid()
17731                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17732            Slog.w(TAG, msg);
17733            throw new SecurityException(msg);
17734        }
17735
17736        mUserSwitchObservers.register(observer);
17737    }
17738
17739    @Override
17740    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17741        mUserSwitchObservers.unregister(observer);
17742    }
17743
17744    private boolean userExists(int userId) {
17745        if (userId == 0) {
17746            return true;
17747        }
17748        UserManagerService ums = getUserManagerLocked();
17749        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17750    }
17751
17752    int[] getUsersLocked() {
17753        UserManagerService ums = getUserManagerLocked();
17754        return ums != null ? ums.getUserIds() : new int[] { 0 };
17755    }
17756
17757    UserManagerService getUserManagerLocked() {
17758        if (mUserManager == null) {
17759            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17760            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17761        }
17762        return mUserManager;
17763    }
17764
17765    private int applyUserId(int uid, int userId) {
17766        return UserHandle.getUid(userId, uid);
17767    }
17768
17769    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17770        if (info == null) return null;
17771        ApplicationInfo newInfo = new ApplicationInfo(info);
17772        newInfo.uid = applyUserId(info.uid, userId);
17773        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17774                + info.packageName;
17775        return newInfo;
17776    }
17777
17778    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17779        if (aInfo == null
17780                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17781            return aInfo;
17782        }
17783
17784        ActivityInfo info = new ActivityInfo(aInfo);
17785        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17786        return info;
17787    }
17788
17789    private final class LocalService extends ActivityManagerInternal {
17790        @Override
17791        public void goingToSleep() {
17792            ActivityManagerService.this.goingToSleep();
17793        }
17794
17795        @Override
17796        public void wakingUp() {
17797            ActivityManagerService.this.wakingUp();
17798        }
17799    }
17800
17801    /**
17802     * An implementation of IAppTask, that allows an app to manage its own tasks via
17803     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17804     * only the process that calls getAppTasks() can call the AppTask methods.
17805     */
17806    class AppTaskImpl extends IAppTask.Stub {
17807        private int mTaskId;
17808        private int mCallingUid;
17809
17810        public AppTaskImpl(int taskId, int callingUid) {
17811            mTaskId = taskId;
17812            mCallingUid = callingUid;
17813        }
17814
17815        @Override
17816        public void finishAndRemoveTask() {
17817            // Ensure that we are called from the same process that created this AppTask
17818            if (mCallingUid != Binder.getCallingUid()) {
17819                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17820                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17821                return;
17822            }
17823
17824            synchronized (ActivityManagerService.this) {
17825                long origId = Binder.clearCallingIdentity();
17826                try {
17827                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17828                    if (tr != null) {
17829                        // Only kill the process if we are not a new document
17830                        int flags = tr.getBaseIntent().getFlags();
17831                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17832                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17833                        removeTaskByIdLocked(mTaskId,
17834                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17835                    }
17836                } finally {
17837                    Binder.restoreCallingIdentity(origId);
17838                }
17839            }
17840        }
17841
17842        @Override
17843        public ActivityManager.RecentTaskInfo getTaskInfo() {
17844            // Ensure that we are called from the same process that created this AppTask
17845            if (mCallingUid != Binder.getCallingUid()) {
17846                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17847                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17848                return null;
17849            }
17850
17851            synchronized (ActivityManagerService.this) {
17852                long origId = Binder.clearCallingIdentity();
17853                try {
17854                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17855                    if (tr != null) {
17856                        return createRecentTaskInfoFromTaskRecord(tr);
17857                    }
17858                } finally {
17859                    Binder.restoreCallingIdentity(origId);
17860                }
17861                return null;
17862            }
17863        }
17864    }
17865}
17866