ActivityManagerService.java revision 41c1ded7f042a4cf303479550b38fa66d7a18906
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.IActivityContainer;
37import android.app.IActivityContainerCallback;
38import android.app.IAppTask;
39import android.app.admin.DevicePolicyManager;
40import android.app.usage.UsageStats;
41import android.app.usage.UsageStatsManagerInternal;
42import android.appwidget.AppWidgetManager;
43import android.graphics.Rect;
44import android.os.BatteryStats;
45import android.os.PersistableBundle;
46import android.service.voice.IVoiceInteractionSession;
47import android.util.ArrayMap;
48import android.util.ArraySet;
49import android.util.SparseIntArray;
50
51import com.android.internal.R;
52import com.android.internal.annotations.GuardedBy;
53import com.android.internal.app.IAppOpsService;
54import com.android.internal.app.IVoiceInteractor;
55import com.android.internal.app.ProcessMap;
56import com.android.internal.app.ProcessStats;
57import com.android.internal.content.PackageMonitor;
58import com.android.internal.os.BackgroundThread;
59import com.android.internal.os.BatteryStatsImpl;
60import com.android.internal.os.ProcessCpuTracker;
61import com.android.internal.os.TransferPipe;
62import com.android.internal.os.Zygote;
63import com.android.internal.util.FastPrintWriter;
64import com.android.internal.util.FastXmlSerializer;
65import com.android.internal.util.MemInfoReader;
66import com.android.internal.util.Preconditions;
67import com.android.server.AppOpsService;
68import com.android.server.AttributeCache;
69import com.android.server.IntentResolver;
70import com.android.server.LocalServices;
71import com.android.server.ServiceThread;
72import com.android.server.SystemService;
73import com.android.server.SystemServiceManager;
74import com.android.server.Watchdog;
75import com.android.server.am.ActivityStack.ActivityState;
76import com.android.server.firewall.IntentFirewall;
77import com.android.server.pm.UserManagerService;
78import com.android.server.wm.AppTransition;
79import com.android.server.wm.WindowManagerService;
80import com.google.android.collect.Lists;
81import com.google.android.collect.Maps;
82
83import libcore.io.IoUtils;
84
85import org.xmlpull.v1.XmlPullParser;
86import org.xmlpull.v1.XmlPullParserException;
87import org.xmlpull.v1.XmlSerializer;
88
89import android.app.Activity;
90import android.app.ActivityManager;
91import android.app.ActivityManager.RunningTaskInfo;
92import android.app.ActivityManager.StackInfo;
93import android.app.ActivityManagerInternal;
94import android.app.ActivityManagerNative;
95import android.app.ActivityOptions;
96import android.app.ActivityThread;
97import android.app.AlertDialog;
98import android.app.AppGlobals;
99import android.app.ApplicationErrorReport;
100import android.app.Dialog;
101import android.app.IActivityController;
102import android.app.IApplicationThread;
103import android.app.IInstrumentationWatcher;
104import android.app.INotificationManager;
105import android.app.IProcessObserver;
106import android.app.IServiceConnection;
107import android.app.IStopUserCallback;
108import android.app.IUiAutomationConnection;
109import android.app.IUserSwitchObserver;
110import android.app.Instrumentation;
111import android.app.Notification;
112import android.app.NotificationManager;
113import android.app.PendingIntent;
114import android.app.backup.IBackupManager;
115import android.content.ActivityNotFoundException;
116import android.content.BroadcastReceiver;
117import android.content.ClipData;
118import android.content.ComponentCallbacks2;
119import android.content.ComponentName;
120import android.content.ContentProvider;
121import android.content.ContentResolver;
122import android.content.Context;
123import android.content.DialogInterface;
124import android.content.IContentProvider;
125import android.content.IIntentReceiver;
126import android.content.IIntentSender;
127import android.content.Intent;
128import android.content.IntentFilter;
129import android.content.IntentSender;
130import android.content.pm.ActivityInfo;
131import android.content.pm.ApplicationInfo;
132import android.content.pm.ConfigurationInfo;
133import android.content.pm.IPackageDataObserver;
134import android.content.pm.IPackageManager;
135import android.content.pm.InstrumentationInfo;
136import android.content.pm.PackageInfo;
137import android.content.pm.PackageManager;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.UserInfo;
140import android.content.pm.PackageManager.NameNotFoundException;
141import android.content.pm.PathPermission;
142import android.content.pm.ProviderInfo;
143import android.content.pm.ResolveInfo;
144import android.content.pm.ServiceInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.net.Proxy;
148import android.net.ProxyInfo;
149import android.net.Uri;
150import android.os.Binder;
151import android.os.Build;
152import android.os.Bundle;
153import android.os.Debug;
154import android.os.DropBoxManager;
155import android.os.Environment;
156import android.os.FactoryTest;
157import android.os.FileObserver;
158import android.os.FileUtils;
159import android.os.Handler;
160import android.os.IBinder;
161import android.os.IPermissionController;
162import android.os.IRemoteCallback;
163import android.os.IUserManager;
164import android.os.Looper;
165import android.os.Message;
166import android.os.Parcel;
167import android.os.ParcelFileDescriptor;
168import android.os.Process;
169import android.os.RemoteCallbackList;
170import android.os.RemoteException;
171import android.os.SELinux;
172import android.os.ServiceManager;
173import android.os.StrictMode;
174import android.os.SystemClock;
175import android.os.SystemProperties;
176import android.os.UpdateLock;
177import android.os.UserHandle;
178import android.provider.Settings;
179import android.text.format.DateUtils;
180import android.text.format.Time;
181import android.util.AtomicFile;
182import android.util.EventLog;
183import android.util.Log;
184import android.util.Pair;
185import android.util.PrintWriterPrinter;
186import android.util.Slog;
187import android.util.SparseArray;
188import android.util.TimeUtils;
189import android.util.Xml;
190import android.view.Gravity;
191import android.view.LayoutInflater;
192import android.view.View;
193import android.view.WindowManager;
194
195import java.io.BufferedInputStream;
196import java.io.BufferedOutputStream;
197import java.io.DataInputStream;
198import java.io.DataOutputStream;
199import java.io.File;
200import java.io.FileDescriptor;
201import java.io.FileInputStream;
202import java.io.FileNotFoundException;
203import java.io.FileOutputStream;
204import java.io.IOException;
205import java.io.InputStreamReader;
206import java.io.PrintWriter;
207import java.io.StringWriter;
208import java.lang.ref.WeakReference;
209import java.util.ArrayList;
210import java.util.Arrays;
211import java.util.Collections;
212import java.util.Comparator;
213import java.util.HashMap;
214import java.util.HashSet;
215import java.util.Iterator;
216import java.util.List;
217import java.util.Locale;
218import java.util.Map;
219import java.util.Set;
220import java.util.concurrent.atomic.AtomicBoolean;
221import java.util.concurrent.atomic.AtomicLong;
222
223public final class ActivityManagerService extends ActivityManagerNative
224        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
225
226    private static final String USER_DATA_DIR = "/data/user/";
227    // File that stores last updated system version and called preboot receivers
228    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
229
230    static final String TAG = "ActivityManager";
231    static final String TAG_MU = "ActivityManagerServiceMU";
232    static final boolean DEBUG = false;
233    static final boolean localLOGV = DEBUG;
234    static final boolean DEBUG_BACKUP = localLOGV || false;
235    static final boolean DEBUG_BROADCAST = localLOGV || false;
236    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
237    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
238    static final boolean DEBUG_CLEANUP = localLOGV || false;
239    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
240    static final boolean DEBUG_FOCUS = false;
241    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
242    static final boolean DEBUG_MU = localLOGV || false;
243    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
244    static final boolean DEBUG_LRU = localLOGV || false;
245    static final boolean DEBUG_PAUSE = localLOGV || false;
246    static final boolean DEBUG_POWER = localLOGV || false;
247    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
248    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
249    static final boolean DEBUG_PROCESSES = localLOGV || false;
250    static final boolean DEBUG_PROVIDER = localLOGV || false;
251    static final boolean DEBUG_RESULTS = localLOGV || false;
252    static final boolean DEBUG_SERVICE = localLOGV || false;
253    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
254    static final boolean DEBUG_STACK = localLOGV || false;
255    static final boolean DEBUG_SWITCH = localLOGV || false;
256    static final boolean DEBUG_TASKS = localLOGV || false;
257    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
258    static final boolean DEBUG_TRANSITION = localLOGV || false;
259    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
260    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
261    static final boolean DEBUG_VISBILITY = localLOGV || false;
262    static final boolean DEBUG_PSS = localLOGV || false;
263    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
264    static final boolean VALIDATE_TOKENS = false;
265    static final boolean SHOW_ACTIVITY_START_TIME = true;
266
267    // Control over CPU and battery monitoring.
268    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
269    static final boolean MONITOR_CPU_USAGE = true;
270    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
271    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
272    static final boolean MONITOR_THREAD_CPU_USAGE = false;
273
274    // The flags that are set for all calls we make to the package manager.
275    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
276
277    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
278
279    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
280
281    // Maximum number of recent tasks that we can remember.
282    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
283
284    // Maximum number recent bitmaps to keep in memory.
285    static final int MAX_RECENT_BITMAPS = 5;
286
287    // Amount of time after a call to stopAppSwitches() during which we will
288    // prevent further untrusted switches from happening.
289    static final long APP_SWITCH_DELAY_TIME = 5*1000;
290
291    // How long we wait for a launched process to attach to the activity manager
292    // before we decide it's never going to come up for real.
293    static final int PROC_START_TIMEOUT = 10*1000;
294
295    // How long we wait for a launched process to attach to the activity manager
296    // before we decide it's never going to come up for real, when the process was
297    // started with a wrapper for instrumentation (such as Valgrind) because it
298    // could take much longer than usual.
299    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
300
301    // How long to wait after going idle before forcing apps to GC.
302    static final int GC_TIMEOUT = 5*1000;
303
304    // The minimum amount of time between successive GC requests for a process.
305    static final int GC_MIN_INTERVAL = 60*1000;
306
307    // The minimum amount of time between successive PSS requests for a process.
308    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
309
310    // The minimum amount of time between successive PSS requests for a process
311    // when the request is due to the memory state being lowered.
312    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
313
314    // The rate at which we check for apps using excessive power -- 15 mins.
315    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
316
317    // The minimum sample duration we will allow before deciding we have
318    // enough data on wake locks to start killing things.
319    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
320
321    // The minimum sample duration we will allow before deciding we have
322    // enough data on CPU usage to start killing things.
323    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
324
325    // How long we allow a receiver to run before giving up on it.
326    static final int BROADCAST_FG_TIMEOUT = 10*1000;
327    static final int BROADCAST_BG_TIMEOUT = 60*1000;
328
329    // How long we wait until we timeout on key dispatching.
330    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
331
332    // How long we wait until we timeout on key dispatching during instrumentation.
333    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
334
335    // Amount of time we wait for observers to handle a user switch before
336    // giving up on them and unfreezing the screen.
337    static final int USER_SWITCH_TIMEOUT = 2*1000;
338
339    // Maximum number of users we allow to be running at a time.
340    static final int MAX_RUNNING_USERS = 3;
341
342    // How long to wait in getAssistContextExtras for the activity and foreground services
343    // to respond with the result.
344    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
345
346    // Maximum number of persisted Uri grants a package is allowed
347    static final int MAX_PERSISTED_URI_GRANTS = 128;
348
349    static final int MY_PID = Process.myPid();
350
351    static final String[] EMPTY_STRING_ARRAY = new String[0];
352
353    // How many bytes to write into the dropbox log before truncating
354    static final int DROPBOX_MAX_SIZE = 256 * 1024;
355
356    // Access modes for handleIncomingUser.
357    static final int ALLOW_NON_FULL = 0;
358    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
359    static final int ALLOW_FULL_ONLY = 2;
360
361    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
362
363    /** All system services */
364    SystemServiceManager mSystemServiceManager;
365
366    /** Run all ActivityStacks through this */
367    ActivityStackSupervisor mStackSupervisor;
368
369    public IntentFirewall mIntentFirewall;
370
371    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
372    // default actuion automatically.  Important for devices without direct input
373    // devices.
374    private boolean mShowDialogs = true;
375
376    BroadcastQueue mFgBroadcastQueue;
377    BroadcastQueue mBgBroadcastQueue;
378    // Convenient for easy iteration over the queues. Foreground is first
379    // so that dispatch of foreground broadcasts gets precedence.
380    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
381
382    BroadcastQueue broadcastQueueForIntent(Intent intent) {
383        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
384        if (DEBUG_BACKGROUND_BROADCAST) {
385            Slog.i(TAG, "Broadcast intent " + intent + " on "
386                    + (isFg ? "foreground" : "background")
387                    + " queue");
388        }
389        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
390    }
391
392    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
393        for (BroadcastQueue queue : mBroadcastQueues) {
394            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
395            if (r != null) {
396                return r;
397            }
398        }
399        return null;
400    }
401
402    /**
403     * Activity we have told the window manager to have key focus.
404     */
405    ActivityRecord mFocusedActivity = null;
406
407    /**
408     * List of intents that were used to start the most recent tasks.
409     */
410    ArrayList<TaskRecord> mRecentTasks;
411    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
412
413    public class PendingAssistExtras extends Binder implements Runnable {
414        public final ActivityRecord activity;
415        public boolean haveResult = false;
416        public Bundle result = null;
417        public PendingAssistExtras(ActivityRecord _activity) {
418            activity = _activity;
419        }
420        @Override
421        public void run() {
422            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
423            synchronized (this) {
424                haveResult = true;
425                notifyAll();
426            }
427        }
428    }
429
430    final ArrayList<PendingAssistExtras> mPendingAssistExtras
431            = new ArrayList<PendingAssistExtras>();
432
433    /**
434     * Process management.
435     */
436    final ProcessList mProcessList = new ProcessList();
437
438    /**
439     * All of the applications we currently have running organized by name.
440     * The keys are strings of the application package name (as
441     * returned by the package manager), and the keys are ApplicationRecord
442     * objects.
443     */
444    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
445
446    /**
447     * Tracking long-term execution of processes to look for abuse and other
448     * bad app behavior.
449     */
450    final ProcessStatsService mProcessStats;
451
452    /**
453     * The currently running isolated processes.
454     */
455    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
456
457    /**
458     * Counter for assigning isolated process uids, to avoid frequently reusing the
459     * same ones.
460     */
461    int mNextIsolatedProcessUid = 0;
462
463    /**
464     * The currently running heavy-weight process, if any.
465     */
466    ProcessRecord mHeavyWeightProcess = null;
467
468    /**
469     * The last time that various processes have crashed.
470     */
471    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
472
473    /**
474     * Information about a process that is currently marked as bad.
475     */
476    static final class BadProcessInfo {
477        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
478            this.time = time;
479            this.shortMsg = shortMsg;
480            this.longMsg = longMsg;
481            this.stack = stack;
482        }
483
484        final long time;
485        final String shortMsg;
486        final String longMsg;
487        final String stack;
488    }
489
490    /**
491     * Set of applications that we consider to be bad, and will reject
492     * incoming broadcasts from (which the user has no control over).
493     * Processes are added to this set when they have crashed twice within
494     * a minimum amount of time; they are removed from it when they are
495     * later restarted (hopefully due to some user action).  The value is the
496     * time it was added to the list.
497     */
498    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
499
500    /**
501     * All of the processes we currently have running organized by pid.
502     * The keys are the pid running the application.
503     *
504     * <p>NOTE: This object is protected by its own lock, NOT the global
505     * activity manager lock!
506     */
507    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
508
509    /**
510     * All of the processes that have been forced to be foreground.  The key
511     * is the pid of the caller who requested it (we hold a death
512     * link on it).
513     */
514    abstract class ForegroundToken implements IBinder.DeathRecipient {
515        int pid;
516        IBinder token;
517    }
518    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
519
520    /**
521     * List of records for processes that someone had tried to start before the
522     * system was ready.  We don't start them at that point, but ensure they
523     * are started by the time booting is complete.
524     */
525    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
526
527    /**
528     * List of persistent applications that are in the process
529     * of being started.
530     */
531    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
532
533    /**
534     * Processes that are being forcibly torn down.
535     */
536    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
537
538    /**
539     * List of running applications, sorted by recent usage.
540     * The first entry in the list is the least recently used.
541     */
542    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
543
544    /**
545     * Where in mLruProcesses that the processes hosting activities start.
546     */
547    int mLruProcessActivityStart = 0;
548
549    /**
550     * Where in mLruProcesses that the processes hosting services start.
551     * This is after (lower index) than mLruProcessesActivityStart.
552     */
553    int mLruProcessServiceStart = 0;
554
555    /**
556     * List of processes that should gc as soon as things are idle.
557     */
558    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
559
560    /**
561     * Processes we want to collect PSS data from.
562     */
563    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
564
565    /**
566     * Last time we requested PSS data of all processes.
567     */
568    long mLastFullPssTime = SystemClock.uptimeMillis();
569
570    /**
571     * If set, the next time we collect PSS data we should do a full collection
572     * with data from native processes and the kernel.
573     */
574    boolean mFullPssPending = false;
575
576    /**
577     * This is the process holding what we currently consider to be
578     * the "home" activity.
579     */
580    ProcessRecord mHomeProcess;
581
582    /**
583     * This is the process holding the activity the user last visited that
584     * is in a different process from the one they are currently in.
585     */
586    ProcessRecord mPreviousProcess;
587
588    /**
589     * The time at which the previous process was last visible.
590     */
591    long mPreviousProcessVisibleTime;
592
593    /**
594     * Which uses have been started, so are allowed to run code.
595     */
596    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
597
598    /**
599     * LRU list of history of current users.  Most recently current is at the end.
600     */
601    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
602
603    /**
604     * Constant array of the users that are currently started.
605     */
606    int[] mStartedUserArray = new int[] { 0 };
607
608    /**
609     * Registered observers of the user switching mechanics.
610     */
611    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
612            = new RemoteCallbackList<IUserSwitchObserver>();
613
614    /**
615     * Currently active user switch.
616     */
617    Object mCurUserSwitchCallback;
618
619    /**
620     * Packages that the user has asked to have run in screen size
621     * compatibility mode instead of filling the screen.
622     */
623    final CompatModePackages mCompatModePackages;
624
625    /**
626     * Set of IntentSenderRecord objects that are currently active.
627     */
628    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
629            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
630
631    /**
632     * Fingerprints (hashCode()) of stack traces that we've
633     * already logged DropBox entries for.  Guarded by itself.  If
634     * something (rogue user app) forces this over
635     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
636     */
637    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
638    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
639
640    /**
641     * Strict Mode background batched logging state.
642     *
643     * The string buffer is guarded by itself, and its lock is also
644     * used to determine if another batched write is already
645     * in-flight.
646     */
647    private final StringBuilder mStrictModeBuffer = new StringBuilder();
648
649    /**
650     * Keeps track of all IIntentReceivers that have been registered for
651     * broadcasts.  Hash keys are the receiver IBinder, hash value is
652     * a ReceiverList.
653     */
654    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
655            new HashMap<IBinder, ReceiverList>();
656
657    /**
658     * Resolver for broadcast intents to registered receivers.
659     * Holds BroadcastFilter (subclass of IntentFilter).
660     */
661    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
662            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
663        @Override
664        protected boolean allowFilterResult(
665                BroadcastFilter filter, List<BroadcastFilter> dest) {
666            IBinder target = filter.receiverList.receiver.asBinder();
667            for (int i=dest.size()-1; i>=0; i--) {
668                if (dest.get(i).receiverList.receiver.asBinder() == target) {
669                    return false;
670                }
671            }
672            return true;
673        }
674
675        @Override
676        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
677            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
678                    || userId == filter.owningUserId) {
679                return super.newResult(filter, match, userId);
680            }
681            return null;
682        }
683
684        @Override
685        protected BroadcastFilter[] newArray(int size) {
686            return new BroadcastFilter[size];
687        }
688
689        @Override
690        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
691            return packageName.equals(filter.packageName);
692        }
693    };
694
695    /**
696     * State of all active sticky broadcasts per user.  Keys are the action of the
697     * sticky Intent, values are an ArrayList of all broadcasted intents with
698     * that action (which should usually be one).  The SparseArray is keyed
699     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
700     * for stickies that are sent to all users.
701     */
702    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
703            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
704
705    final ActiveServices mServices;
706
707    /**
708     * Backup/restore process management
709     */
710    String mBackupAppName = null;
711    BackupRecord mBackupTarget = null;
712
713    final ProviderMap mProviderMap;
714
715    /**
716     * List of content providers who have clients waiting for them.  The
717     * application is currently being launched and the provider will be
718     * removed from this list once it is published.
719     */
720    final ArrayList<ContentProviderRecord> mLaunchingProviders
721            = new ArrayList<ContentProviderRecord>();
722
723    /**
724     * File storing persisted {@link #mGrantedUriPermissions}.
725     */
726    private final AtomicFile mGrantFile;
727
728    /** XML constants used in {@link #mGrantFile} */
729    private static final String TAG_URI_GRANTS = "uri-grants";
730    private static final String TAG_URI_GRANT = "uri-grant";
731    private static final String ATTR_USER_HANDLE = "userHandle";
732    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
733    private static final String ATTR_TARGET_USER_ID = "targetUserId";
734    private static final String ATTR_SOURCE_PKG = "sourcePkg";
735    private static final String ATTR_TARGET_PKG = "targetPkg";
736    private static final String ATTR_URI = "uri";
737    private static final String ATTR_MODE_FLAGS = "modeFlags";
738    private static final String ATTR_CREATED_TIME = "createdTime";
739    private static final String ATTR_PREFIX = "prefix";
740
741    /**
742     * Global set of specific {@link Uri} permissions that have been granted.
743     * This optimized lookup structure maps from {@link UriPermission#targetUid}
744     * to {@link UriPermission#uri} to {@link UriPermission}.
745     */
746    @GuardedBy("this")
747    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
748            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
749
750    public static class GrantUri {
751        public final int sourceUserId;
752        public final Uri uri;
753        public boolean prefix;
754
755        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
756            this.sourceUserId = sourceUserId;
757            this.uri = uri;
758            this.prefix = prefix;
759        }
760
761        @Override
762        public int hashCode() {
763            return toString().hashCode();
764        }
765
766        @Override
767        public boolean equals(Object o) {
768            if (o instanceof GrantUri) {
769                GrantUri other = (GrantUri) o;
770                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
771                        && prefix == other.prefix;
772            }
773            return false;
774        }
775
776        @Override
777        public String toString() {
778            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
779            if (prefix) result += " [prefix]";
780            return result;
781        }
782
783        public String toSafeString() {
784            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
785            if (prefix) result += " [prefix]";
786            return result;
787        }
788
789        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
790            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
791                    ContentProvider.getUriWithoutUserId(uri), false);
792        }
793    }
794
795    CoreSettingsObserver mCoreSettingsObserver;
796
797    /**
798     * Thread-local storage used to carry caller permissions over through
799     * indirect content-provider access.
800     */
801    private class Identity {
802        public int pid;
803        public int uid;
804
805        Identity(int _pid, int _uid) {
806            pid = _pid;
807            uid = _uid;
808        }
809    }
810
811    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
812
813    /**
814     * All information we have collected about the runtime performance of
815     * any user id that can impact battery performance.
816     */
817    final BatteryStatsService mBatteryStatsService;
818
819    /**
820     * Information about component usage
821     */
822    UsageStatsManagerInternal mUsageStatsService;
823
824    /**
825     * Information about and control over application operations
826     */
827    final AppOpsService mAppOpsService;
828
829    /**
830     * Save recent tasks information across reboots.
831     */
832    final TaskPersister mTaskPersister;
833
834    /**
835     * Current configuration information.  HistoryRecord objects are given
836     * a reference to this object to indicate which configuration they are
837     * currently running in, so this object must be kept immutable.
838     */
839    Configuration mConfiguration = new Configuration();
840
841    /**
842     * Current sequencing integer of the configuration, for skipping old
843     * configurations.
844     */
845    int mConfigurationSeq = 0;
846
847    /**
848     * Hardware-reported OpenGLES version.
849     */
850    final int GL_ES_VERSION;
851
852    /**
853     * List of initialization arguments to pass to all processes when binding applications to them.
854     * For example, references to the commonly used services.
855     */
856    HashMap<String, IBinder> mAppBindArgs;
857
858    /**
859     * Temporary to avoid allocations.  Protected by main lock.
860     */
861    final StringBuilder mStringBuilder = new StringBuilder(256);
862
863    /**
864     * Used to control how we initialize the service.
865     */
866    ComponentName mTopComponent;
867    String mTopAction = Intent.ACTION_MAIN;
868    String mTopData;
869    boolean mProcessesReady = false;
870    boolean mSystemReady = false;
871    boolean mBooting = false;
872    boolean mWaitingUpdate = false;
873    boolean mDidUpdate = false;
874    boolean mOnBattery = false;
875    boolean mLaunchWarningShown = false;
876
877    Context mContext;
878
879    int mFactoryTest;
880
881    boolean mCheckedForSetup;
882
883    /**
884     * The time at which we will allow normal application switches again,
885     * after a call to {@link #stopAppSwitches()}.
886     */
887    long mAppSwitchesAllowedTime;
888
889    /**
890     * This is set to true after the first switch after mAppSwitchesAllowedTime
891     * is set; any switches after that will clear the time.
892     */
893    boolean mDidAppSwitch;
894
895    /**
896     * Last time (in realtime) at which we checked for power usage.
897     */
898    long mLastPowerCheckRealtime;
899
900    /**
901     * Last time (in uptime) at which we checked for power usage.
902     */
903    long mLastPowerCheckUptime;
904
905    /**
906     * Set while we are wanting to sleep, to prevent any
907     * activities from being started/resumed.
908     */
909    private boolean mSleeping = false;
910
911    /**
912     * Set while we are running a voice interaction.  This overrides
913     * sleeping while it is active.
914     */
915    private boolean mRunningVoice = false;
916
917    /**
918     * State of external calls telling us if the device is asleep.
919     */
920    private boolean mWentToSleep = false;
921
922    /**
923     * State of external call telling us if the lock screen is shown.
924     */
925    private boolean mLockScreenShown = false;
926
927    /**
928     * Set if we are shutting down the system, similar to sleeping.
929     */
930    boolean mShuttingDown = false;
931
932    /**
933     * Current sequence id for oom_adj computation traversal.
934     */
935    int mAdjSeq = 0;
936
937    /**
938     * Current sequence id for process LRU updating.
939     */
940    int mLruSeq = 0;
941
942    /**
943     * Keep track of the non-cached/empty process we last found, to help
944     * determine how to distribute cached/empty processes next time.
945     */
946    int mNumNonCachedProcs = 0;
947
948    /**
949     * Keep track of the number of cached hidden procs, to balance oom adj
950     * distribution between those and empty procs.
951     */
952    int mNumCachedHiddenProcs = 0;
953
954    /**
955     * Keep track of the number of service processes we last found, to
956     * determine on the next iteration which should be B services.
957     */
958    int mNumServiceProcs = 0;
959    int mNewNumAServiceProcs = 0;
960    int mNewNumServiceProcs = 0;
961
962    /**
963     * Allow the current computed overall memory level of the system to go down?
964     * This is set to false when we are killing processes for reasons other than
965     * memory management, so that the now smaller process list will not be taken as
966     * an indication that memory is tighter.
967     */
968    boolean mAllowLowerMemLevel = false;
969
970    /**
971     * The last computed memory level, for holding when we are in a state that
972     * processes are going away for other reasons.
973     */
974    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
975
976    /**
977     * The last total number of process we have, to determine if changes actually look
978     * like a shrinking number of process due to lower RAM.
979     */
980    int mLastNumProcesses;
981
982    /**
983     * The uptime of the last time we performed idle maintenance.
984     */
985    long mLastIdleTime = SystemClock.uptimeMillis();
986
987    /**
988     * Total time spent with RAM that has been added in the past since the last idle time.
989     */
990    long mLowRamTimeSinceLastIdle = 0;
991
992    /**
993     * If RAM is currently low, when that horrible situation started.
994     */
995    long mLowRamStartTime = 0;
996
997    /**
998     * For reporting to battery stats the current top application.
999     */
1000    private String mCurResumedPackage = null;
1001    private int mCurResumedUid = -1;
1002
1003    /**
1004     * For reporting to battery stats the apps currently running foreground
1005     * service.  The ProcessMap is package/uid tuples; each of these contain
1006     * an array of the currently foreground processes.
1007     */
1008    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1009            = new ProcessMap<ArrayList<ProcessRecord>>();
1010
1011    /**
1012     * This is set if we had to do a delayed dexopt of an app before launching
1013     * it, to increase the ANR timeouts in that case.
1014     */
1015    boolean mDidDexOpt;
1016
1017    /**
1018     * Set if the systemServer made a call to enterSafeMode.
1019     */
1020    boolean mSafeMode;
1021
1022    String mDebugApp = null;
1023    boolean mWaitForDebugger = false;
1024    boolean mDebugTransient = false;
1025    String mOrigDebugApp = null;
1026    boolean mOrigWaitForDebugger = false;
1027    boolean mAlwaysFinishActivities = false;
1028    IActivityController mController = null;
1029    String mProfileApp = null;
1030    ProcessRecord mProfileProc = null;
1031    String mProfileFile;
1032    ParcelFileDescriptor mProfileFd;
1033    int mProfileType = 0;
1034    boolean mAutoStopProfiler = false;
1035    String mOpenGlTraceApp = null;
1036
1037    static class ProcessChangeItem {
1038        static final int CHANGE_ACTIVITIES = 1<<0;
1039        static final int CHANGE_PROCESS_STATE = 1<<1;
1040        int changes;
1041        int uid;
1042        int pid;
1043        int processState;
1044        boolean foregroundActivities;
1045    }
1046
1047    final RemoteCallbackList<IProcessObserver> mProcessObservers
1048            = new RemoteCallbackList<IProcessObserver>();
1049    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1050
1051    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1052            = new ArrayList<ProcessChangeItem>();
1053    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1054            = new ArrayList<ProcessChangeItem>();
1055
1056    /**
1057     * Runtime CPU use collection thread.  This object's lock is used to
1058     * protect all related state.
1059     */
1060    final Thread mProcessCpuThread;
1061
1062    /**
1063     * Used to collect process stats when showing not responding dialog.
1064     * Protected by mProcessCpuThread.
1065     */
1066    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1067            MONITOR_THREAD_CPU_USAGE);
1068    final AtomicLong mLastCpuTime = new AtomicLong(0);
1069    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1070
1071    long mLastWriteTime = 0;
1072
1073    /**
1074     * Used to retain an update lock when the foreground activity is in
1075     * immersive mode.
1076     */
1077    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1078
1079    /**
1080     * Set to true after the system has finished booting.
1081     */
1082    boolean mBooted = false;
1083
1084    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1085    int mProcessLimitOverride = -1;
1086
1087    WindowManagerService mWindowManager;
1088
1089    final ActivityThread mSystemThread;
1090
1091    int mCurrentUserId = 0;
1092    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1093
1094    /**
1095     * Mapping from each known user ID to the profile group ID it is associated with.
1096     */
1097    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1098
1099    private UserManagerService mUserManager;
1100
1101    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1102        final ProcessRecord mApp;
1103        final int mPid;
1104        final IApplicationThread mAppThread;
1105
1106        AppDeathRecipient(ProcessRecord app, int pid,
1107                IApplicationThread thread) {
1108            if (localLOGV) Slog.v(
1109                TAG, "New death recipient " + this
1110                + " for thread " + thread.asBinder());
1111            mApp = app;
1112            mPid = pid;
1113            mAppThread = thread;
1114        }
1115
1116        @Override
1117        public void binderDied() {
1118            if (localLOGV) Slog.v(
1119                TAG, "Death received in " + this
1120                + " for thread " + mAppThread.asBinder());
1121            synchronized(ActivityManagerService.this) {
1122                appDiedLocked(mApp, mPid, mAppThread);
1123            }
1124        }
1125    }
1126
1127    static final int SHOW_ERROR_MSG = 1;
1128    static final int SHOW_NOT_RESPONDING_MSG = 2;
1129    static final int SHOW_FACTORY_ERROR_MSG = 3;
1130    static final int UPDATE_CONFIGURATION_MSG = 4;
1131    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1132    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1133    static final int SERVICE_TIMEOUT_MSG = 12;
1134    static final int UPDATE_TIME_ZONE = 13;
1135    static final int SHOW_UID_ERROR_MSG = 14;
1136    static final int IM_FEELING_LUCKY_MSG = 15;
1137    static final int PROC_START_TIMEOUT_MSG = 20;
1138    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1139    static final int KILL_APPLICATION_MSG = 22;
1140    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1141    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1142    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1143    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1144    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1145    static final int CLEAR_DNS_CACHE_MSG = 28;
1146    static final int UPDATE_HTTP_PROXY_MSG = 29;
1147    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1148    static final int DISPATCH_PROCESSES_CHANGED = 31;
1149    static final int DISPATCH_PROCESS_DIED = 32;
1150    static final int REPORT_MEM_USAGE_MSG = 33;
1151    static final int REPORT_USER_SWITCH_MSG = 34;
1152    static final int CONTINUE_USER_SWITCH_MSG = 35;
1153    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1154    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1155    static final int PERSIST_URI_GRANTS_MSG = 38;
1156    static final int REQUEST_ALL_PSS_MSG = 39;
1157    static final int START_PROFILES_MSG = 40;
1158    static final int UPDATE_TIME = 41;
1159    static final int SYSTEM_USER_START_MSG = 42;
1160    static final int SYSTEM_USER_CURRENT_MSG = 43;
1161    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1162    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1163
1164    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1165    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1166    static final int FIRST_COMPAT_MODE_MSG = 300;
1167    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1168
1169    AlertDialog mUidAlert;
1170    CompatModeDialog mCompatModeDialog;
1171    long mLastMemUsageReportTime = 0;
1172
1173    private LockToAppRequestDialog mLockToAppRequest;
1174
1175    /**
1176     * Flag whether the current user is a "monkey", i.e. whether
1177     * the UI is driven by a UI automation tool.
1178     */
1179    private boolean mUserIsMonkey;
1180
1181    /** Flag whether the device has a recents UI */
1182    final boolean mHasRecents;
1183
1184    final ServiceThread mHandlerThread;
1185    final MainHandler mHandler;
1186
1187    final class MainHandler extends Handler {
1188        public MainHandler(Looper looper) {
1189            super(looper, null, true);
1190        }
1191
1192        @Override
1193        public void handleMessage(Message msg) {
1194            switch (msg.what) {
1195            case SHOW_ERROR_MSG: {
1196                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1197                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1198                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1199                synchronized (ActivityManagerService.this) {
1200                    ProcessRecord proc = (ProcessRecord)data.get("app");
1201                    AppErrorResult res = (AppErrorResult) data.get("result");
1202                    if (proc != null && proc.crashDialog != null) {
1203                        Slog.e(TAG, "App already has crash dialog: " + proc);
1204                        if (res != null) {
1205                            res.set(0);
1206                        }
1207                        return;
1208                    }
1209                    if (!showBackground && UserHandle.getAppId(proc.uid)
1210                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1211                            && proc.pid != MY_PID) {
1212                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1213                        if (res != null) {
1214                            res.set(0);
1215                        }
1216                        return;
1217                    }
1218                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1219                        Dialog d = new AppErrorDialog(mContext,
1220                                ActivityManagerService.this, res, proc);
1221                        d.show();
1222                        proc.crashDialog = d;
1223                    } else {
1224                        // The device is asleep, so just pretend that the user
1225                        // saw a crash dialog and hit "force quit".
1226                        if (res != null) {
1227                            res.set(0);
1228                        }
1229                    }
1230                }
1231
1232                ensureBootCompleted();
1233            } break;
1234            case SHOW_NOT_RESPONDING_MSG: {
1235                synchronized (ActivityManagerService.this) {
1236                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1237                    ProcessRecord proc = (ProcessRecord)data.get("app");
1238                    if (proc != null && proc.anrDialog != null) {
1239                        Slog.e(TAG, "App already has anr dialog: " + proc);
1240                        return;
1241                    }
1242
1243                    Intent intent = new Intent("android.intent.action.ANR");
1244                    if (!mProcessesReady) {
1245                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1246                                | Intent.FLAG_RECEIVER_FOREGROUND);
1247                    }
1248                    broadcastIntentLocked(null, null, intent,
1249                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1250                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1251
1252                    if (mShowDialogs) {
1253                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1254                                mContext, proc, (ActivityRecord)data.get("activity"),
1255                                msg.arg1 != 0);
1256                        d.show();
1257                        proc.anrDialog = d;
1258                    } else {
1259                        // Just kill the app if there is no dialog to be shown.
1260                        killAppAtUsersRequest(proc, null);
1261                    }
1262                }
1263
1264                ensureBootCompleted();
1265            } break;
1266            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1267                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1268                synchronized (ActivityManagerService.this) {
1269                    ProcessRecord proc = (ProcessRecord) data.get("app");
1270                    if (proc == null) {
1271                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1272                        break;
1273                    }
1274                    if (proc.crashDialog != null) {
1275                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1276                        return;
1277                    }
1278                    AppErrorResult res = (AppErrorResult) data.get("result");
1279                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1280                        Dialog d = new StrictModeViolationDialog(mContext,
1281                                ActivityManagerService.this, res, proc);
1282                        d.show();
1283                        proc.crashDialog = d;
1284                    } else {
1285                        // The device is asleep, so just pretend that the user
1286                        // saw a crash dialog and hit "force quit".
1287                        res.set(0);
1288                    }
1289                }
1290                ensureBootCompleted();
1291            } break;
1292            case SHOW_FACTORY_ERROR_MSG: {
1293                Dialog d = new FactoryErrorDialog(
1294                    mContext, msg.getData().getCharSequence("msg"));
1295                d.show();
1296                ensureBootCompleted();
1297            } break;
1298            case UPDATE_CONFIGURATION_MSG: {
1299                final ContentResolver resolver = mContext.getContentResolver();
1300                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1301            } break;
1302            case GC_BACKGROUND_PROCESSES_MSG: {
1303                synchronized (ActivityManagerService.this) {
1304                    performAppGcsIfAppropriateLocked();
1305                }
1306            } break;
1307            case WAIT_FOR_DEBUGGER_MSG: {
1308                synchronized (ActivityManagerService.this) {
1309                    ProcessRecord app = (ProcessRecord)msg.obj;
1310                    if (msg.arg1 != 0) {
1311                        if (!app.waitedForDebugger) {
1312                            Dialog d = new AppWaitingForDebuggerDialog(
1313                                    ActivityManagerService.this,
1314                                    mContext, app);
1315                            app.waitDialog = d;
1316                            app.waitedForDebugger = true;
1317                            d.show();
1318                        }
1319                    } else {
1320                        if (app.waitDialog != null) {
1321                            app.waitDialog.dismiss();
1322                            app.waitDialog = null;
1323                        }
1324                    }
1325                }
1326            } break;
1327            case SERVICE_TIMEOUT_MSG: {
1328                if (mDidDexOpt) {
1329                    mDidDexOpt = false;
1330                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1331                    nmsg.obj = msg.obj;
1332                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1333                    return;
1334                }
1335                mServices.serviceTimeout((ProcessRecord)msg.obj);
1336            } break;
1337            case UPDATE_TIME_ZONE: {
1338                synchronized (ActivityManagerService.this) {
1339                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1340                        ProcessRecord r = mLruProcesses.get(i);
1341                        if (r.thread != null) {
1342                            try {
1343                                r.thread.updateTimeZone();
1344                            } catch (RemoteException ex) {
1345                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1346                            }
1347                        }
1348                    }
1349                }
1350            } break;
1351            case CLEAR_DNS_CACHE_MSG: {
1352                synchronized (ActivityManagerService.this) {
1353                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1354                        ProcessRecord r = mLruProcesses.get(i);
1355                        if (r.thread != null) {
1356                            try {
1357                                r.thread.clearDnsCache();
1358                            } catch (RemoteException ex) {
1359                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1360                            }
1361                        }
1362                    }
1363                }
1364            } break;
1365            case UPDATE_HTTP_PROXY_MSG: {
1366                ProxyInfo proxy = (ProxyInfo)msg.obj;
1367                String host = "";
1368                String port = "";
1369                String exclList = "";
1370                Uri pacFileUrl = Uri.EMPTY;
1371                if (proxy != null) {
1372                    host = proxy.getHost();
1373                    port = Integer.toString(proxy.getPort());
1374                    exclList = proxy.getExclusionListAsString();
1375                    pacFileUrl = proxy.getPacFileUrl();
1376                }
1377                synchronized (ActivityManagerService.this) {
1378                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1379                        ProcessRecord r = mLruProcesses.get(i);
1380                        if (r.thread != null) {
1381                            try {
1382                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1383                            } catch (RemoteException ex) {
1384                                Slog.w(TAG, "Failed to update http proxy for: " +
1385                                        r.info.processName);
1386                            }
1387                        }
1388                    }
1389                }
1390            } break;
1391            case SHOW_UID_ERROR_MSG: {
1392                String title = "System UIDs Inconsistent";
1393                String text = "UIDs on the system are inconsistent, you need to wipe your"
1394                        + " data partition or your device will be unstable.";
1395                Log.e(TAG, title + ": " + text);
1396                if (mShowDialogs) {
1397                    // XXX This is a temporary dialog, no need to localize.
1398                    AlertDialog d = new BaseErrorDialog(mContext);
1399                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1400                    d.setCancelable(false);
1401                    d.setTitle(title);
1402                    d.setMessage(text);
1403                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1404                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1405                    mUidAlert = d;
1406                    d.show();
1407                }
1408            } break;
1409            case IM_FEELING_LUCKY_MSG: {
1410                if (mUidAlert != null) {
1411                    mUidAlert.dismiss();
1412                    mUidAlert = null;
1413                }
1414            } break;
1415            case PROC_START_TIMEOUT_MSG: {
1416                if (mDidDexOpt) {
1417                    mDidDexOpt = false;
1418                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1419                    nmsg.obj = msg.obj;
1420                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1421                    return;
1422                }
1423                ProcessRecord app = (ProcessRecord)msg.obj;
1424                synchronized (ActivityManagerService.this) {
1425                    processStartTimedOutLocked(app);
1426                }
1427            } break;
1428            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1429                synchronized (ActivityManagerService.this) {
1430                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1431                }
1432            } break;
1433            case KILL_APPLICATION_MSG: {
1434                synchronized (ActivityManagerService.this) {
1435                    int appid = msg.arg1;
1436                    boolean restart = (msg.arg2 == 1);
1437                    Bundle bundle = (Bundle)msg.obj;
1438                    String pkg = bundle.getString("pkg");
1439                    String reason = bundle.getString("reason");
1440                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1441                            false, UserHandle.USER_ALL, reason);
1442                }
1443            } break;
1444            case FINALIZE_PENDING_INTENT_MSG: {
1445                ((PendingIntentRecord)msg.obj).completeFinalize();
1446            } break;
1447            case POST_HEAVY_NOTIFICATION_MSG: {
1448                INotificationManager inm = NotificationManager.getService();
1449                if (inm == null) {
1450                    return;
1451                }
1452
1453                ActivityRecord root = (ActivityRecord)msg.obj;
1454                ProcessRecord process = root.app;
1455                if (process == null) {
1456                    return;
1457                }
1458
1459                try {
1460                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1461                    String text = mContext.getString(R.string.heavy_weight_notification,
1462                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1463                    Notification notification = new Notification();
1464                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1465                    notification.when = 0;
1466                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1467                    notification.tickerText = text;
1468                    notification.defaults = 0; // please be quiet
1469                    notification.sound = null;
1470                    notification.vibrate = null;
1471                    notification.setLatestEventInfo(context, text,
1472                            mContext.getText(R.string.heavy_weight_notification_detail),
1473                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1474                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1475                                    new UserHandle(root.userId)));
1476
1477                    try {
1478                        int[] outId = new int[1];
1479                        inm.enqueueNotificationWithTag("android", "android", null,
1480                                R.string.heavy_weight_notification,
1481                                notification, outId, root.userId);
1482                    } catch (RuntimeException e) {
1483                        Slog.w(ActivityManagerService.TAG,
1484                                "Error showing notification for heavy-weight app", e);
1485                    } catch (RemoteException e) {
1486                    }
1487                } catch (NameNotFoundException e) {
1488                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1489                }
1490            } break;
1491            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1492                INotificationManager inm = NotificationManager.getService();
1493                if (inm == null) {
1494                    return;
1495                }
1496                try {
1497                    inm.cancelNotificationWithTag("android", null,
1498                            R.string.heavy_weight_notification,  msg.arg1);
1499                } catch (RuntimeException e) {
1500                    Slog.w(ActivityManagerService.TAG,
1501                            "Error canceling notification for service", e);
1502                } catch (RemoteException e) {
1503                }
1504            } break;
1505            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1506                synchronized (ActivityManagerService.this) {
1507                    checkExcessivePowerUsageLocked(true);
1508                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1509                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1510                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1511                }
1512            } break;
1513            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1514                synchronized (ActivityManagerService.this) {
1515                    ActivityRecord ar = (ActivityRecord)msg.obj;
1516                    if (mCompatModeDialog != null) {
1517                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1518                                ar.info.applicationInfo.packageName)) {
1519                            return;
1520                        }
1521                        mCompatModeDialog.dismiss();
1522                        mCompatModeDialog = null;
1523                    }
1524                    if (ar != null && false) {
1525                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1526                                ar.packageName)) {
1527                            int mode = mCompatModePackages.computeCompatModeLocked(
1528                                    ar.info.applicationInfo);
1529                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1530                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1531                                mCompatModeDialog = new CompatModeDialog(
1532                                        ActivityManagerService.this, mContext,
1533                                        ar.info.applicationInfo);
1534                                mCompatModeDialog.show();
1535                            }
1536                        }
1537                    }
1538                }
1539                break;
1540            }
1541            case DISPATCH_PROCESSES_CHANGED: {
1542                dispatchProcessesChanged();
1543                break;
1544            }
1545            case DISPATCH_PROCESS_DIED: {
1546                final int pid = msg.arg1;
1547                final int uid = msg.arg2;
1548                dispatchProcessDied(pid, uid);
1549                break;
1550            }
1551            case REPORT_MEM_USAGE_MSG: {
1552                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1553                Thread thread = new Thread() {
1554                    @Override public void run() {
1555                        final SparseArray<ProcessMemInfo> infoMap
1556                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1557                        for (int i=0, N=memInfos.size(); i<N; i++) {
1558                            ProcessMemInfo mi = memInfos.get(i);
1559                            infoMap.put(mi.pid, mi);
1560                        }
1561                        updateCpuStatsNow();
1562                        synchronized (mProcessCpuThread) {
1563                            final int N = mProcessCpuTracker.countStats();
1564                            for (int i=0; i<N; i++) {
1565                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1566                                if (st.vsize > 0) {
1567                                    long pss = Debug.getPss(st.pid, null);
1568                                    if (pss > 0) {
1569                                        if (infoMap.indexOfKey(st.pid) < 0) {
1570                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1571                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1572                                            mi.pss = pss;
1573                                            memInfos.add(mi);
1574                                        }
1575                                    }
1576                                }
1577                            }
1578                        }
1579
1580                        long totalPss = 0;
1581                        for (int i=0, N=memInfos.size(); i<N; i++) {
1582                            ProcessMemInfo mi = memInfos.get(i);
1583                            if (mi.pss == 0) {
1584                                mi.pss = Debug.getPss(mi.pid, null);
1585                            }
1586                            totalPss += mi.pss;
1587                        }
1588                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1589                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1590                                if (lhs.oomAdj != rhs.oomAdj) {
1591                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1592                                }
1593                                if (lhs.pss != rhs.pss) {
1594                                    return lhs.pss < rhs.pss ? 1 : -1;
1595                                }
1596                                return 0;
1597                            }
1598                        });
1599
1600                        StringBuilder tag = new StringBuilder(128);
1601                        StringBuilder stack = new StringBuilder(128);
1602                        tag.append("Low on memory -- ");
1603                        appendMemBucket(tag, totalPss, "total", false);
1604                        appendMemBucket(stack, totalPss, "total", true);
1605
1606                        StringBuilder logBuilder = new StringBuilder(1024);
1607                        logBuilder.append("Low on memory:\n");
1608
1609                        boolean firstLine = true;
1610                        int lastOomAdj = Integer.MIN_VALUE;
1611                        for (int i=0, N=memInfos.size(); i<N; i++) {
1612                            ProcessMemInfo mi = memInfos.get(i);
1613
1614                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1615                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1616                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1617                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1618                                if (lastOomAdj != mi.oomAdj) {
1619                                    lastOomAdj = mi.oomAdj;
1620                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1621                                        tag.append(" / ");
1622                                    }
1623                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1624                                        if (firstLine) {
1625                                            stack.append(":");
1626                                            firstLine = false;
1627                                        }
1628                                        stack.append("\n\t at ");
1629                                    } else {
1630                                        stack.append("$");
1631                                    }
1632                                } else {
1633                                    tag.append(" ");
1634                                    stack.append("$");
1635                                }
1636                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1637                                    appendMemBucket(tag, mi.pss, mi.name, false);
1638                                }
1639                                appendMemBucket(stack, mi.pss, mi.name, true);
1640                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1641                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1642                                    stack.append("(");
1643                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1644                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1645                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1646                                            stack.append(":");
1647                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1648                                        }
1649                                    }
1650                                    stack.append(")");
1651                                }
1652                            }
1653
1654                            logBuilder.append("  ");
1655                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1656                            logBuilder.append(' ');
1657                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1658                            logBuilder.append(' ');
1659                            ProcessList.appendRamKb(logBuilder, mi.pss);
1660                            logBuilder.append(" kB: ");
1661                            logBuilder.append(mi.name);
1662                            logBuilder.append(" (");
1663                            logBuilder.append(mi.pid);
1664                            logBuilder.append(") ");
1665                            logBuilder.append(mi.adjType);
1666                            logBuilder.append('\n');
1667                            if (mi.adjReason != null) {
1668                                logBuilder.append("                      ");
1669                                logBuilder.append(mi.adjReason);
1670                                logBuilder.append('\n');
1671                            }
1672                        }
1673
1674                        logBuilder.append("           ");
1675                        ProcessList.appendRamKb(logBuilder, totalPss);
1676                        logBuilder.append(" kB: TOTAL\n");
1677
1678                        long[] infos = new long[Debug.MEMINFO_COUNT];
1679                        Debug.getMemInfo(infos);
1680                        logBuilder.append("  MemInfo: ");
1681                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1682                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1683                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1684                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1685                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1686                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1687                            logBuilder.append("  ZRAM: ");
1688                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1689                            logBuilder.append(" kB RAM, ");
1690                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1691                            logBuilder.append(" kB swap total, ");
1692                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1693                            logBuilder.append(" kB swap free\n");
1694                        }
1695                        Slog.i(TAG, logBuilder.toString());
1696
1697                        StringBuilder dropBuilder = new StringBuilder(1024);
1698                        /*
1699                        StringWriter oomSw = new StringWriter();
1700                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1701                        StringWriter catSw = new StringWriter();
1702                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1703                        String[] emptyArgs = new String[] { };
1704                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1705                        oomPw.flush();
1706                        String oomString = oomSw.toString();
1707                        */
1708                        dropBuilder.append(stack);
1709                        dropBuilder.append('\n');
1710                        dropBuilder.append('\n');
1711                        dropBuilder.append(logBuilder);
1712                        dropBuilder.append('\n');
1713                        /*
1714                        dropBuilder.append(oomString);
1715                        dropBuilder.append('\n');
1716                        */
1717                        StringWriter catSw = new StringWriter();
1718                        synchronized (ActivityManagerService.this) {
1719                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1720                            String[] emptyArgs = new String[] { };
1721                            catPw.println();
1722                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1723                            catPw.println();
1724                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1725                                    false, false, null);
1726                            catPw.println();
1727                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1728                            catPw.flush();
1729                        }
1730                        dropBuilder.append(catSw.toString());
1731                        addErrorToDropBox("lowmem", null, "system_server", null,
1732                                null, tag.toString(), dropBuilder.toString(), null, null);
1733                        //Slog.i(TAG, "Sent to dropbox:");
1734                        //Slog.i(TAG, dropBuilder.toString());
1735                        synchronized (ActivityManagerService.this) {
1736                            long now = SystemClock.uptimeMillis();
1737                            if (mLastMemUsageReportTime < now) {
1738                                mLastMemUsageReportTime = now;
1739                            }
1740                        }
1741                    }
1742                };
1743                thread.start();
1744                break;
1745            }
1746            case REPORT_USER_SWITCH_MSG: {
1747                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1748                break;
1749            }
1750            case CONTINUE_USER_SWITCH_MSG: {
1751                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1752                break;
1753            }
1754            case USER_SWITCH_TIMEOUT_MSG: {
1755                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1756                break;
1757            }
1758            case IMMERSIVE_MODE_LOCK_MSG: {
1759                final boolean nextState = (msg.arg1 != 0);
1760                if (mUpdateLock.isHeld() != nextState) {
1761                    if (DEBUG_IMMERSIVE) {
1762                        final ActivityRecord r = (ActivityRecord) msg.obj;
1763                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1764                    }
1765                    if (nextState) {
1766                        mUpdateLock.acquire();
1767                    } else {
1768                        mUpdateLock.release();
1769                    }
1770                }
1771                break;
1772            }
1773            case PERSIST_URI_GRANTS_MSG: {
1774                writeGrantedUriPermissions();
1775                break;
1776            }
1777            case REQUEST_ALL_PSS_MSG: {
1778                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1779                break;
1780            }
1781            case START_PROFILES_MSG: {
1782                synchronized (ActivityManagerService.this) {
1783                    startProfilesLocked();
1784                }
1785                break;
1786            }
1787            case UPDATE_TIME: {
1788                synchronized (ActivityManagerService.this) {
1789                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1790                        ProcessRecord r = mLruProcesses.get(i);
1791                        if (r.thread != null) {
1792                            try {
1793                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1794                            } catch (RemoteException ex) {
1795                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1796                            }
1797                        }
1798                    }
1799                }
1800                break;
1801            }
1802            case SYSTEM_USER_START_MSG: {
1803                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1804                        Integer.toString(msg.arg1), msg.arg1);
1805                mSystemServiceManager.startUser(msg.arg1);
1806                break;
1807            }
1808            case SYSTEM_USER_CURRENT_MSG: {
1809                mBatteryStatsService.noteEvent(
1810                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1811                        Integer.toString(msg.arg2), msg.arg2);
1812                mBatteryStatsService.noteEvent(
1813                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1814                        Integer.toString(msg.arg1), msg.arg1);
1815                mSystemServiceManager.switchUser(msg.arg1);
1816                break;
1817            }
1818            case ENTER_ANIMATION_COMPLETE_MSG: {
1819                synchronized (ActivityManagerService.this) {
1820                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1821                    if (r != null && r.app != null && r.app.thread != null) {
1822                        try {
1823                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1824                        } catch (RemoteException e) {
1825                        }
1826                    }
1827                }
1828                break;
1829            }
1830            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1831                enableScreenAfterBoot();
1832                break;
1833            }
1834            }
1835        }
1836    };
1837
1838    static final int COLLECT_PSS_BG_MSG = 1;
1839
1840    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1841        @Override
1842        public void handleMessage(Message msg) {
1843            switch (msg.what) {
1844            case COLLECT_PSS_BG_MSG: {
1845                long start = SystemClock.uptimeMillis();
1846                MemInfoReader memInfo = null;
1847                synchronized (ActivityManagerService.this) {
1848                    if (mFullPssPending) {
1849                        mFullPssPending = false;
1850                        memInfo = new MemInfoReader();
1851                    }
1852                }
1853                if (memInfo != null) {
1854                    updateCpuStatsNow();
1855                    long nativeTotalPss = 0;
1856                    synchronized (mProcessCpuThread) {
1857                        final int N = mProcessCpuTracker.countStats();
1858                        for (int j=0; j<N; j++) {
1859                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1860                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1861                                // This is definitely an application process; skip it.
1862                                continue;
1863                            }
1864                            synchronized (mPidsSelfLocked) {
1865                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1866                                    // This is one of our own processes; skip it.
1867                                    continue;
1868                                }
1869                            }
1870                            nativeTotalPss += Debug.getPss(st.pid, null);
1871                        }
1872                    }
1873                    memInfo.readMemInfo();
1874                    synchronized (this) {
1875                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1876                                + (SystemClock.uptimeMillis()-start) + "ms");
1877                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1878                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1879                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1880                                        +memInfo.getSlabSizeKb(),
1881                                nativeTotalPss);
1882                    }
1883                }
1884
1885                int i=0, num=0;
1886                long[] tmp = new long[1];
1887                do {
1888                    ProcessRecord proc;
1889                    int procState;
1890                    int pid;
1891                    synchronized (ActivityManagerService.this) {
1892                        if (i >= mPendingPssProcesses.size()) {
1893                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1894                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1895                            mPendingPssProcesses.clear();
1896                            return;
1897                        }
1898                        proc = mPendingPssProcesses.get(i);
1899                        procState = proc.pssProcState;
1900                        if (proc.thread != null && procState == proc.setProcState) {
1901                            pid = proc.pid;
1902                        } else {
1903                            proc = null;
1904                            pid = 0;
1905                        }
1906                        i++;
1907                    }
1908                    if (proc != null) {
1909                        long pss = Debug.getPss(pid, tmp);
1910                        synchronized (ActivityManagerService.this) {
1911                            if (proc.thread != null && proc.setProcState == procState
1912                                    && proc.pid == pid) {
1913                                num++;
1914                                proc.lastPssTime = SystemClock.uptimeMillis();
1915                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1916                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1917                                        + ": " + pss + " lastPss=" + proc.lastPss
1918                                        + " state=" + ProcessList.makeProcStateString(procState));
1919                                if (proc.initialIdlePss == 0) {
1920                                    proc.initialIdlePss = pss;
1921                                }
1922                                proc.lastPss = pss;
1923                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1924                                    proc.lastCachedPss = pss;
1925                                }
1926                            }
1927                        }
1928                    }
1929                } while (true);
1930            }
1931            }
1932        }
1933    };
1934
1935    /**
1936     * Monitor for package changes and update our internal state.
1937     */
1938    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1939        @Override
1940        public void onPackageRemoved(String packageName, int uid) {
1941            // Remove all tasks with activities in the specified package from the list of recent tasks
1942            synchronized (ActivityManagerService.this) {
1943                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1944                    TaskRecord tr = mRecentTasks.get(i);
1945                    ComponentName cn = tr.intent.getComponent();
1946                    if (cn != null && cn.getPackageName().equals(packageName)) {
1947                        // If the package name matches, remove the task and kill the process
1948                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1949                    }
1950                }
1951            }
1952        }
1953
1954        @Override
1955        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1956            onPackageModified(packageName);
1957            return true;
1958        }
1959
1960        @Override
1961        public void onPackageModified(String packageName) {
1962            final PackageManager pm = mContext.getPackageManager();
1963            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1964                    new ArrayList<Pair<Intent, Integer>>();
1965            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1966            // Copy the list of recent tasks so that we don't hold onto the lock on
1967            // ActivityManagerService for long periods while checking if components exist.
1968            synchronized (ActivityManagerService.this) {
1969                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1970                    TaskRecord tr = mRecentTasks.get(i);
1971                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1972                }
1973            }
1974            // Check the recent tasks and filter out all tasks with components that no longer exist.
1975            Intent tmpI = new Intent();
1976            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1977                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1978                ComponentName cn = p.first.getComponent();
1979                if (cn != null && cn.getPackageName().equals(packageName)) {
1980                    try {
1981                        // Add the task to the list to remove if the component no longer exists
1982                        tmpI.setComponent(cn);
1983                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1984                            tasksToRemove.add(p.second);
1985                        }
1986                    } catch (Exception e) {}
1987                }
1988            }
1989            // Prune all the tasks with removed components from the list of recent tasks
1990            synchronized (ActivityManagerService.this) {
1991                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1992                    // Remove the task but don't kill the process (since other components in that
1993                    // package may still be running and in the background)
1994                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1995                }
1996            }
1997        }
1998
1999        @Override
2000        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2001            // Force stop the specified packages
2002            if (packages != null) {
2003                for (String pkg : packages) {
2004                    synchronized (ActivityManagerService.this) {
2005                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2006                                "finished booting")) {
2007                            return true;
2008                        }
2009                    }
2010                }
2011            }
2012            return false;
2013        }
2014    };
2015
2016    public void setSystemProcess() {
2017        try {
2018            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2019            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2020            ServiceManager.addService("meminfo", new MemBinder(this));
2021            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2022            ServiceManager.addService("dbinfo", new DbBinder(this));
2023            if (MONITOR_CPU_USAGE) {
2024                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2025            }
2026            ServiceManager.addService("permission", new PermissionController(this));
2027
2028            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2029                    "android", STOCK_PM_FLAGS);
2030            mSystemThread.installSystemApplicationInfo(info);
2031
2032            synchronized (this) {
2033                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2034                app.persistent = true;
2035                app.pid = MY_PID;
2036                app.maxAdj = ProcessList.SYSTEM_ADJ;
2037                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2038                mProcessNames.put(app.processName, app.uid, app);
2039                synchronized (mPidsSelfLocked) {
2040                    mPidsSelfLocked.put(app.pid, app);
2041                }
2042                updateLruProcessLocked(app, false, null);
2043                updateOomAdjLocked();
2044            }
2045        } catch (PackageManager.NameNotFoundException e) {
2046            throw new RuntimeException(
2047                    "Unable to find android system package", e);
2048        }
2049    }
2050
2051    public void setWindowManager(WindowManagerService wm) {
2052        mWindowManager = wm;
2053        mStackSupervisor.setWindowManager(wm);
2054    }
2055
2056    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2057        mUsageStatsService = usageStatsManager;
2058    }
2059
2060    public void startObservingNativeCrashes() {
2061        final NativeCrashListener ncl = new NativeCrashListener(this);
2062        ncl.start();
2063    }
2064
2065    public IAppOpsService getAppOpsService() {
2066        return mAppOpsService;
2067    }
2068
2069    static class MemBinder extends Binder {
2070        ActivityManagerService mActivityManagerService;
2071        MemBinder(ActivityManagerService activityManagerService) {
2072            mActivityManagerService = activityManagerService;
2073        }
2074
2075        @Override
2076        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2077            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2078                    != PackageManager.PERMISSION_GRANTED) {
2079                pw.println("Permission Denial: can't dump meminfo from from pid="
2080                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2081                        + " without permission " + android.Manifest.permission.DUMP);
2082                return;
2083            }
2084
2085            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2086        }
2087    }
2088
2089    static class GraphicsBinder extends Binder {
2090        ActivityManagerService mActivityManagerService;
2091        GraphicsBinder(ActivityManagerService activityManagerService) {
2092            mActivityManagerService = activityManagerService;
2093        }
2094
2095        @Override
2096        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2097            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2098                    != PackageManager.PERMISSION_GRANTED) {
2099                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2100                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2101                        + " without permission " + android.Manifest.permission.DUMP);
2102                return;
2103            }
2104
2105            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2106        }
2107    }
2108
2109    static class DbBinder extends Binder {
2110        ActivityManagerService mActivityManagerService;
2111        DbBinder(ActivityManagerService activityManagerService) {
2112            mActivityManagerService = activityManagerService;
2113        }
2114
2115        @Override
2116        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2117            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2118                    != PackageManager.PERMISSION_GRANTED) {
2119                pw.println("Permission Denial: can't dump dbinfo from from pid="
2120                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2121                        + " without permission " + android.Manifest.permission.DUMP);
2122                return;
2123            }
2124
2125            mActivityManagerService.dumpDbInfo(fd, pw, args);
2126        }
2127    }
2128
2129    static class CpuBinder extends Binder {
2130        ActivityManagerService mActivityManagerService;
2131        CpuBinder(ActivityManagerService activityManagerService) {
2132            mActivityManagerService = activityManagerService;
2133        }
2134
2135        @Override
2136        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2137            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2138                    != PackageManager.PERMISSION_GRANTED) {
2139                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2140                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2141                        + " without permission " + android.Manifest.permission.DUMP);
2142                return;
2143            }
2144
2145            synchronized (mActivityManagerService.mProcessCpuThread) {
2146                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2147                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2148                        SystemClock.uptimeMillis()));
2149            }
2150        }
2151    }
2152
2153    public static final class Lifecycle extends SystemService {
2154        private final ActivityManagerService mService;
2155
2156        public Lifecycle(Context context) {
2157            super(context);
2158            mService = new ActivityManagerService(context);
2159        }
2160
2161        @Override
2162        public void onStart() {
2163            mService.start();
2164        }
2165
2166        public ActivityManagerService getService() {
2167            return mService;
2168        }
2169    }
2170
2171    // Note: This method is invoked on the main thread but may need to attach various
2172    // handlers to other threads.  So take care to be explicit about the looper.
2173    public ActivityManagerService(Context systemContext) {
2174        mContext = systemContext;
2175        mFactoryTest = FactoryTest.getMode();
2176        mSystemThread = ActivityThread.currentActivityThread();
2177
2178        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2179
2180        mHandlerThread = new ServiceThread(TAG,
2181                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2182        mHandlerThread.start();
2183        mHandler = new MainHandler(mHandlerThread.getLooper());
2184
2185        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2186                "foreground", BROADCAST_FG_TIMEOUT, false);
2187        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2188                "background", BROADCAST_BG_TIMEOUT, true);
2189        mBroadcastQueues[0] = mFgBroadcastQueue;
2190        mBroadcastQueues[1] = mBgBroadcastQueue;
2191
2192        mServices = new ActiveServices(this);
2193        mProviderMap = new ProviderMap(this);
2194
2195        // TODO: Move creation of battery stats service outside of activity manager service.
2196        File dataDir = Environment.getDataDirectory();
2197        File systemDir = new File(dataDir, "system");
2198        systemDir.mkdirs();
2199        mBatteryStatsService = new BatteryStatsService(new File(
2200                systemDir, "batterystats.bin").toString(), mHandler);
2201        mBatteryStatsService.getActiveStatistics().readLocked();
2202        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2203        mOnBattery = DEBUG_POWER ? true
2204                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2205        mBatteryStatsService.getActiveStatistics().setCallback(this);
2206
2207        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2208
2209        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2210
2211        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2212
2213        // User 0 is the first and only user that runs at boot.
2214        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2215        mUserLru.add(Integer.valueOf(0));
2216        updateStartedUserArrayLocked();
2217
2218        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2219            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2220
2221        mConfiguration.setToDefaults();
2222        mConfiguration.setLocale(Locale.getDefault());
2223
2224        mConfigurationSeq = mConfiguration.seq = 1;
2225        mProcessCpuTracker.init();
2226
2227        mHasRecents = mContext.getResources().getBoolean(
2228                com.android.internal.R.bool.config_hasRecents);
2229
2230        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2231        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2232        mStackSupervisor = new ActivityStackSupervisor(this);
2233        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2234
2235        mProcessCpuThread = new Thread("CpuTracker") {
2236            @Override
2237            public void run() {
2238                while (true) {
2239                    try {
2240                        try {
2241                            synchronized(this) {
2242                                final long now = SystemClock.uptimeMillis();
2243                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2244                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2245                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2246                                //        + ", write delay=" + nextWriteDelay);
2247                                if (nextWriteDelay < nextCpuDelay) {
2248                                    nextCpuDelay = nextWriteDelay;
2249                                }
2250                                if (nextCpuDelay > 0) {
2251                                    mProcessCpuMutexFree.set(true);
2252                                    this.wait(nextCpuDelay);
2253                                }
2254                            }
2255                        } catch (InterruptedException e) {
2256                        }
2257                        updateCpuStatsNow();
2258                    } catch (Exception e) {
2259                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2260                    }
2261                }
2262            }
2263        };
2264
2265        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2266
2267        Watchdog.getInstance().addMonitor(this);
2268        Watchdog.getInstance().addThread(mHandler);
2269    }
2270
2271    public void setSystemServiceManager(SystemServiceManager mgr) {
2272        mSystemServiceManager = mgr;
2273    }
2274
2275    private void start() {
2276        Process.removeAllProcessGroups();
2277        mProcessCpuThread.start();
2278
2279        mBatteryStatsService.publish(mContext);
2280        mAppOpsService.publish(mContext);
2281        Slog.d("AppOps", "AppOpsService published");
2282        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2283    }
2284
2285    public void initPowerManagement() {
2286        mStackSupervisor.initPowerManagement();
2287        mBatteryStatsService.initPowerManagement();
2288    }
2289
2290    @Override
2291    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2292            throws RemoteException {
2293        if (code == SYSPROPS_TRANSACTION) {
2294            // We need to tell all apps about the system property change.
2295            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2296            synchronized(this) {
2297                final int NP = mProcessNames.getMap().size();
2298                for (int ip=0; ip<NP; ip++) {
2299                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2300                    final int NA = apps.size();
2301                    for (int ia=0; ia<NA; ia++) {
2302                        ProcessRecord app = apps.valueAt(ia);
2303                        if (app.thread != null) {
2304                            procs.add(app.thread.asBinder());
2305                        }
2306                    }
2307                }
2308            }
2309
2310            int N = procs.size();
2311            for (int i=0; i<N; i++) {
2312                Parcel data2 = Parcel.obtain();
2313                try {
2314                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2315                } catch (RemoteException e) {
2316                }
2317                data2.recycle();
2318            }
2319        }
2320        try {
2321            return super.onTransact(code, data, reply, flags);
2322        } catch (RuntimeException e) {
2323            // The activity manager only throws security exceptions, so let's
2324            // log all others.
2325            if (!(e instanceof SecurityException)) {
2326                Slog.wtf(TAG, "Activity Manager Crash", e);
2327            }
2328            throw e;
2329        }
2330    }
2331
2332    void updateCpuStats() {
2333        final long now = SystemClock.uptimeMillis();
2334        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2335            return;
2336        }
2337        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2338            synchronized (mProcessCpuThread) {
2339                mProcessCpuThread.notify();
2340            }
2341        }
2342    }
2343
2344    void updateCpuStatsNow() {
2345        synchronized (mProcessCpuThread) {
2346            mProcessCpuMutexFree.set(false);
2347            final long now = SystemClock.uptimeMillis();
2348            boolean haveNewCpuStats = false;
2349
2350            if (MONITOR_CPU_USAGE &&
2351                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2352                mLastCpuTime.set(now);
2353                haveNewCpuStats = true;
2354                mProcessCpuTracker.update();
2355                //Slog.i(TAG, mProcessCpu.printCurrentState());
2356                //Slog.i(TAG, "Total CPU usage: "
2357                //        + mProcessCpu.getTotalCpuPercent() + "%");
2358
2359                // Slog the cpu usage if the property is set.
2360                if ("true".equals(SystemProperties.get("events.cpu"))) {
2361                    int user = mProcessCpuTracker.getLastUserTime();
2362                    int system = mProcessCpuTracker.getLastSystemTime();
2363                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2364                    int irq = mProcessCpuTracker.getLastIrqTime();
2365                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2366                    int idle = mProcessCpuTracker.getLastIdleTime();
2367
2368                    int total = user + system + iowait + irq + softIrq + idle;
2369                    if (total == 0) total = 1;
2370
2371                    EventLog.writeEvent(EventLogTags.CPU,
2372                            ((user+system+iowait+irq+softIrq) * 100) / total,
2373                            (user * 100) / total,
2374                            (system * 100) / total,
2375                            (iowait * 100) / total,
2376                            (irq * 100) / total,
2377                            (softIrq * 100) / total);
2378                }
2379            }
2380
2381            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2382            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2383            synchronized(bstats) {
2384                synchronized(mPidsSelfLocked) {
2385                    if (haveNewCpuStats) {
2386                        if (mOnBattery) {
2387                            int perc = bstats.startAddingCpuLocked();
2388                            int totalUTime = 0;
2389                            int totalSTime = 0;
2390                            final int N = mProcessCpuTracker.countStats();
2391                            for (int i=0; i<N; i++) {
2392                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2393                                if (!st.working) {
2394                                    continue;
2395                                }
2396                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2397                                int otherUTime = (st.rel_utime*perc)/100;
2398                                int otherSTime = (st.rel_stime*perc)/100;
2399                                totalUTime += otherUTime;
2400                                totalSTime += otherSTime;
2401                                if (pr != null) {
2402                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2403                                    if (ps == null || !ps.isActive()) {
2404                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2405                                                pr.info.uid, pr.processName);
2406                                    }
2407                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2408                                            st.rel_stime-otherSTime);
2409                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2410                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2411                                } else {
2412                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2413                                    if (ps == null || !ps.isActive()) {
2414                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2415                                                bstats.mapUid(st.uid), st.name);
2416                                    }
2417                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2418                                            st.rel_stime-otherSTime);
2419                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2420                                }
2421                            }
2422                            bstats.finishAddingCpuLocked(perc, totalUTime,
2423                                    totalSTime, cpuSpeedTimes);
2424                        }
2425                    }
2426                }
2427
2428                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2429                    mLastWriteTime = now;
2430                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2431                }
2432            }
2433        }
2434    }
2435
2436    @Override
2437    public void batteryNeedsCpuUpdate() {
2438        updateCpuStatsNow();
2439    }
2440
2441    @Override
2442    public void batteryPowerChanged(boolean onBattery) {
2443        // When plugging in, update the CPU stats first before changing
2444        // the plug state.
2445        updateCpuStatsNow();
2446        synchronized (this) {
2447            synchronized(mPidsSelfLocked) {
2448                mOnBattery = DEBUG_POWER ? true : onBattery;
2449            }
2450        }
2451    }
2452
2453    /**
2454     * Initialize the application bind args. These are passed to each
2455     * process when the bindApplication() IPC is sent to the process. They're
2456     * lazily setup to make sure the services are running when they're asked for.
2457     */
2458    private HashMap<String, IBinder> getCommonServicesLocked() {
2459        if (mAppBindArgs == null) {
2460            mAppBindArgs = new HashMap<String, IBinder>();
2461
2462            // Setup the application init args
2463            mAppBindArgs.put("package", ServiceManager.getService("package"));
2464            mAppBindArgs.put("window", ServiceManager.getService("window"));
2465            mAppBindArgs.put(Context.ALARM_SERVICE,
2466                    ServiceManager.getService(Context.ALARM_SERVICE));
2467        }
2468        return mAppBindArgs;
2469    }
2470
2471    final void setFocusedActivityLocked(ActivityRecord r) {
2472        if (mFocusedActivity != r) {
2473            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2474            mFocusedActivity = r;
2475            if (r.task != null && r.task.voiceInteractor != null) {
2476                startRunningVoiceLocked();
2477            } else {
2478                finishRunningVoiceLocked();
2479            }
2480            mStackSupervisor.setFocusedStack(r);
2481            if (r != null) {
2482                mWindowManager.setFocusedApp(r.appToken, true);
2483            }
2484            applyUpdateLockStateLocked(r);
2485        }
2486    }
2487
2488    final void clearFocusedActivity(ActivityRecord r) {
2489        if (mFocusedActivity == r) {
2490            mFocusedActivity = null;
2491        }
2492    }
2493
2494    @Override
2495    public void setFocusedStack(int stackId) {
2496        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2497        synchronized (ActivityManagerService.this) {
2498            ActivityStack stack = mStackSupervisor.getStack(stackId);
2499            if (stack != null) {
2500                ActivityRecord r = stack.topRunningActivityLocked(null);
2501                if (r != null) {
2502                    setFocusedActivityLocked(r);
2503                }
2504            }
2505        }
2506    }
2507
2508    @Override
2509    public void notifyActivityDrawn(IBinder token) {
2510        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2511        synchronized (this) {
2512            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2513            if (r != null) {
2514                r.task.stack.notifyActivityDrawnLocked(r);
2515            }
2516        }
2517    }
2518
2519    final void applyUpdateLockStateLocked(ActivityRecord r) {
2520        // Modifications to the UpdateLock state are done on our handler, outside
2521        // the activity manager's locks.  The new state is determined based on the
2522        // state *now* of the relevant activity record.  The object is passed to
2523        // the handler solely for logging detail, not to be consulted/modified.
2524        final boolean nextState = r != null && r.immersive;
2525        mHandler.sendMessage(
2526                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2527    }
2528
2529    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2530        Message msg = Message.obtain();
2531        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2532        msg.obj = r.task.askedCompatMode ? null : r;
2533        mHandler.sendMessage(msg);
2534    }
2535
2536    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2537            String what, Object obj, ProcessRecord srcApp) {
2538        app.lastActivityTime = now;
2539
2540        if (app.activities.size() > 0) {
2541            // Don't want to touch dependent processes that are hosting activities.
2542            return index;
2543        }
2544
2545        int lrui = mLruProcesses.lastIndexOf(app);
2546        if (lrui < 0) {
2547            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2548                    + what + " " + obj + " from " + srcApp);
2549            return index;
2550        }
2551
2552        if (lrui >= index) {
2553            // Don't want to cause this to move dependent processes *back* in the
2554            // list as if they were less frequently used.
2555            return index;
2556        }
2557
2558        if (lrui >= mLruProcessActivityStart) {
2559            // Don't want to touch dependent processes that are hosting activities.
2560            return index;
2561        }
2562
2563        mLruProcesses.remove(lrui);
2564        if (index > 0) {
2565            index--;
2566        }
2567        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2568                + " in LRU list: " + app);
2569        mLruProcesses.add(index, app);
2570        return index;
2571    }
2572
2573    final void removeLruProcessLocked(ProcessRecord app) {
2574        int lrui = mLruProcesses.lastIndexOf(app);
2575        if (lrui >= 0) {
2576            if (lrui <= mLruProcessActivityStart) {
2577                mLruProcessActivityStart--;
2578            }
2579            if (lrui <= mLruProcessServiceStart) {
2580                mLruProcessServiceStart--;
2581            }
2582            mLruProcesses.remove(lrui);
2583        }
2584    }
2585
2586    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2587            ProcessRecord client) {
2588        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2589                || app.treatLikeActivity;
2590        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2591        if (!activityChange && hasActivity) {
2592            // The process has activities, so we are only allowing activity-based adjustments
2593            // to move it.  It should be kept in the front of the list with other
2594            // processes that have activities, and we don't want those to change their
2595            // order except due to activity operations.
2596            return;
2597        }
2598
2599        mLruSeq++;
2600        final long now = SystemClock.uptimeMillis();
2601        app.lastActivityTime = now;
2602
2603        // First a quick reject: if the app is already at the position we will
2604        // put it, then there is nothing to do.
2605        if (hasActivity) {
2606            final int N = mLruProcesses.size();
2607            if (N > 0 && mLruProcesses.get(N-1) == app) {
2608                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2609                return;
2610            }
2611        } else {
2612            if (mLruProcessServiceStart > 0
2613                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2614                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2615                return;
2616            }
2617        }
2618
2619        int lrui = mLruProcesses.lastIndexOf(app);
2620
2621        if (app.persistent && lrui >= 0) {
2622            // We don't care about the position of persistent processes, as long as
2623            // they are in the list.
2624            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2625            return;
2626        }
2627
2628        /* In progress: compute new position first, so we can avoid doing work
2629           if the process is not actually going to move.  Not yet working.
2630        int addIndex;
2631        int nextIndex;
2632        boolean inActivity = false, inService = false;
2633        if (hasActivity) {
2634            // Process has activities, put it at the very tipsy-top.
2635            addIndex = mLruProcesses.size();
2636            nextIndex = mLruProcessServiceStart;
2637            inActivity = true;
2638        } else if (hasService) {
2639            // Process has services, put it at the top of the service list.
2640            addIndex = mLruProcessActivityStart;
2641            nextIndex = mLruProcessServiceStart;
2642            inActivity = true;
2643            inService = true;
2644        } else  {
2645            // Process not otherwise of interest, it goes to the top of the non-service area.
2646            addIndex = mLruProcessServiceStart;
2647            if (client != null) {
2648                int clientIndex = mLruProcesses.lastIndexOf(client);
2649                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2650                        + app);
2651                if (clientIndex >= 0 && addIndex > clientIndex) {
2652                    addIndex = clientIndex;
2653                }
2654            }
2655            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2656        }
2657
2658        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2659                + mLruProcessActivityStart + "): " + app);
2660        */
2661
2662        if (lrui >= 0) {
2663            if (lrui < mLruProcessActivityStart) {
2664                mLruProcessActivityStart--;
2665            }
2666            if (lrui < mLruProcessServiceStart) {
2667                mLruProcessServiceStart--;
2668            }
2669            /*
2670            if (addIndex > lrui) {
2671                addIndex--;
2672            }
2673            if (nextIndex > lrui) {
2674                nextIndex--;
2675            }
2676            */
2677            mLruProcesses.remove(lrui);
2678        }
2679
2680        /*
2681        mLruProcesses.add(addIndex, app);
2682        if (inActivity) {
2683            mLruProcessActivityStart++;
2684        }
2685        if (inService) {
2686            mLruProcessActivityStart++;
2687        }
2688        */
2689
2690        int nextIndex;
2691        if (hasActivity) {
2692            final int N = mLruProcesses.size();
2693            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2694                // Process doesn't have activities, but has clients with
2695                // activities...  move it up, but one below the top (the top
2696                // should always have a real activity).
2697                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2698                mLruProcesses.add(N-1, app);
2699                // To keep it from spamming the LRU list (by making a bunch of clients),
2700                // we will push down any other entries owned by the app.
2701                final int uid = app.info.uid;
2702                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2703                    ProcessRecord subProc = mLruProcesses.get(i);
2704                    if (subProc.info.uid == uid) {
2705                        // We want to push this one down the list.  If the process after
2706                        // it is for the same uid, however, don't do so, because we don't
2707                        // want them internally to be re-ordered.
2708                        if (mLruProcesses.get(i-1).info.uid != uid) {
2709                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2710                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2711                            ProcessRecord tmp = mLruProcesses.get(i);
2712                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2713                            mLruProcesses.set(i-1, tmp);
2714                            i--;
2715                        }
2716                    } else {
2717                        // A gap, we can stop here.
2718                        break;
2719                    }
2720                }
2721            } else {
2722                // Process has activities, put it at the very tipsy-top.
2723                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2724                mLruProcesses.add(app);
2725            }
2726            nextIndex = mLruProcessServiceStart;
2727        } else if (hasService) {
2728            // Process has services, put it at the top of the service list.
2729            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2730            mLruProcesses.add(mLruProcessActivityStart, app);
2731            nextIndex = mLruProcessServiceStart;
2732            mLruProcessActivityStart++;
2733        } else  {
2734            // Process not otherwise of interest, it goes to the top of the non-service area.
2735            int index = mLruProcessServiceStart;
2736            if (client != null) {
2737                // If there is a client, don't allow the process to be moved up higher
2738                // in the list than that client.
2739                int clientIndex = mLruProcesses.lastIndexOf(client);
2740                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2741                        + " when updating " + app);
2742                if (clientIndex <= lrui) {
2743                    // Don't allow the client index restriction to push it down farther in the
2744                    // list than it already is.
2745                    clientIndex = lrui;
2746                }
2747                if (clientIndex >= 0 && index > clientIndex) {
2748                    index = clientIndex;
2749                }
2750            }
2751            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2752            mLruProcesses.add(index, app);
2753            nextIndex = index-1;
2754            mLruProcessActivityStart++;
2755            mLruProcessServiceStart++;
2756        }
2757
2758        // If the app is currently using a content provider or service,
2759        // bump those processes as well.
2760        for (int j=app.connections.size()-1; j>=0; j--) {
2761            ConnectionRecord cr = app.connections.valueAt(j);
2762            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2763                    && cr.binding.service.app != null
2764                    && cr.binding.service.app.lruSeq != mLruSeq
2765                    && !cr.binding.service.app.persistent) {
2766                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2767                        "service connection", cr, app);
2768            }
2769        }
2770        for (int j=app.conProviders.size()-1; j>=0; j--) {
2771            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2772            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2773                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2774                        "provider reference", cpr, app);
2775            }
2776        }
2777    }
2778
2779    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2780        if (uid == Process.SYSTEM_UID) {
2781            // The system gets to run in any process.  If there are multiple
2782            // processes with the same uid, just pick the first (this
2783            // should never happen).
2784            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2785            if (procs == null) return null;
2786            final int N = procs.size();
2787            for (int i = 0; i < N; i++) {
2788                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2789            }
2790        }
2791        ProcessRecord proc = mProcessNames.get(processName, uid);
2792        if (false && proc != null && !keepIfLarge
2793                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2794                && proc.lastCachedPss >= 4000) {
2795            // Turn this condition on to cause killing to happen regularly, for testing.
2796            if (proc.baseProcessTracker != null) {
2797                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2798            }
2799            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2800                    + "k from cached");
2801        } else if (proc != null && !keepIfLarge
2802                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2803                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2804            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2805            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2806                if (proc.baseProcessTracker != null) {
2807                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2808                }
2809                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2810                        + "k from cached");
2811            }
2812        }
2813        return proc;
2814    }
2815
2816    void ensurePackageDexOpt(String packageName) {
2817        IPackageManager pm = AppGlobals.getPackageManager();
2818        try {
2819            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2820                mDidDexOpt = true;
2821            }
2822        } catch (RemoteException e) {
2823        }
2824    }
2825
2826    boolean isNextTransitionForward() {
2827        int transit = mWindowManager.getPendingAppTransition();
2828        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2829                || transit == AppTransition.TRANSIT_TASK_OPEN
2830                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2831    }
2832
2833    final ProcessRecord startProcessLocked(String processName,
2834            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2835            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2836            boolean isolated, boolean keepIfLarge) {
2837        ProcessRecord app;
2838        if (!isolated) {
2839            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2840        } else {
2841            // If this is an isolated process, it can't re-use an existing process.
2842            app = null;
2843        }
2844        // We don't have to do anything more if:
2845        // (1) There is an existing application record; and
2846        // (2) The caller doesn't think it is dead, OR there is no thread
2847        //     object attached to it so we know it couldn't have crashed; and
2848        // (3) There is a pid assigned to it, so it is either starting or
2849        //     already running.
2850        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2851                + " app=" + app + " knownToBeDead=" + knownToBeDead
2852                + " thread=" + (app != null ? app.thread : null)
2853                + " pid=" + (app != null ? app.pid : -1));
2854        if (app != null && app.pid > 0) {
2855            if (!knownToBeDead || app.thread == null) {
2856                // We already have the app running, or are waiting for it to
2857                // come up (we have a pid but not yet its thread), so keep it.
2858                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2859                // If this is a new package in the process, add the package to the list
2860                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2861                return app;
2862            }
2863
2864            // An application record is attached to a previous process,
2865            // clean it up now.
2866            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2867            Process.killProcessGroup(app.info.uid, app.pid);
2868            handleAppDiedLocked(app, true, true);
2869        }
2870
2871        String hostingNameStr = hostingName != null
2872                ? hostingName.flattenToShortString() : null;
2873
2874        if (!isolated) {
2875            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2876                // If we are in the background, then check to see if this process
2877                // is bad.  If so, we will just silently fail.
2878                if (mBadProcesses.get(info.processName, info.uid) != null) {
2879                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2880                            + "/" + info.processName);
2881                    return null;
2882                }
2883            } else {
2884                // When the user is explicitly starting a process, then clear its
2885                // crash count so that we won't make it bad until they see at
2886                // least one crash dialog again, and make the process good again
2887                // if it had been bad.
2888                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2889                        + "/" + info.processName);
2890                mProcessCrashTimes.remove(info.processName, info.uid);
2891                if (mBadProcesses.get(info.processName, info.uid) != null) {
2892                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2893                            UserHandle.getUserId(info.uid), info.uid,
2894                            info.processName);
2895                    mBadProcesses.remove(info.processName, info.uid);
2896                    if (app != null) {
2897                        app.bad = false;
2898                    }
2899                }
2900            }
2901        }
2902
2903        if (app == null) {
2904            app = newProcessRecordLocked(info, processName, isolated);
2905            if (app == null) {
2906                Slog.w(TAG, "Failed making new process record for "
2907                        + processName + "/" + info.uid + " isolated=" + isolated);
2908                return null;
2909            }
2910            mProcessNames.put(processName, app.uid, app);
2911            if (isolated) {
2912                mIsolatedProcesses.put(app.uid, app);
2913            }
2914        } else {
2915            // If this is a new package in the process, add the package to the list
2916            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2917        }
2918
2919        // If the system is not ready yet, then hold off on starting this
2920        // process until it is.
2921        if (!mProcessesReady
2922                && !isAllowedWhileBooting(info)
2923                && !allowWhileBooting) {
2924            if (!mProcessesOnHold.contains(app)) {
2925                mProcessesOnHold.add(app);
2926            }
2927            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2928            return app;
2929        }
2930
2931        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2932        return (app.pid != 0) ? app : null;
2933    }
2934
2935    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2936        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2937    }
2938
2939    private final void startProcessLocked(ProcessRecord app,
2940            String hostingType, String hostingNameStr, String abiOverride) {
2941        if (app.pid > 0 && app.pid != MY_PID) {
2942            synchronized (mPidsSelfLocked) {
2943                mPidsSelfLocked.remove(app.pid);
2944                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2945            }
2946            app.setPid(0);
2947        }
2948
2949        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2950                "startProcessLocked removing on hold: " + app);
2951        mProcessesOnHold.remove(app);
2952
2953        updateCpuStats();
2954
2955        try {
2956            int uid = app.uid;
2957
2958            int[] gids = null;
2959            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2960            if (!app.isolated) {
2961                int[] permGids = null;
2962                try {
2963                    final PackageManager pm = mContext.getPackageManager();
2964                    permGids = pm.getPackageGids(app.info.packageName);
2965
2966                    if (Environment.isExternalStorageEmulated()) {
2967                        if (pm.checkPermission(
2968                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2969                                app.info.packageName) == PERMISSION_GRANTED) {
2970                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2971                        } else {
2972                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2973                        }
2974                    }
2975                } catch (PackageManager.NameNotFoundException e) {
2976                    Slog.w(TAG, "Unable to retrieve gids", e);
2977                }
2978
2979                /*
2980                 * Add shared application and profile GIDs so applications can share some
2981                 * resources like shared libraries and access user-wide resources
2982                 */
2983                if (permGids == null) {
2984                    gids = new int[2];
2985                } else {
2986                    gids = new int[permGids.length + 2];
2987                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2988                }
2989                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2990                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2991            }
2992            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2993                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2994                        && mTopComponent != null
2995                        && app.processName.equals(mTopComponent.getPackageName())) {
2996                    uid = 0;
2997                }
2998                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2999                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3000                    uid = 0;
3001                }
3002            }
3003            int debugFlags = 0;
3004            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3005                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3006                // Also turn on CheckJNI for debuggable apps. It's quite
3007                // awkward to turn on otherwise.
3008                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3009            }
3010            // Run the app in safe mode if its manifest requests so or the
3011            // system is booted in safe mode.
3012            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3013                mSafeMode == true) {
3014                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3015            }
3016            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3017                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3018            }
3019            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3020                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3021            }
3022            if ("1".equals(SystemProperties.get("debug.assert"))) {
3023                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3024            }
3025
3026            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3027            if (requiredAbi == null) {
3028                requiredAbi = Build.SUPPORTED_ABIS[0];
3029            }
3030
3031            // Start the process.  It will either succeed and return a result containing
3032            // the PID of the new process, or else throw a RuntimeException.
3033            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
3034                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3035                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
3036
3037            if (app.isolated) {
3038                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3039            }
3040            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3041
3042            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3043                    UserHandle.getUserId(uid), startResult.pid, uid,
3044                    app.processName, hostingType,
3045                    hostingNameStr != null ? hostingNameStr : "");
3046
3047            if (app.persistent) {
3048                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3049            }
3050
3051            StringBuilder buf = mStringBuilder;
3052            buf.setLength(0);
3053            buf.append("Start proc ");
3054            buf.append(app.processName);
3055            buf.append(" for ");
3056            buf.append(hostingType);
3057            if (hostingNameStr != null) {
3058                buf.append(" ");
3059                buf.append(hostingNameStr);
3060            }
3061            buf.append(": pid=");
3062            buf.append(startResult.pid);
3063            buf.append(" uid=");
3064            buf.append(uid);
3065            buf.append(" gids={");
3066            if (gids != null) {
3067                for (int gi=0; gi<gids.length; gi++) {
3068                    if (gi != 0) buf.append(", ");
3069                    buf.append(gids[gi]);
3070
3071                }
3072            }
3073            buf.append("}");
3074            if (requiredAbi != null) {
3075                buf.append(" abi=");
3076                buf.append(requiredAbi);
3077            }
3078            Slog.i(TAG, buf.toString());
3079            app.setPid(startResult.pid);
3080            app.usingWrapper = startResult.usingWrapper;
3081            app.removed = false;
3082            app.killedByAm = false;
3083            synchronized (mPidsSelfLocked) {
3084                this.mPidsSelfLocked.put(startResult.pid, app);
3085                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3086                msg.obj = app;
3087                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3088                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3089            }
3090        } catch (RuntimeException e) {
3091            // XXX do better error recovery.
3092            app.setPid(0);
3093            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3094            if (app.isolated) {
3095                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3096            }
3097            Slog.e(TAG, "Failure starting process " + app.processName, e);
3098        }
3099    }
3100
3101    void updateUsageStats(ActivityRecord component, boolean resumed) {
3102        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3103        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3104        if (resumed) {
3105            if (mUsageStatsService != null) {
3106                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3107                        System.currentTimeMillis(),
3108                        UsageStats.Event.MOVE_TO_FOREGROUND);
3109            }
3110            synchronized (stats) {
3111                stats.noteActivityResumedLocked(component.app.uid);
3112            }
3113        } else {
3114            if (mUsageStatsService != null) {
3115                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3116                        System.currentTimeMillis(),
3117                        UsageStats.Event.MOVE_TO_BACKGROUND);
3118            }
3119            synchronized (stats) {
3120                stats.noteActivityPausedLocked(component.app.uid);
3121            }
3122        }
3123    }
3124
3125    Intent getHomeIntent() {
3126        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3127        intent.setComponent(mTopComponent);
3128        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3129            intent.addCategory(Intent.CATEGORY_HOME);
3130        }
3131        return intent;
3132    }
3133
3134    boolean startHomeActivityLocked(int userId) {
3135        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3136                && mTopAction == null) {
3137            // We are running in factory test mode, but unable to find
3138            // the factory test app, so just sit around displaying the
3139            // error message and don't try to start anything.
3140            return false;
3141        }
3142        Intent intent = getHomeIntent();
3143        ActivityInfo aInfo =
3144            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3145        if (aInfo != null) {
3146            intent.setComponent(new ComponentName(
3147                    aInfo.applicationInfo.packageName, aInfo.name));
3148            // Don't do this if the home app is currently being
3149            // instrumented.
3150            aInfo = new ActivityInfo(aInfo);
3151            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3152            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3153                    aInfo.applicationInfo.uid, true);
3154            if (app == null || app.instrumentationClass == null) {
3155                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3156                mStackSupervisor.startHomeActivity(intent, aInfo);
3157            }
3158        }
3159
3160        return true;
3161    }
3162
3163    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3164        ActivityInfo ai = null;
3165        ComponentName comp = intent.getComponent();
3166        try {
3167            if (comp != null) {
3168                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3169            } else {
3170                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3171                        intent,
3172                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3173                            flags, userId);
3174
3175                if (info != null) {
3176                    ai = info.activityInfo;
3177                }
3178            }
3179        } catch (RemoteException e) {
3180            // ignore
3181        }
3182
3183        return ai;
3184    }
3185
3186    /**
3187     * Starts the "new version setup screen" if appropriate.
3188     */
3189    void startSetupActivityLocked() {
3190        // Only do this once per boot.
3191        if (mCheckedForSetup) {
3192            return;
3193        }
3194
3195        // We will show this screen if the current one is a different
3196        // version than the last one shown, and we are not running in
3197        // low-level factory test mode.
3198        final ContentResolver resolver = mContext.getContentResolver();
3199        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3200                Settings.Global.getInt(resolver,
3201                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3202            mCheckedForSetup = true;
3203
3204            // See if we should be showing the platform update setup UI.
3205            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3206            List<ResolveInfo> ris = mContext.getPackageManager()
3207                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3208
3209            // We don't allow third party apps to replace this.
3210            ResolveInfo ri = null;
3211            for (int i=0; ris != null && i<ris.size(); i++) {
3212                if ((ris.get(i).activityInfo.applicationInfo.flags
3213                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3214                    ri = ris.get(i);
3215                    break;
3216                }
3217            }
3218
3219            if (ri != null) {
3220                String vers = ri.activityInfo.metaData != null
3221                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3222                        : null;
3223                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3224                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3225                            Intent.METADATA_SETUP_VERSION);
3226                }
3227                String lastVers = Settings.Secure.getString(
3228                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3229                if (vers != null && !vers.equals(lastVers)) {
3230                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3231                    intent.setComponent(new ComponentName(
3232                            ri.activityInfo.packageName, ri.activityInfo.name));
3233                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3234                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3235                }
3236            }
3237        }
3238    }
3239
3240    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3241        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3242    }
3243
3244    void enforceNotIsolatedCaller(String caller) {
3245        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3246            throw new SecurityException("Isolated process not allowed to call " + caller);
3247        }
3248    }
3249
3250    @Override
3251    public int getFrontActivityScreenCompatMode() {
3252        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3253        synchronized (this) {
3254            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3255        }
3256    }
3257
3258    @Override
3259    public void setFrontActivityScreenCompatMode(int mode) {
3260        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3261                "setFrontActivityScreenCompatMode");
3262        synchronized (this) {
3263            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3264        }
3265    }
3266
3267    @Override
3268    public int getPackageScreenCompatMode(String packageName) {
3269        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3270        synchronized (this) {
3271            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3272        }
3273    }
3274
3275    @Override
3276    public void setPackageScreenCompatMode(String packageName, int mode) {
3277        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3278                "setPackageScreenCompatMode");
3279        synchronized (this) {
3280            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3281        }
3282    }
3283
3284    @Override
3285    public boolean getPackageAskScreenCompat(String packageName) {
3286        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3287        synchronized (this) {
3288            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3289        }
3290    }
3291
3292    @Override
3293    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3294        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3295                "setPackageAskScreenCompat");
3296        synchronized (this) {
3297            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3298        }
3299    }
3300
3301    private void dispatchProcessesChanged() {
3302        int N;
3303        synchronized (this) {
3304            N = mPendingProcessChanges.size();
3305            if (mActiveProcessChanges.length < N) {
3306                mActiveProcessChanges = new ProcessChangeItem[N];
3307            }
3308            mPendingProcessChanges.toArray(mActiveProcessChanges);
3309            mAvailProcessChanges.addAll(mPendingProcessChanges);
3310            mPendingProcessChanges.clear();
3311            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3312        }
3313
3314        int i = mProcessObservers.beginBroadcast();
3315        while (i > 0) {
3316            i--;
3317            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3318            if (observer != null) {
3319                try {
3320                    for (int j=0; j<N; j++) {
3321                        ProcessChangeItem item = mActiveProcessChanges[j];
3322                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3323                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3324                                    + item.pid + " uid=" + item.uid + ": "
3325                                    + item.foregroundActivities);
3326                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3327                                    item.foregroundActivities);
3328                        }
3329                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3330                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3331                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3332                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3333                        }
3334                    }
3335                } catch (RemoteException e) {
3336                }
3337            }
3338        }
3339        mProcessObservers.finishBroadcast();
3340    }
3341
3342    private void dispatchProcessDied(int pid, int uid) {
3343        int i = mProcessObservers.beginBroadcast();
3344        while (i > 0) {
3345            i--;
3346            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3347            if (observer != null) {
3348                try {
3349                    observer.onProcessDied(pid, uid);
3350                } catch (RemoteException e) {
3351                }
3352            }
3353        }
3354        mProcessObservers.finishBroadcast();
3355    }
3356
3357    @Override
3358    public final int startActivity(IApplicationThread caller, String callingPackage,
3359            Intent intent, String resolvedType, IBinder resultTo,
3360            String resultWho, int requestCode, int startFlags,
3361            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3362        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3363                resultWho, requestCode,
3364                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3365    }
3366
3367    @Override
3368    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3369            Intent intent, String resolvedType, IBinder resultTo,
3370            String resultWho, int requestCode, int startFlags,
3371            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3372        enforceNotIsolatedCaller("startActivity");
3373        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3374                false, ALLOW_FULL_ONLY, "startActivity", null);
3375        // TODO: Switch to user app stacks here.
3376        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3377                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3378                null, null, options, userId, null);
3379    }
3380
3381    @Override
3382    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3383            Intent intent, String resolvedType, IBinder resultTo,
3384            String resultWho, int requestCode, int startFlags, String profileFile,
3385            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3386        enforceNotIsolatedCaller("startActivityAndWait");
3387        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3388                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3389        WaitResult res = new WaitResult();
3390        // TODO: Switch to user app stacks here.
3391        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3392                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3393                res, null, options, userId, null);
3394        return res;
3395    }
3396
3397    @Override
3398    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3399            Intent intent, String resolvedType, IBinder resultTo,
3400            String resultWho, int requestCode, int startFlags, Configuration config,
3401            Bundle options, int userId) {
3402        enforceNotIsolatedCaller("startActivityWithConfig");
3403        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3404                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3405        // TODO: Switch to user app stacks here.
3406        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3407                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3408                null, null, null, config, options, userId, null);
3409        return ret;
3410    }
3411
3412    @Override
3413    public int startActivityIntentSender(IApplicationThread caller,
3414            IntentSender intent, Intent fillInIntent, String resolvedType,
3415            IBinder resultTo, String resultWho, int requestCode,
3416            int flagsMask, int flagsValues, Bundle options) {
3417        enforceNotIsolatedCaller("startActivityIntentSender");
3418        // Refuse possible leaked file descriptors
3419        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3420            throw new IllegalArgumentException("File descriptors passed in Intent");
3421        }
3422
3423        IIntentSender sender = intent.getTarget();
3424        if (!(sender instanceof PendingIntentRecord)) {
3425            throw new IllegalArgumentException("Bad PendingIntent object");
3426        }
3427
3428        PendingIntentRecord pir = (PendingIntentRecord)sender;
3429
3430        synchronized (this) {
3431            // If this is coming from the currently resumed activity, it is
3432            // effectively saying that app switches are allowed at this point.
3433            final ActivityStack stack = getFocusedStack();
3434            if (stack.mResumedActivity != null &&
3435                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3436                mAppSwitchesAllowedTime = 0;
3437            }
3438        }
3439        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3440                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3441        return ret;
3442    }
3443
3444    @Override
3445    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3446            Intent intent, String resolvedType, IVoiceInteractionSession session,
3447            IVoiceInteractor interactor, int startFlags, String profileFile,
3448            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3449        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3450                != PackageManager.PERMISSION_GRANTED) {
3451            String msg = "Permission Denial: startVoiceActivity() from pid="
3452                    + Binder.getCallingPid()
3453                    + ", uid=" + Binder.getCallingUid()
3454                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3455            Slog.w(TAG, msg);
3456            throw new SecurityException(msg);
3457        }
3458        if (session == null || interactor == null) {
3459            throw new NullPointerException("null session or interactor");
3460        }
3461        userId = handleIncomingUser(callingPid, callingUid, userId,
3462                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3463        // TODO: Switch to user app stacks here.
3464        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3465                resolvedType, session, interactor, null, null, 0, startFlags,
3466                profileFile, profileFd, null, null, options, userId, null);
3467    }
3468
3469    @Override
3470    public boolean startNextMatchingActivity(IBinder callingActivity,
3471            Intent intent, Bundle options) {
3472        // Refuse possible leaked file descriptors
3473        if (intent != null && intent.hasFileDescriptors() == true) {
3474            throw new IllegalArgumentException("File descriptors passed in Intent");
3475        }
3476
3477        synchronized (this) {
3478            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3479            if (r == null) {
3480                ActivityOptions.abort(options);
3481                return false;
3482            }
3483            if (r.app == null || r.app.thread == null) {
3484                // The caller is not running...  d'oh!
3485                ActivityOptions.abort(options);
3486                return false;
3487            }
3488            intent = new Intent(intent);
3489            // The caller is not allowed to change the data.
3490            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3491            // And we are resetting to find the next component...
3492            intent.setComponent(null);
3493
3494            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3495
3496            ActivityInfo aInfo = null;
3497            try {
3498                List<ResolveInfo> resolves =
3499                    AppGlobals.getPackageManager().queryIntentActivities(
3500                            intent, r.resolvedType,
3501                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3502                            UserHandle.getCallingUserId());
3503
3504                // Look for the original activity in the list...
3505                final int N = resolves != null ? resolves.size() : 0;
3506                for (int i=0; i<N; i++) {
3507                    ResolveInfo rInfo = resolves.get(i);
3508                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3509                            && rInfo.activityInfo.name.equals(r.info.name)) {
3510                        // We found the current one...  the next matching is
3511                        // after it.
3512                        i++;
3513                        if (i<N) {
3514                            aInfo = resolves.get(i).activityInfo;
3515                        }
3516                        if (debug) {
3517                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3518                                    + "/" + r.info.name);
3519                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3520                                    + "/" + aInfo.name);
3521                        }
3522                        break;
3523                    }
3524                }
3525            } catch (RemoteException e) {
3526            }
3527
3528            if (aInfo == null) {
3529                // Nobody who is next!
3530                ActivityOptions.abort(options);
3531                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3532                return false;
3533            }
3534
3535            intent.setComponent(new ComponentName(
3536                    aInfo.applicationInfo.packageName, aInfo.name));
3537            intent.setFlags(intent.getFlags()&~(
3538                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3539                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3540                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3541                    Intent.FLAG_ACTIVITY_NEW_TASK));
3542
3543            // Okay now we need to start the new activity, replacing the
3544            // currently running activity.  This is a little tricky because
3545            // we want to start the new one as if the current one is finished,
3546            // but not finish the current one first so that there is no flicker.
3547            // And thus...
3548            final boolean wasFinishing = r.finishing;
3549            r.finishing = true;
3550
3551            // Propagate reply information over to the new activity.
3552            final ActivityRecord resultTo = r.resultTo;
3553            final String resultWho = r.resultWho;
3554            final int requestCode = r.requestCode;
3555            r.resultTo = null;
3556            if (resultTo != null) {
3557                resultTo.removeResultsLocked(r, resultWho, requestCode);
3558            }
3559
3560            final long origId = Binder.clearCallingIdentity();
3561            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3562                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3563                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3564                    options, false, null, null);
3565            Binder.restoreCallingIdentity(origId);
3566
3567            r.finishing = wasFinishing;
3568            if (res != ActivityManager.START_SUCCESS) {
3569                return false;
3570            }
3571            return true;
3572        }
3573    }
3574
3575    @Override
3576    public final int startActivityFromRecents(int taskId, Bundle options) {
3577        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3578            String msg = "Permission Denial: startActivityFromRecents called without " +
3579                    START_TASKS_FROM_RECENTS;
3580            Slog.w(TAG, msg);
3581            throw new SecurityException(msg);
3582        }
3583        final int callingUid;
3584        final String callingPackage;
3585        final Intent intent;
3586        final int userId;
3587        synchronized (this) {
3588            final TaskRecord task = recentTaskForIdLocked(taskId);
3589            if (task == null) {
3590                throw new ActivityNotFoundException("Task " + taskId + " not found.");
3591            }
3592            callingUid = task.mCallingUid;
3593            callingPackage = task.mCallingPackage;
3594            intent = task.intent;
3595            userId = task.userId;
3596        }
3597        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3598                options, userId, null);
3599    }
3600
3601    final int startActivityInPackage(int uid, String callingPackage,
3602            Intent intent, String resolvedType, IBinder resultTo,
3603            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3604                    IActivityContainer container) {
3605
3606        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3607                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3608
3609        // TODO: Switch to user app stacks here.
3610        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3611                null, null, resultTo, resultWho, requestCode, startFlags,
3612                null, null, null, null, options, userId, container);
3613        return ret;
3614    }
3615
3616    @Override
3617    public final int startActivities(IApplicationThread caller, String callingPackage,
3618            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3619            int userId) {
3620        enforceNotIsolatedCaller("startActivities");
3621        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3622                false, ALLOW_FULL_ONLY, "startActivity", null);
3623        // TODO: Switch to user app stacks here.
3624        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3625                resolvedTypes, resultTo, options, userId);
3626        return ret;
3627    }
3628
3629    final int startActivitiesInPackage(int uid, String callingPackage,
3630            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3631            Bundle options, int userId) {
3632
3633        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3634                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3635        // TODO: Switch to user app stacks here.
3636        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3637                resultTo, options, userId);
3638        return ret;
3639    }
3640
3641    //explicitly remove thd old information in mRecentTasks when removing existing user.
3642    private void removeRecentTasksForUser(int userId) {
3643        if(userId <= 0) {
3644            Slog.i(TAG, "Can't remove recent task on user " + userId);
3645            return;
3646        }
3647
3648        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3649            TaskRecord tr = mRecentTasks.get(i);
3650            if (tr.userId == userId) {
3651                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3652                        + " when finishing user" + userId);
3653                tr.disposeThumbnail();
3654                mRecentTasks.remove(i);
3655            }
3656        }
3657
3658        // Remove tasks from persistent storage.
3659        mTaskPersister.wakeup(null, true);
3660    }
3661
3662    final void addRecentTaskLocked(TaskRecord task) {
3663        int N = mRecentTasks.size();
3664        // Quick case: check if the top-most recent task is the same.
3665        if (N > 0 && mRecentTasks.get(0) == task) {
3666            return;
3667        }
3668        // Another quick case: never add voice sessions.
3669        if (task.voiceSession != null) {
3670            return;
3671        }
3672        // Remove any existing entries that are the same kind of task.
3673        final Intent intent = task.intent;
3674        final boolean document = intent != null && intent.isDocument();
3675        final ComponentName comp = intent.getComponent();
3676
3677        int maxRecents = task.maxRecents - 1;
3678        for (int i=0; i<N; i++) {
3679            final TaskRecord tr = mRecentTasks.get(i);
3680            if (task != tr) {
3681                if (task.userId != tr.userId) {
3682                    continue;
3683                }
3684                if (i > MAX_RECENT_BITMAPS) {
3685                    tr.freeLastThumbnail();
3686                }
3687                final Intent trIntent = tr.intent;
3688                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3689                    (intent == null || !intent.filterEquals(trIntent))) {
3690                    continue;
3691                }
3692                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3693                if (document && trIsDocument) {
3694                    // These are the same document activity (not necessarily the same doc).
3695                    if (maxRecents > 0) {
3696                        --maxRecents;
3697                        continue;
3698                    }
3699                    // Hit the maximum number of documents for this task. Fall through
3700                    // and remove this document from recents.
3701                } else if (document || trIsDocument) {
3702                    // Only one of these is a document. Not the droid we're looking for.
3703                    continue;
3704                }
3705            }
3706
3707            // Either task and tr are the same or, their affinities match or their intents match
3708            // and neither of them is a document, or they are documents using the same activity
3709            // and their maxRecents has been reached.
3710            tr.disposeThumbnail();
3711            mRecentTasks.remove(i);
3712            if (task != tr) {
3713                tr.closeRecentsChain();
3714            }
3715            i--;
3716            N--;
3717            if (task.intent == null) {
3718                // If the new recent task we are adding is not fully
3719                // specified, then replace it with the existing recent task.
3720                task = tr;
3721            }
3722            notifyTaskPersisterLocked(tr, false);
3723        }
3724        if (N >= MAX_RECENT_TASKS) {
3725            final TaskRecord tr = mRecentTasks.remove(N - 1);
3726            tr.disposeThumbnail();
3727            tr.closeRecentsChain();
3728        }
3729        mRecentTasks.add(0, task);
3730    }
3731
3732    @Override
3733    public void reportActivityFullyDrawn(IBinder token) {
3734        synchronized (this) {
3735            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3736            if (r == null) {
3737                return;
3738            }
3739            r.reportFullyDrawnLocked();
3740        }
3741    }
3742
3743    @Override
3744    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3745        synchronized (this) {
3746            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3747            if (r == null) {
3748                return;
3749            }
3750            final long origId = Binder.clearCallingIdentity();
3751            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3752            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3753                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3754            if (config != null) {
3755                r.frozenBeforeDestroy = true;
3756                if (!updateConfigurationLocked(config, r, false, false)) {
3757                    mStackSupervisor.resumeTopActivitiesLocked();
3758                }
3759            }
3760            Binder.restoreCallingIdentity(origId);
3761        }
3762    }
3763
3764    @Override
3765    public int getRequestedOrientation(IBinder token) {
3766        synchronized (this) {
3767            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3768            if (r == null) {
3769                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3770            }
3771            return mWindowManager.getAppOrientation(r.appToken);
3772        }
3773    }
3774
3775    /**
3776     * This is the internal entry point for handling Activity.finish().
3777     *
3778     * @param token The Binder token referencing the Activity we want to finish.
3779     * @param resultCode Result code, if any, from this Activity.
3780     * @param resultData Result data (Intent), if any, from this Activity.
3781     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3782     *            the root Activity in the task.
3783     *
3784     * @return Returns true if the activity successfully finished, or false if it is still running.
3785     */
3786    @Override
3787    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3788            boolean finishTask) {
3789        // Refuse possible leaked file descriptors
3790        if (resultData != null && resultData.hasFileDescriptors() == true) {
3791            throw new IllegalArgumentException("File descriptors passed in Intent");
3792        }
3793
3794        synchronized(this) {
3795            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3796            if (r == null) {
3797                return true;
3798            }
3799            // Keep track of the root activity of the task before we finish it
3800            TaskRecord tr = r.task;
3801            ActivityRecord rootR = tr.getRootActivity();
3802            // Do not allow task to finish in Lock Task mode.
3803            if (tr == mStackSupervisor.mLockTaskModeTask) {
3804                if (rootR == r) {
3805                    mStackSupervisor.showLockTaskToast();
3806                    return false;
3807                }
3808            }
3809            if (mController != null) {
3810                // Find the first activity that is not finishing.
3811                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3812                if (next != null) {
3813                    // ask watcher if this is allowed
3814                    boolean resumeOK = true;
3815                    try {
3816                        resumeOK = mController.activityResuming(next.packageName);
3817                    } catch (RemoteException e) {
3818                        mController = null;
3819                        Watchdog.getInstance().setActivityController(null);
3820                    }
3821
3822                    if (!resumeOK) {
3823                        return false;
3824                    }
3825                }
3826            }
3827            final long origId = Binder.clearCallingIdentity();
3828            try {
3829                boolean res;
3830                if (finishTask && r == rootR) {
3831                    // If requested, remove the task that is associated to this activity only if it
3832                    // was the root activity in the task.  The result code and data is ignored because
3833                    // we don't support returning them across task boundaries.
3834                    res = removeTaskByIdLocked(tr.taskId, 0);
3835                } else {
3836                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3837                            resultData, "app-request", true);
3838                }
3839                return res;
3840            } finally {
3841                Binder.restoreCallingIdentity(origId);
3842            }
3843        }
3844    }
3845
3846    @Override
3847    public final void finishHeavyWeightApp() {
3848        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3849                != PackageManager.PERMISSION_GRANTED) {
3850            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3851                    + Binder.getCallingPid()
3852                    + ", uid=" + Binder.getCallingUid()
3853                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3854            Slog.w(TAG, msg);
3855            throw new SecurityException(msg);
3856        }
3857
3858        synchronized(this) {
3859            if (mHeavyWeightProcess == null) {
3860                return;
3861            }
3862
3863            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3864                    mHeavyWeightProcess.activities);
3865            for (int i=0; i<activities.size(); i++) {
3866                ActivityRecord r = activities.get(i);
3867                if (!r.finishing) {
3868                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3869                            null, "finish-heavy", true);
3870                }
3871            }
3872
3873            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3874                    mHeavyWeightProcess.userId, 0));
3875            mHeavyWeightProcess = null;
3876        }
3877    }
3878
3879    @Override
3880    public void crashApplication(int uid, int initialPid, String packageName,
3881            String message) {
3882        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3883                != PackageManager.PERMISSION_GRANTED) {
3884            String msg = "Permission Denial: crashApplication() from pid="
3885                    + Binder.getCallingPid()
3886                    + ", uid=" + Binder.getCallingUid()
3887                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3888            Slog.w(TAG, msg);
3889            throw new SecurityException(msg);
3890        }
3891
3892        synchronized(this) {
3893            ProcessRecord proc = null;
3894
3895            // Figure out which process to kill.  We don't trust that initialPid
3896            // still has any relation to current pids, so must scan through the
3897            // list.
3898            synchronized (mPidsSelfLocked) {
3899                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3900                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3901                    if (p.uid != uid) {
3902                        continue;
3903                    }
3904                    if (p.pid == initialPid) {
3905                        proc = p;
3906                        break;
3907                    }
3908                    if (p.pkgList.containsKey(packageName)) {
3909                        proc = p;
3910                    }
3911                }
3912            }
3913
3914            if (proc == null) {
3915                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3916                        + " initialPid=" + initialPid
3917                        + " packageName=" + packageName);
3918                return;
3919            }
3920
3921            if (proc.thread != null) {
3922                if (proc.pid == Process.myPid()) {
3923                    Log.w(TAG, "crashApplication: trying to crash self!");
3924                    return;
3925                }
3926                long ident = Binder.clearCallingIdentity();
3927                try {
3928                    proc.thread.scheduleCrash(message);
3929                } catch (RemoteException e) {
3930                }
3931                Binder.restoreCallingIdentity(ident);
3932            }
3933        }
3934    }
3935
3936    @Override
3937    public final void finishSubActivity(IBinder token, String resultWho,
3938            int requestCode) {
3939        synchronized(this) {
3940            final long origId = Binder.clearCallingIdentity();
3941            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3942            if (r != null) {
3943                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3944            }
3945            Binder.restoreCallingIdentity(origId);
3946        }
3947    }
3948
3949    @Override
3950    public boolean finishActivityAffinity(IBinder token) {
3951        synchronized(this) {
3952            final long origId = Binder.clearCallingIdentity();
3953            try {
3954                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3955
3956                ActivityRecord rootR = r.task.getRootActivity();
3957                // Do not allow task to finish in Lock Task mode.
3958                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3959                    if (rootR == r) {
3960                        mStackSupervisor.showLockTaskToast();
3961                        return false;
3962                    }
3963                }
3964                boolean res = false;
3965                if (r != null) {
3966                    res = r.task.stack.finishActivityAffinityLocked(r);
3967                }
3968                return res;
3969            } finally {
3970                Binder.restoreCallingIdentity(origId);
3971            }
3972        }
3973    }
3974
3975    @Override
3976    public void finishVoiceTask(IVoiceInteractionSession session) {
3977        synchronized(this) {
3978            final long origId = Binder.clearCallingIdentity();
3979            try {
3980                mStackSupervisor.finishVoiceTask(session);
3981            } finally {
3982                Binder.restoreCallingIdentity(origId);
3983            }
3984        }
3985
3986    }
3987
3988    @Override
3989    public boolean willActivityBeVisible(IBinder token) {
3990        synchronized(this) {
3991            ActivityStack stack = ActivityRecord.getStackLocked(token);
3992            if (stack != null) {
3993                return stack.willActivityBeVisibleLocked(token);
3994            }
3995            return false;
3996        }
3997    }
3998
3999    @Override
4000    public void overridePendingTransition(IBinder token, String packageName,
4001            int enterAnim, int exitAnim) {
4002        synchronized(this) {
4003            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4004            if (self == null) {
4005                return;
4006            }
4007
4008            final long origId = Binder.clearCallingIdentity();
4009
4010            if (self.state == ActivityState.RESUMED
4011                    || self.state == ActivityState.PAUSING) {
4012                mWindowManager.overridePendingAppTransition(packageName,
4013                        enterAnim, exitAnim, null);
4014            }
4015
4016            Binder.restoreCallingIdentity(origId);
4017        }
4018    }
4019
4020    /**
4021     * Main function for removing an existing process from the activity manager
4022     * as a result of that process going away.  Clears out all connections
4023     * to the process.
4024     */
4025    private final void handleAppDiedLocked(ProcessRecord app,
4026            boolean restarting, boolean allowRestart) {
4027        int pid = app.pid;
4028        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4029        if (!restarting) {
4030            removeLruProcessLocked(app);
4031            if (pid > 0) {
4032                ProcessList.remove(pid);
4033            }
4034        }
4035
4036        if (mProfileProc == app) {
4037            clearProfilerLocked();
4038        }
4039
4040        // Remove this application's activities from active lists.
4041        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4042
4043        app.activities.clear();
4044
4045        if (app.instrumentationClass != null) {
4046            Slog.w(TAG, "Crash of app " + app.processName
4047                  + " running instrumentation " + app.instrumentationClass);
4048            Bundle info = new Bundle();
4049            info.putString("shortMsg", "Process crashed.");
4050            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4051        }
4052
4053        if (!restarting) {
4054            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4055                // If there was nothing to resume, and we are not already
4056                // restarting this process, but there is a visible activity that
4057                // is hosted by the process...  then make sure all visible
4058                // activities are running, taking care of restarting this
4059                // process.
4060                if (hasVisibleActivities) {
4061                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4062                }
4063            }
4064        }
4065    }
4066
4067    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4068        IBinder threadBinder = thread.asBinder();
4069        // Find the application record.
4070        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4071            ProcessRecord rec = mLruProcesses.get(i);
4072            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4073                return i;
4074            }
4075        }
4076        return -1;
4077    }
4078
4079    final ProcessRecord getRecordForAppLocked(
4080            IApplicationThread thread) {
4081        if (thread == null) {
4082            return null;
4083        }
4084
4085        int appIndex = getLRURecordIndexForAppLocked(thread);
4086        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4087    }
4088
4089    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4090        // If there are no longer any background processes running,
4091        // and the app that died was not running instrumentation,
4092        // then tell everyone we are now low on memory.
4093        boolean haveBg = false;
4094        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4095            ProcessRecord rec = mLruProcesses.get(i);
4096            if (rec.thread != null
4097                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4098                haveBg = true;
4099                break;
4100            }
4101        }
4102
4103        if (!haveBg) {
4104            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4105            if (doReport) {
4106                long now = SystemClock.uptimeMillis();
4107                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4108                    doReport = false;
4109                } else {
4110                    mLastMemUsageReportTime = now;
4111                }
4112            }
4113            final ArrayList<ProcessMemInfo> memInfos
4114                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4115            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4116            long now = SystemClock.uptimeMillis();
4117            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4118                ProcessRecord rec = mLruProcesses.get(i);
4119                if (rec == dyingProc || rec.thread == null) {
4120                    continue;
4121                }
4122                if (doReport) {
4123                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4124                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4125                }
4126                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4127                    // The low memory report is overriding any current
4128                    // state for a GC request.  Make sure to do
4129                    // heavy/important/visible/foreground processes first.
4130                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4131                        rec.lastRequestedGc = 0;
4132                    } else {
4133                        rec.lastRequestedGc = rec.lastLowMemory;
4134                    }
4135                    rec.reportLowMemory = true;
4136                    rec.lastLowMemory = now;
4137                    mProcessesToGc.remove(rec);
4138                    addProcessToGcListLocked(rec);
4139                }
4140            }
4141            if (doReport) {
4142                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4143                mHandler.sendMessage(msg);
4144            }
4145            scheduleAppGcsLocked();
4146        }
4147    }
4148
4149    final void appDiedLocked(ProcessRecord app, int pid,
4150            IApplicationThread thread) {
4151
4152        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4153        synchronized (stats) {
4154            stats.noteProcessDiedLocked(app.info.uid, pid);
4155        }
4156
4157        Process.killProcessGroup(app.info.uid, pid);
4158
4159        // Clean up already done if the process has been re-started.
4160        if (app.pid == pid && app.thread != null &&
4161                app.thread.asBinder() == thread.asBinder()) {
4162            boolean doLowMem = app.instrumentationClass == null;
4163            boolean doOomAdj = doLowMem;
4164            if (!app.killedByAm) {
4165                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4166                        + ") has died.");
4167                mAllowLowerMemLevel = true;
4168            } else {
4169                // Note that we always want to do oom adj to update our state with the
4170                // new number of procs.
4171                mAllowLowerMemLevel = false;
4172                doLowMem = false;
4173            }
4174            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4175            if (DEBUG_CLEANUP) Slog.v(
4176                TAG, "Dying app: " + app + ", pid: " + pid
4177                + ", thread: " + thread.asBinder());
4178            handleAppDiedLocked(app, false, true);
4179
4180            if (doOomAdj) {
4181                updateOomAdjLocked();
4182            }
4183            if (doLowMem) {
4184                doLowMemReportIfNeededLocked(app);
4185            }
4186        } else if (app.pid != pid) {
4187            // A new process has already been started.
4188            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4189                    + ") has died and restarted (pid " + app.pid + ").");
4190            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4191        } else if (DEBUG_PROCESSES) {
4192            Slog.d(TAG, "Received spurious death notification for thread "
4193                    + thread.asBinder());
4194        }
4195    }
4196
4197    /**
4198     * If a stack trace dump file is configured, dump process stack traces.
4199     * @param clearTraces causes the dump file to be erased prior to the new
4200     *    traces being written, if true; when false, the new traces will be
4201     *    appended to any existing file content.
4202     * @param firstPids of dalvik VM processes to dump stack traces for first
4203     * @param lastPids of dalvik VM processes to dump stack traces for last
4204     * @param nativeProcs optional list of native process names to dump stack crawls
4205     * @return file containing stack traces, or null if no dump file is configured
4206     */
4207    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4208            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4209        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4210        if (tracesPath == null || tracesPath.length() == 0) {
4211            return null;
4212        }
4213
4214        File tracesFile = new File(tracesPath);
4215        try {
4216            File tracesDir = tracesFile.getParentFile();
4217            if (!tracesDir.exists()) {
4218                tracesFile.mkdirs();
4219                if (!SELinux.restorecon(tracesDir)) {
4220                    return null;
4221                }
4222            }
4223            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4224
4225            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4226            tracesFile.createNewFile();
4227            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4228        } catch (IOException e) {
4229            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4230            return null;
4231        }
4232
4233        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4234        return tracesFile;
4235    }
4236
4237    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4238            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4239        // Use a FileObserver to detect when traces finish writing.
4240        // The order of traces is considered important to maintain for legibility.
4241        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4242            @Override
4243            public synchronized void onEvent(int event, String path) { notify(); }
4244        };
4245
4246        try {
4247            observer.startWatching();
4248
4249            // First collect all of the stacks of the most important pids.
4250            if (firstPids != null) {
4251                try {
4252                    int num = firstPids.size();
4253                    for (int i = 0; i < num; i++) {
4254                        synchronized (observer) {
4255                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4256                            observer.wait(200);  // Wait for write-close, give up after 200msec
4257                        }
4258                    }
4259                } catch (InterruptedException e) {
4260                    Log.wtf(TAG, e);
4261                }
4262            }
4263
4264            // Next collect the stacks of the native pids
4265            if (nativeProcs != null) {
4266                int[] pids = Process.getPidsForCommands(nativeProcs);
4267                if (pids != null) {
4268                    for (int pid : pids) {
4269                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4270                    }
4271                }
4272            }
4273
4274            // Lastly, measure CPU usage.
4275            if (processCpuTracker != null) {
4276                processCpuTracker.init();
4277                System.gc();
4278                processCpuTracker.update();
4279                try {
4280                    synchronized (processCpuTracker) {
4281                        processCpuTracker.wait(500); // measure over 1/2 second.
4282                    }
4283                } catch (InterruptedException e) {
4284                }
4285                processCpuTracker.update();
4286
4287                // We'll take the stack crawls of just the top apps using CPU.
4288                final int N = processCpuTracker.countWorkingStats();
4289                int numProcs = 0;
4290                for (int i=0; i<N && numProcs<5; i++) {
4291                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4292                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4293                        numProcs++;
4294                        try {
4295                            synchronized (observer) {
4296                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4297                                observer.wait(200);  // Wait for write-close, give up after 200msec
4298                            }
4299                        } catch (InterruptedException e) {
4300                            Log.wtf(TAG, e);
4301                        }
4302
4303                    }
4304                }
4305            }
4306        } finally {
4307            observer.stopWatching();
4308        }
4309    }
4310
4311    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4312        if (true || IS_USER_BUILD) {
4313            return;
4314        }
4315        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4316        if (tracesPath == null || tracesPath.length() == 0) {
4317            return;
4318        }
4319
4320        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4321        StrictMode.allowThreadDiskWrites();
4322        try {
4323            final File tracesFile = new File(tracesPath);
4324            final File tracesDir = tracesFile.getParentFile();
4325            final File tracesTmp = new File(tracesDir, "__tmp__");
4326            try {
4327                if (!tracesDir.exists()) {
4328                    tracesFile.mkdirs();
4329                    if (!SELinux.restorecon(tracesDir.getPath())) {
4330                        return;
4331                    }
4332                }
4333                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4334
4335                if (tracesFile.exists()) {
4336                    tracesTmp.delete();
4337                    tracesFile.renameTo(tracesTmp);
4338                }
4339                StringBuilder sb = new StringBuilder();
4340                Time tobj = new Time();
4341                tobj.set(System.currentTimeMillis());
4342                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4343                sb.append(": ");
4344                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4345                sb.append(" since ");
4346                sb.append(msg);
4347                FileOutputStream fos = new FileOutputStream(tracesFile);
4348                fos.write(sb.toString().getBytes());
4349                if (app == null) {
4350                    fos.write("\n*** No application process!".getBytes());
4351                }
4352                fos.close();
4353                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4354            } catch (IOException e) {
4355                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4356                return;
4357            }
4358
4359            if (app != null) {
4360                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4361                firstPids.add(app.pid);
4362                dumpStackTraces(tracesPath, firstPids, null, null, null);
4363            }
4364
4365            File lastTracesFile = null;
4366            File curTracesFile = null;
4367            for (int i=9; i>=0; i--) {
4368                String name = String.format(Locale.US, "slow%02d.txt", i);
4369                curTracesFile = new File(tracesDir, name);
4370                if (curTracesFile.exists()) {
4371                    if (lastTracesFile != null) {
4372                        curTracesFile.renameTo(lastTracesFile);
4373                    } else {
4374                        curTracesFile.delete();
4375                    }
4376                }
4377                lastTracesFile = curTracesFile;
4378            }
4379            tracesFile.renameTo(curTracesFile);
4380            if (tracesTmp.exists()) {
4381                tracesTmp.renameTo(tracesFile);
4382            }
4383        } finally {
4384            StrictMode.setThreadPolicy(oldPolicy);
4385        }
4386    }
4387
4388    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4389            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4390        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4391        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4392
4393        if (mController != null) {
4394            try {
4395                // 0 == continue, -1 = kill process immediately
4396                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4397                if (res < 0 && app.pid != MY_PID) {
4398                    Process.killProcess(app.pid);
4399                    Process.killProcessGroup(app.info.uid, app.pid);
4400                }
4401            } catch (RemoteException e) {
4402                mController = null;
4403                Watchdog.getInstance().setActivityController(null);
4404            }
4405        }
4406
4407        long anrTime = SystemClock.uptimeMillis();
4408        if (MONITOR_CPU_USAGE) {
4409            updateCpuStatsNow();
4410        }
4411
4412        synchronized (this) {
4413            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4414            if (mShuttingDown) {
4415                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4416                return;
4417            } else if (app.notResponding) {
4418                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4419                return;
4420            } else if (app.crashing) {
4421                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4422                return;
4423            }
4424
4425            // In case we come through here for the same app before completing
4426            // this one, mark as anring now so we will bail out.
4427            app.notResponding = true;
4428
4429            // Log the ANR to the event log.
4430            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4431                    app.processName, app.info.flags, annotation);
4432
4433            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4434            firstPids.add(app.pid);
4435
4436            int parentPid = app.pid;
4437            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4438            if (parentPid != app.pid) firstPids.add(parentPid);
4439
4440            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4441
4442            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4443                ProcessRecord r = mLruProcesses.get(i);
4444                if (r != null && r.thread != null) {
4445                    int pid = r.pid;
4446                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4447                        if (r.persistent) {
4448                            firstPids.add(pid);
4449                        } else {
4450                            lastPids.put(pid, Boolean.TRUE);
4451                        }
4452                    }
4453                }
4454            }
4455        }
4456
4457        // Log the ANR to the main log.
4458        StringBuilder info = new StringBuilder();
4459        info.setLength(0);
4460        info.append("ANR in ").append(app.processName);
4461        if (activity != null && activity.shortComponentName != null) {
4462            info.append(" (").append(activity.shortComponentName).append(")");
4463        }
4464        info.append("\n");
4465        info.append("PID: ").append(app.pid).append("\n");
4466        if (annotation != null) {
4467            info.append("Reason: ").append(annotation).append("\n");
4468        }
4469        if (parent != null && parent != activity) {
4470            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4471        }
4472
4473        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4474
4475        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4476                NATIVE_STACKS_OF_INTEREST);
4477
4478        String cpuInfo = null;
4479        if (MONITOR_CPU_USAGE) {
4480            updateCpuStatsNow();
4481            synchronized (mProcessCpuThread) {
4482                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4483            }
4484            info.append(processCpuTracker.printCurrentLoad());
4485            info.append(cpuInfo);
4486        }
4487
4488        info.append(processCpuTracker.printCurrentState(anrTime));
4489
4490        Slog.e(TAG, info.toString());
4491        if (tracesFile == null) {
4492            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4493            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4494        }
4495
4496        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4497                cpuInfo, tracesFile, null);
4498
4499        if (mController != null) {
4500            try {
4501                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4502                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4503                if (res != 0) {
4504                    if (res < 0 && app.pid != MY_PID) {
4505                        Process.killProcess(app.pid);
4506                        Process.killProcessGroup(app.info.uid, app.pid);
4507                    } else {
4508                        synchronized (this) {
4509                            mServices.scheduleServiceTimeoutLocked(app);
4510                        }
4511                    }
4512                    return;
4513                }
4514            } catch (RemoteException e) {
4515                mController = null;
4516                Watchdog.getInstance().setActivityController(null);
4517            }
4518        }
4519
4520        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4521        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4522                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4523
4524        synchronized (this) {
4525            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4526                killUnneededProcessLocked(app, "background ANR");
4527                return;
4528            }
4529
4530            // Set the app's notResponding state, and look up the errorReportReceiver
4531            makeAppNotRespondingLocked(app,
4532                    activity != null ? activity.shortComponentName : null,
4533                    annotation != null ? "ANR " + annotation : "ANR",
4534                    info.toString());
4535
4536            // Bring up the infamous App Not Responding dialog
4537            Message msg = Message.obtain();
4538            HashMap<String, Object> map = new HashMap<String, Object>();
4539            msg.what = SHOW_NOT_RESPONDING_MSG;
4540            msg.obj = map;
4541            msg.arg1 = aboveSystem ? 1 : 0;
4542            map.put("app", app);
4543            if (activity != null) {
4544                map.put("activity", activity);
4545            }
4546
4547            mHandler.sendMessage(msg);
4548        }
4549    }
4550
4551    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4552        if (!mLaunchWarningShown) {
4553            mLaunchWarningShown = true;
4554            mHandler.post(new Runnable() {
4555                @Override
4556                public void run() {
4557                    synchronized (ActivityManagerService.this) {
4558                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4559                        d.show();
4560                        mHandler.postDelayed(new Runnable() {
4561                            @Override
4562                            public void run() {
4563                                synchronized (ActivityManagerService.this) {
4564                                    d.dismiss();
4565                                    mLaunchWarningShown = false;
4566                                }
4567                            }
4568                        }, 4000);
4569                    }
4570                }
4571            });
4572        }
4573    }
4574
4575    @Override
4576    public boolean clearApplicationUserData(final String packageName,
4577            final IPackageDataObserver observer, int userId) {
4578        enforceNotIsolatedCaller("clearApplicationUserData");
4579        int uid = Binder.getCallingUid();
4580        int pid = Binder.getCallingPid();
4581        userId = handleIncomingUser(pid, uid,
4582                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4583        long callingId = Binder.clearCallingIdentity();
4584        try {
4585            IPackageManager pm = AppGlobals.getPackageManager();
4586            int pkgUid = -1;
4587            synchronized(this) {
4588                try {
4589                    pkgUid = pm.getPackageUid(packageName, userId);
4590                } catch (RemoteException e) {
4591                }
4592                if (pkgUid == -1) {
4593                    Slog.w(TAG, "Invalid packageName: " + packageName);
4594                    if (observer != null) {
4595                        try {
4596                            observer.onRemoveCompleted(packageName, false);
4597                        } catch (RemoteException e) {
4598                            Slog.i(TAG, "Observer no longer exists.");
4599                        }
4600                    }
4601                    return false;
4602                }
4603                if (uid == pkgUid || checkComponentPermission(
4604                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4605                        pid, uid, -1, true)
4606                        == PackageManager.PERMISSION_GRANTED) {
4607                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4608                } else {
4609                    throw new SecurityException("PID " + pid + " does not have permission "
4610                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4611                                    + " of package " + packageName);
4612                }
4613            }
4614
4615            try {
4616                // Clear application user data
4617                pm.clearApplicationUserData(packageName, observer, userId);
4618
4619                // Remove all permissions granted from/to this package
4620                removeUriPermissionsForPackageLocked(packageName, userId, true);
4621
4622                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4623                        Uri.fromParts("package", packageName, null));
4624                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4625                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4626                        null, null, 0, null, null, null, false, false, userId);
4627            } catch (RemoteException e) {
4628            }
4629        } finally {
4630            Binder.restoreCallingIdentity(callingId);
4631        }
4632        return true;
4633    }
4634
4635    @Override
4636    public void killBackgroundProcesses(final String packageName, int userId) {
4637        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4638                != PackageManager.PERMISSION_GRANTED &&
4639                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4640                        != PackageManager.PERMISSION_GRANTED) {
4641            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4642                    + Binder.getCallingPid()
4643                    + ", uid=" + Binder.getCallingUid()
4644                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4645            Slog.w(TAG, msg);
4646            throw new SecurityException(msg);
4647        }
4648
4649        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4650                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4651        long callingId = Binder.clearCallingIdentity();
4652        try {
4653            IPackageManager pm = AppGlobals.getPackageManager();
4654            synchronized(this) {
4655                int appId = -1;
4656                try {
4657                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4658                } catch (RemoteException e) {
4659                }
4660                if (appId == -1) {
4661                    Slog.w(TAG, "Invalid packageName: " + packageName);
4662                    return;
4663                }
4664                killPackageProcessesLocked(packageName, appId, userId,
4665                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4666            }
4667        } finally {
4668            Binder.restoreCallingIdentity(callingId);
4669        }
4670    }
4671
4672    @Override
4673    public void killAllBackgroundProcesses() {
4674        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4675                != PackageManager.PERMISSION_GRANTED) {
4676            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4677                    + Binder.getCallingPid()
4678                    + ", uid=" + Binder.getCallingUid()
4679                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4680            Slog.w(TAG, msg);
4681            throw new SecurityException(msg);
4682        }
4683
4684        long callingId = Binder.clearCallingIdentity();
4685        try {
4686            synchronized(this) {
4687                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4688                final int NP = mProcessNames.getMap().size();
4689                for (int ip=0; ip<NP; ip++) {
4690                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4691                    final int NA = apps.size();
4692                    for (int ia=0; ia<NA; ia++) {
4693                        ProcessRecord app = apps.valueAt(ia);
4694                        if (app.persistent) {
4695                            // we don't kill persistent processes
4696                            continue;
4697                        }
4698                        if (app.removed) {
4699                            procs.add(app);
4700                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4701                            app.removed = true;
4702                            procs.add(app);
4703                        }
4704                    }
4705                }
4706
4707                int N = procs.size();
4708                for (int i=0; i<N; i++) {
4709                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4710                }
4711                mAllowLowerMemLevel = true;
4712                updateOomAdjLocked();
4713                doLowMemReportIfNeededLocked(null);
4714            }
4715        } finally {
4716            Binder.restoreCallingIdentity(callingId);
4717        }
4718    }
4719
4720    @Override
4721    public void forceStopPackage(final String packageName, int userId) {
4722        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4723                != PackageManager.PERMISSION_GRANTED) {
4724            String msg = "Permission Denial: forceStopPackage() from pid="
4725                    + Binder.getCallingPid()
4726                    + ", uid=" + Binder.getCallingUid()
4727                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4728            Slog.w(TAG, msg);
4729            throw new SecurityException(msg);
4730        }
4731        final int callingPid = Binder.getCallingPid();
4732        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4733                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4734        long callingId = Binder.clearCallingIdentity();
4735        try {
4736            IPackageManager pm = AppGlobals.getPackageManager();
4737            synchronized(this) {
4738                int[] users = userId == UserHandle.USER_ALL
4739                        ? getUsersLocked() : new int[] { userId };
4740                for (int user : users) {
4741                    int pkgUid = -1;
4742                    try {
4743                        pkgUid = pm.getPackageUid(packageName, user);
4744                    } catch (RemoteException e) {
4745                    }
4746                    if (pkgUid == -1) {
4747                        Slog.w(TAG, "Invalid packageName: " + packageName);
4748                        continue;
4749                    }
4750                    try {
4751                        pm.setPackageStoppedState(packageName, true, user);
4752                    } catch (RemoteException e) {
4753                    } catch (IllegalArgumentException e) {
4754                        Slog.w(TAG, "Failed trying to unstop package "
4755                                + packageName + ": " + e);
4756                    }
4757                    if (isUserRunningLocked(user, false)) {
4758                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4759                    }
4760                }
4761            }
4762        } finally {
4763            Binder.restoreCallingIdentity(callingId);
4764        }
4765    }
4766
4767    @Override
4768    public void addPackageDependency(String packageName) {
4769        synchronized (this) {
4770            int callingPid = Binder.getCallingPid();
4771            if (callingPid == Process.myPid()) {
4772                //  Yeah, um, no.
4773                Slog.w(TAG, "Can't addPackageDependency on system process");
4774                return;
4775            }
4776            ProcessRecord proc;
4777            synchronized (mPidsSelfLocked) {
4778                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4779            }
4780            if (proc != null) {
4781                if (proc.pkgDeps == null) {
4782                    proc.pkgDeps = new ArraySet<String>(1);
4783                }
4784                proc.pkgDeps.add(packageName);
4785            }
4786        }
4787    }
4788
4789    /*
4790     * The pkg name and app id have to be specified.
4791     */
4792    @Override
4793    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4794        if (pkg == null) {
4795            return;
4796        }
4797        // Make sure the uid is valid.
4798        if (appid < 0) {
4799            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4800            return;
4801        }
4802        int callerUid = Binder.getCallingUid();
4803        // Only the system server can kill an application
4804        if (callerUid == Process.SYSTEM_UID) {
4805            // Post an aysnc message to kill the application
4806            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4807            msg.arg1 = appid;
4808            msg.arg2 = 0;
4809            Bundle bundle = new Bundle();
4810            bundle.putString("pkg", pkg);
4811            bundle.putString("reason", reason);
4812            msg.obj = bundle;
4813            mHandler.sendMessage(msg);
4814        } else {
4815            throw new SecurityException(callerUid + " cannot kill pkg: " +
4816                    pkg);
4817        }
4818    }
4819
4820    @Override
4821    public void closeSystemDialogs(String reason) {
4822        enforceNotIsolatedCaller("closeSystemDialogs");
4823
4824        final int pid = Binder.getCallingPid();
4825        final int uid = Binder.getCallingUid();
4826        final long origId = Binder.clearCallingIdentity();
4827        try {
4828            synchronized (this) {
4829                // Only allow this from foreground processes, so that background
4830                // applications can't abuse it to prevent system UI from being shown.
4831                if (uid >= Process.FIRST_APPLICATION_UID) {
4832                    ProcessRecord proc;
4833                    synchronized (mPidsSelfLocked) {
4834                        proc = mPidsSelfLocked.get(pid);
4835                    }
4836                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4837                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4838                                + " from background process " + proc);
4839                        return;
4840                    }
4841                }
4842                closeSystemDialogsLocked(reason);
4843            }
4844        } finally {
4845            Binder.restoreCallingIdentity(origId);
4846        }
4847    }
4848
4849    void closeSystemDialogsLocked(String reason) {
4850        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4851        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4852                | Intent.FLAG_RECEIVER_FOREGROUND);
4853        if (reason != null) {
4854            intent.putExtra("reason", reason);
4855        }
4856        mWindowManager.closeSystemDialogs(reason);
4857
4858        mStackSupervisor.closeSystemDialogsLocked();
4859
4860        broadcastIntentLocked(null, null, intent, null,
4861                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4862                Process.SYSTEM_UID, UserHandle.USER_ALL);
4863    }
4864
4865    @Override
4866    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4867        enforceNotIsolatedCaller("getProcessMemoryInfo");
4868        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[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            infos[i] = new Debug.MemoryInfo();
4879            Debug.getMemoryInfo(pids[i], infos[i]);
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(infos[i].getTotalPss(),
4885                                infos[i].getTotalUss(), false, proc.pkgList);
4886                    }
4887                }
4888            }
4889        }
4890        return infos;
4891    }
4892
4893    @Override
4894    public long[] getProcessPss(int[] pids) {
4895        enforceNotIsolatedCaller("getProcessPss");
4896        long[] pss = new long[pids.length];
4897        for (int i=pids.length-1; i>=0; i--) {
4898            ProcessRecord proc;
4899            int oomAdj;
4900            synchronized (this) {
4901                synchronized (mPidsSelfLocked) {
4902                    proc = mPidsSelfLocked.get(pids[i]);
4903                    oomAdj = proc != null ? proc.setAdj : 0;
4904                }
4905            }
4906            long[] tmpUss = new long[1];
4907            pss[i] = Debug.getPss(pids[i], tmpUss);
4908            if (proc != null) {
4909                synchronized (this) {
4910                    if (proc.thread != null && proc.setAdj == oomAdj) {
4911                        // Record this for posterity if the process has been stable.
4912                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4913                    }
4914                }
4915            }
4916        }
4917        return pss;
4918    }
4919
4920    @Override
4921    public void killApplicationProcess(String processName, int uid) {
4922        if (processName == null) {
4923            return;
4924        }
4925
4926        int callerUid = Binder.getCallingUid();
4927        // Only the system server can kill an application
4928        if (callerUid == Process.SYSTEM_UID) {
4929            synchronized (this) {
4930                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4931                if (app != null && app.thread != null) {
4932                    try {
4933                        app.thread.scheduleSuicide();
4934                    } catch (RemoteException e) {
4935                        // If the other end already died, then our work here is done.
4936                    }
4937                } else {
4938                    Slog.w(TAG, "Process/uid not found attempting kill of "
4939                            + processName + " / " + uid);
4940                }
4941            }
4942        } else {
4943            throw new SecurityException(callerUid + " cannot kill app process: " +
4944                    processName);
4945        }
4946    }
4947
4948    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4949        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4950                false, true, false, false, UserHandle.getUserId(uid), reason);
4951        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4952                Uri.fromParts("package", packageName, null));
4953        if (!mProcessesReady) {
4954            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4955                    | Intent.FLAG_RECEIVER_FOREGROUND);
4956        }
4957        intent.putExtra(Intent.EXTRA_UID, uid);
4958        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4959        broadcastIntentLocked(null, null, intent,
4960                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4961                false, false,
4962                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4963    }
4964
4965    private void forceStopUserLocked(int userId, String reason) {
4966        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4967        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4968        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4969                | Intent.FLAG_RECEIVER_FOREGROUND);
4970        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4971        broadcastIntentLocked(null, null, intent,
4972                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4973                false, false,
4974                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4975    }
4976
4977    private final boolean killPackageProcessesLocked(String packageName, int appId,
4978            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4979            boolean doit, boolean evenPersistent, String reason) {
4980        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4981
4982        // Remove all processes this package may have touched: all with the
4983        // same UID (except for the system or root user), and all whose name
4984        // matches the package name.
4985        final int NP = mProcessNames.getMap().size();
4986        for (int ip=0; ip<NP; ip++) {
4987            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4988            final int NA = apps.size();
4989            for (int ia=0; ia<NA; ia++) {
4990                ProcessRecord app = apps.valueAt(ia);
4991                if (app.persistent && !evenPersistent) {
4992                    // we don't kill persistent processes
4993                    continue;
4994                }
4995                if (app.removed) {
4996                    if (doit) {
4997                        procs.add(app);
4998                    }
4999                    continue;
5000                }
5001
5002                // Skip process if it doesn't meet our oom adj requirement.
5003                if (app.setAdj < minOomAdj) {
5004                    continue;
5005                }
5006
5007                // If no package is specified, we call all processes under the
5008                // give user id.
5009                if (packageName == null) {
5010                    if (app.userId != userId) {
5011                        continue;
5012                    }
5013                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5014                        continue;
5015                    }
5016                // Package has been specified, we want to hit all processes
5017                // that match it.  We need to qualify this by the processes
5018                // that are running under the specified app and user ID.
5019                } else {
5020                    final boolean isDep = app.pkgDeps != null
5021                            && app.pkgDeps.contains(packageName);
5022                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5023                        continue;
5024                    }
5025                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5026                        continue;
5027                    }
5028                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5029                        continue;
5030                    }
5031                }
5032
5033                // Process has passed all conditions, kill it!
5034                if (!doit) {
5035                    return true;
5036                }
5037                app.removed = true;
5038                procs.add(app);
5039            }
5040        }
5041
5042        int N = procs.size();
5043        for (int i=0; i<N; i++) {
5044            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5045        }
5046        updateOomAdjLocked();
5047        return N > 0;
5048    }
5049
5050    private final boolean forceStopPackageLocked(String name, int appId,
5051            boolean callerWillRestart, boolean purgeCache, boolean doit,
5052            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5053        int i;
5054        int N;
5055
5056        if (userId == UserHandle.USER_ALL && name == null) {
5057            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5058        }
5059
5060        if (appId < 0 && name != null) {
5061            try {
5062                appId = UserHandle.getAppId(
5063                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5064            } catch (RemoteException e) {
5065            }
5066        }
5067
5068        if (doit) {
5069            if (name != null) {
5070                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5071                        + " user=" + userId + ": " + reason);
5072            } else {
5073                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5074            }
5075
5076            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5077            for (int ip=pmap.size()-1; ip>=0; ip--) {
5078                SparseArray<Long> ba = pmap.valueAt(ip);
5079                for (i=ba.size()-1; i>=0; i--) {
5080                    boolean remove = false;
5081                    final int entUid = ba.keyAt(i);
5082                    if (name != null) {
5083                        if (userId == UserHandle.USER_ALL) {
5084                            if (UserHandle.getAppId(entUid) == appId) {
5085                                remove = true;
5086                            }
5087                        } else {
5088                            if (entUid == UserHandle.getUid(userId, appId)) {
5089                                remove = true;
5090                            }
5091                        }
5092                    } else if (UserHandle.getUserId(entUid) == userId) {
5093                        remove = true;
5094                    }
5095                    if (remove) {
5096                        ba.removeAt(i);
5097                    }
5098                }
5099                if (ba.size() == 0) {
5100                    pmap.removeAt(ip);
5101                }
5102            }
5103        }
5104
5105        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5106                -100, callerWillRestart, true, doit, evenPersistent,
5107                name == null ? ("stop user " + userId) : ("stop " + name));
5108
5109        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5110            if (!doit) {
5111                return true;
5112            }
5113            didSomething = true;
5114        }
5115
5116        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5117            if (!doit) {
5118                return true;
5119            }
5120            didSomething = true;
5121        }
5122
5123        if (name == null) {
5124            // Remove all sticky broadcasts from this user.
5125            mStickyBroadcasts.remove(userId);
5126        }
5127
5128        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5129        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5130                userId, providers)) {
5131            if (!doit) {
5132                return true;
5133            }
5134            didSomething = true;
5135        }
5136        N = providers.size();
5137        for (i=0; i<N; i++) {
5138            removeDyingProviderLocked(null, providers.get(i), true);
5139        }
5140
5141        // Remove transient permissions granted from/to this package/user
5142        removeUriPermissionsForPackageLocked(name, userId, false);
5143
5144        if (name == null || uninstalling) {
5145            // Remove pending intents.  For now we only do this when force
5146            // stopping users, because we have some problems when doing this
5147            // for packages -- app widgets are not currently cleaned up for
5148            // such packages, so they can be left with bad pending intents.
5149            if (mIntentSenderRecords.size() > 0) {
5150                Iterator<WeakReference<PendingIntentRecord>> it
5151                        = mIntentSenderRecords.values().iterator();
5152                while (it.hasNext()) {
5153                    WeakReference<PendingIntentRecord> wpir = it.next();
5154                    if (wpir == null) {
5155                        it.remove();
5156                        continue;
5157                    }
5158                    PendingIntentRecord pir = wpir.get();
5159                    if (pir == null) {
5160                        it.remove();
5161                        continue;
5162                    }
5163                    if (name == null) {
5164                        // Stopping user, remove all objects for the user.
5165                        if (pir.key.userId != userId) {
5166                            // Not the same user, skip it.
5167                            continue;
5168                        }
5169                    } else {
5170                        if (UserHandle.getAppId(pir.uid) != appId) {
5171                            // Different app id, skip it.
5172                            continue;
5173                        }
5174                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5175                            // Different user, skip it.
5176                            continue;
5177                        }
5178                        if (!pir.key.packageName.equals(name)) {
5179                            // Different package, skip it.
5180                            continue;
5181                        }
5182                    }
5183                    if (!doit) {
5184                        return true;
5185                    }
5186                    didSomething = true;
5187                    it.remove();
5188                    pir.canceled = true;
5189                    if (pir.key.activity != null) {
5190                        pir.key.activity.pendingResults.remove(pir.ref);
5191                    }
5192                }
5193            }
5194        }
5195
5196        if (doit) {
5197            if (purgeCache && name != null) {
5198                AttributeCache ac = AttributeCache.instance();
5199                if (ac != null) {
5200                    ac.removePackage(name);
5201                }
5202            }
5203            if (mBooted) {
5204                mStackSupervisor.resumeTopActivitiesLocked();
5205                mStackSupervisor.scheduleIdleLocked();
5206            }
5207        }
5208
5209        return didSomething;
5210    }
5211
5212    private final boolean removeProcessLocked(ProcessRecord app,
5213            boolean callerWillRestart, boolean allowRestart, String reason) {
5214        final String name = app.processName;
5215        final int uid = app.uid;
5216        if (DEBUG_PROCESSES) Slog.d(
5217            TAG, "Force removing proc " + app.toShortString() + " (" + name
5218            + "/" + uid + ")");
5219
5220        mProcessNames.remove(name, uid);
5221        mIsolatedProcesses.remove(app.uid);
5222        if (mHeavyWeightProcess == app) {
5223            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5224                    mHeavyWeightProcess.userId, 0));
5225            mHeavyWeightProcess = null;
5226        }
5227        boolean needRestart = false;
5228        if (app.pid > 0 && app.pid != MY_PID) {
5229            int pid = app.pid;
5230            synchronized (mPidsSelfLocked) {
5231                mPidsSelfLocked.remove(pid);
5232                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5233            }
5234            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5235            if (app.isolated) {
5236                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5237            }
5238            killUnneededProcessLocked(app, reason);
5239            Process.killProcessGroup(app.info.uid, app.pid);
5240            handleAppDiedLocked(app, true, allowRestart);
5241            removeLruProcessLocked(app);
5242
5243            if (app.persistent && !app.isolated) {
5244                if (!callerWillRestart) {
5245                    addAppLocked(app.info, false, null /* ABI override */);
5246                } else {
5247                    needRestart = true;
5248                }
5249            }
5250        } else {
5251            mRemovedProcesses.add(app);
5252        }
5253
5254        return needRestart;
5255    }
5256
5257    private final void processStartTimedOutLocked(ProcessRecord app) {
5258        final int pid = app.pid;
5259        boolean gone = false;
5260        synchronized (mPidsSelfLocked) {
5261            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5262            if (knownApp != null && knownApp.thread == null) {
5263                mPidsSelfLocked.remove(pid);
5264                gone = true;
5265            }
5266        }
5267
5268        if (gone) {
5269            Slog.w(TAG, "Process " + app + " failed to attach");
5270            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5271                    pid, app.uid, app.processName);
5272            mProcessNames.remove(app.processName, app.uid);
5273            mIsolatedProcesses.remove(app.uid);
5274            if (mHeavyWeightProcess == app) {
5275                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5276                        mHeavyWeightProcess.userId, 0));
5277                mHeavyWeightProcess = null;
5278            }
5279            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5280            if (app.isolated) {
5281                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5282            }
5283            // Take care of any launching providers waiting for this process.
5284            checkAppInLaunchingProvidersLocked(app, true);
5285            // Take care of any services that are waiting for the process.
5286            mServices.processStartTimedOutLocked(app);
5287            killUnneededProcessLocked(app, "start timeout");
5288            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5289                Slog.w(TAG, "Unattached app died before backup, skipping");
5290                try {
5291                    IBackupManager bm = IBackupManager.Stub.asInterface(
5292                            ServiceManager.getService(Context.BACKUP_SERVICE));
5293                    bm.agentDisconnected(app.info.packageName);
5294                } catch (RemoteException e) {
5295                    // Can't happen; the backup manager is local
5296                }
5297            }
5298            if (isPendingBroadcastProcessLocked(pid)) {
5299                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5300                skipPendingBroadcastLocked(pid);
5301            }
5302        } else {
5303            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5304        }
5305    }
5306
5307    private final boolean attachApplicationLocked(IApplicationThread thread,
5308            int pid) {
5309
5310        // Find the application record that is being attached...  either via
5311        // the pid if we are running in multiple processes, or just pull the
5312        // next app record if we are emulating process with anonymous threads.
5313        ProcessRecord app;
5314        if (pid != MY_PID && pid >= 0) {
5315            synchronized (mPidsSelfLocked) {
5316                app = mPidsSelfLocked.get(pid);
5317            }
5318        } else {
5319            app = null;
5320        }
5321
5322        if (app == null) {
5323            Slog.w(TAG, "No pending application record for pid " + pid
5324                    + " (IApplicationThread " + thread + "); dropping process");
5325            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5326            if (pid > 0 && pid != MY_PID) {
5327                Process.killProcessQuiet(pid);
5328                //TODO: Process.killProcessGroup(app.info.uid, pid);
5329            } else {
5330                try {
5331                    thread.scheduleExit();
5332                } catch (Exception e) {
5333                    // Ignore exceptions.
5334                }
5335            }
5336            return false;
5337        }
5338
5339        // If this application record is still attached to a previous
5340        // process, clean it up now.
5341        if (app.thread != null) {
5342            handleAppDiedLocked(app, true, true);
5343        }
5344
5345        // Tell the process all about itself.
5346
5347        if (localLOGV) Slog.v(
5348                TAG, "Binding process pid " + pid + " to record " + app);
5349
5350        final String processName = app.processName;
5351        try {
5352            AppDeathRecipient adr = new AppDeathRecipient(
5353                    app, pid, thread);
5354            thread.asBinder().linkToDeath(adr, 0);
5355            app.deathRecipient = adr;
5356        } catch (RemoteException e) {
5357            app.resetPackageList(mProcessStats);
5358            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5359            return false;
5360        }
5361
5362        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5363
5364        app.makeActive(thread, mProcessStats);
5365        app.curAdj = app.setAdj = -100;
5366        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5367        app.forcingToForeground = null;
5368        updateProcessForegroundLocked(app, false, false);
5369        app.hasShownUi = false;
5370        app.debugging = false;
5371        app.cached = false;
5372
5373        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5374
5375        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5376        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5377
5378        if (!normalMode) {
5379            Slog.i(TAG, "Launching preboot mode app: " + app);
5380        }
5381
5382        if (localLOGV) Slog.v(
5383            TAG, "New app record " + app
5384            + " thread=" + thread.asBinder() + " pid=" + pid);
5385        try {
5386            int testMode = IApplicationThread.DEBUG_OFF;
5387            if (mDebugApp != null && mDebugApp.equals(processName)) {
5388                testMode = mWaitForDebugger
5389                    ? IApplicationThread.DEBUG_WAIT
5390                    : IApplicationThread.DEBUG_ON;
5391                app.debugging = true;
5392                if (mDebugTransient) {
5393                    mDebugApp = mOrigDebugApp;
5394                    mWaitForDebugger = mOrigWaitForDebugger;
5395                }
5396            }
5397            String profileFile = app.instrumentationProfileFile;
5398            ParcelFileDescriptor profileFd = null;
5399            boolean profileAutoStop = false;
5400            if (mProfileApp != null && mProfileApp.equals(processName)) {
5401                mProfileProc = app;
5402                profileFile = mProfileFile;
5403                profileFd = mProfileFd;
5404                profileAutoStop = mAutoStopProfiler;
5405            }
5406            boolean enableOpenGlTrace = false;
5407            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5408                enableOpenGlTrace = true;
5409                mOpenGlTraceApp = null;
5410            }
5411
5412            // If the app is being launched for restore or full backup, set it up specially
5413            boolean isRestrictedBackupMode = false;
5414            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5415                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5416                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5417                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5418            }
5419
5420            ensurePackageDexOpt(app.instrumentationInfo != null
5421                    ? app.instrumentationInfo.packageName
5422                    : app.info.packageName);
5423            if (app.instrumentationClass != null) {
5424                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5425            }
5426            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5427                    + processName + " with config " + mConfiguration);
5428            ApplicationInfo appInfo = app.instrumentationInfo != null
5429                    ? app.instrumentationInfo : app.info;
5430            app.compat = compatibilityInfoForPackageLocked(appInfo);
5431            if (profileFd != null) {
5432                profileFd = profileFd.dup();
5433            }
5434            thread.bindApplication(processName, appInfo, providers,
5435                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5436                    app.instrumentationArguments, app.instrumentationWatcher,
5437                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5438                    isRestrictedBackupMode || !normalMode, app.persistent,
5439                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5440                    mCoreSettingsObserver.getCoreSettingsLocked());
5441            updateLruProcessLocked(app, false, null);
5442            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5443        } catch (Exception e) {
5444            // todo: Yikes!  What should we do?  For now we will try to
5445            // start another process, but that could easily get us in
5446            // an infinite loop of restarting processes...
5447            Slog.w(TAG, "Exception thrown during bind!", e);
5448
5449            app.resetPackageList(mProcessStats);
5450            app.unlinkDeathRecipient();
5451            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5452            return false;
5453        }
5454
5455        // Remove this record from the list of starting applications.
5456        mPersistentStartingProcesses.remove(app);
5457        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5458                "Attach application locked removing on hold: " + app);
5459        mProcessesOnHold.remove(app);
5460
5461        boolean badApp = false;
5462        boolean didSomething = false;
5463
5464        // See if the top visible activity is waiting to run in this process...
5465        if (normalMode) {
5466            try {
5467                if (mStackSupervisor.attachApplicationLocked(app)) {
5468                    didSomething = true;
5469                }
5470            } catch (Exception e) {
5471                badApp = true;
5472            }
5473        }
5474
5475        // Find any services that should be running in this process...
5476        if (!badApp) {
5477            try {
5478                didSomething |= mServices.attachApplicationLocked(app, processName);
5479            } catch (Exception e) {
5480                badApp = true;
5481            }
5482        }
5483
5484        // Check if a next-broadcast receiver is in this process...
5485        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5486            try {
5487                didSomething |= sendPendingBroadcastsLocked(app);
5488            } catch (Exception e) {
5489                // If the app died trying to launch the receiver we declare it 'bad'
5490                badApp = true;
5491            }
5492        }
5493
5494        // Check whether the next backup agent is in this process...
5495        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5496            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5497            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5498            try {
5499                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5500                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5501                        mBackupTarget.backupMode);
5502            } catch (Exception e) {
5503                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5504                e.printStackTrace();
5505            }
5506        }
5507
5508        if (badApp) {
5509            // todo: Also need to kill application to deal with all
5510            // kinds of exceptions.
5511            handleAppDiedLocked(app, false, true);
5512            return false;
5513        }
5514
5515        if (!didSomething) {
5516            updateOomAdjLocked();
5517        }
5518
5519        return true;
5520    }
5521
5522    @Override
5523    public final void attachApplication(IApplicationThread thread) {
5524        synchronized (this) {
5525            int callingPid = Binder.getCallingPid();
5526            final long origId = Binder.clearCallingIdentity();
5527            attachApplicationLocked(thread, callingPid);
5528            Binder.restoreCallingIdentity(origId);
5529        }
5530    }
5531
5532    @Override
5533    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5534        final long origId = Binder.clearCallingIdentity();
5535        synchronized (this) {
5536            ActivityStack stack = ActivityRecord.getStackLocked(token);
5537            if (stack != null) {
5538                ActivityRecord r =
5539                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5540                if (stopProfiling) {
5541                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5542                        try {
5543                            mProfileFd.close();
5544                        } catch (IOException e) {
5545                        }
5546                        clearProfilerLocked();
5547                    }
5548                }
5549            }
5550        }
5551        Binder.restoreCallingIdentity(origId);
5552    }
5553
5554    void postEnableScreenAfterBootLocked() {
5555        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
5556    }
5557
5558    void enableScreenAfterBoot() {
5559        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5560                SystemClock.uptimeMillis());
5561        mWindowManager.enableScreenAfterBoot();
5562
5563        synchronized (this) {
5564            updateEventDispatchingLocked();
5565        }
5566    }
5567
5568    @Override
5569    public void showBootMessage(final CharSequence msg, final boolean always) {
5570        enforceNotIsolatedCaller("showBootMessage");
5571        mWindowManager.showBootMessage(msg, always);
5572    }
5573
5574    @Override
5575    public void dismissKeyguardOnNextActivity() {
5576        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5577        final long token = Binder.clearCallingIdentity();
5578        try {
5579            synchronized (this) {
5580                if (DEBUG_LOCKSCREEN) logLockScreen("");
5581                if (mLockScreenShown) {
5582                    mLockScreenShown = false;
5583                    comeOutOfSleepIfNeededLocked();
5584                }
5585                mStackSupervisor.setDismissKeyguard(true);
5586            }
5587        } finally {
5588            Binder.restoreCallingIdentity(token);
5589        }
5590    }
5591
5592    final void finishBooting() {
5593        // Register receivers to handle package update events
5594        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5595
5596        synchronized (this) {
5597            // Ensure that any processes we had put on hold are now started
5598            // up.
5599            final int NP = mProcessesOnHold.size();
5600            if (NP > 0) {
5601                ArrayList<ProcessRecord> procs =
5602                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5603                for (int ip=0; ip<NP; ip++) {
5604                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5605                            + procs.get(ip));
5606                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5607                }
5608            }
5609
5610            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5611                // Start looking for apps that are abusing wake locks.
5612                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5613                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5614                // Tell anyone interested that we are done booting!
5615                SystemProperties.set("sys.boot_completed", "1");
5616                SystemProperties.set("dev.bootcomplete", "1");
5617                for (int i=0; i<mStartedUsers.size(); i++) {
5618                    UserStartedState uss = mStartedUsers.valueAt(i);
5619                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5620                        uss.mState = UserStartedState.STATE_RUNNING;
5621                        final int userId = mStartedUsers.keyAt(i);
5622                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5623                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5624                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5625                        broadcastIntentLocked(null, null, intent, null,
5626                                new IIntentReceiver.Stub() {
5627                                    @Override
5628                                    public void performReceive(Intent intent, int resultCode,
5629                                            String data, Bundle extras, boolean ordered,
5630                                            boolean sticky, int sendingUser) {
5631                                        synchronized (ActivityManagerService.this) {
5632                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5633                                                    true, false);
5634                                        }
5635                                    }
5636                                },
5637                                0, null, null,
5638                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5639                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5640                                userId);
5641                    }
5642                }
5643                scheduleStartProfilesLocked();
5644            }
5645        }
5646    }
5647
5648    final void ensureBootCompleted() {
5649        boolean booting;
5650        boolean enableScreen;
5651        synchronized (this) {
5652            booting = mBooting;
5653            mBooting = false;
5654            enableScreen = !mBooted;
5655            mBooted = true;
5656        }
5657
5658        if (booting) {
5659            finishBooting();
5660        }
5661
5662        if (enableScreen) {
5663            enableScreenAfterBoot();
5664        }
5665    }
5666
5667    @Override
5668    public final void activityResumed(IBinder token) {
5669        final long origId = Binder.clearCallingIdentity();
5670        synchronized(this) {
5671            ActivityStack stack = ActivityRecord.getStackLocked(token);
5672            if (stack != null) {
5673                ActivityRecord.activityResumedLocked(token);
5674            }
5675        }
5676        Binder.restoreCallingIdentity(origId);
5677    }
5678
5679    @Override
5680    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5681        final long origId = Binder.clearCallingIdentity();
5682        synchronized(this) {
5683            ActivityStack stack = ActivityRecord.getStackLocked(token);
5684            if (stack != null) {
5685                stack.activityPausedLocked(token, false, persistentState);
5686            }
5687        }
5688        Binder.restoreCallingIdentity(origId);
5689    }
5690
5691    @Override
5692    public final void activityStopped(IBinder token, Bundle icicle,
5693            PersistableBundle persistentState, CharSequence description) {
5694        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5695
5696        // Refuse possible leaked file descriptors
5697        if (icicle != null && icicle.hasFileDescriptors()) {
5698            throw new IllegalArgumentException("File descriptors passed in Bundle");
5699        }
5700
5701        final long origId = Binder.clearCallingIdentity();
5702
5703        synchronized (this) {
5704            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5705            if (r != null) {
5706                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5707            }
5708        }
5709
5710        trimApplications();
5711
5712        Binder.restoreCallingIdentity(origId);
5713    }
5714
5715    @Override
5716    public final void activityDestroyed(IBinder token) {
5717        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5718        synchronized (this) {
5719            ActivityStack stack = ActivityRecord.getStackLocked(token);
5720            if (stack != null) {
5721                stack.activityDestroyedLocked(token);
5722            }
5723        }
5724    }
5725
5726    @Override
5727    public final void mediaResourcesReleased(IBinder token) {
5728        final long origId = Binder.clearCallingIdentity();
5729        try {
5730            synchronized (this) {
5731                ActivityStack stack = ActivityRecord.getStackLocked(token);
5732                if (stack != null) {
5733                    stack.mediaResourcesReleased(token);
5734                }
5735            }
5736        } finally {
5737            Binder.restoreCallingIdentity(origId);
5738        }
5739    }
5740
5741    @Override
5742    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5743        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5744    }
5745
5746    @Override
5747    public final void notifyEnterAnimationComplete(IBinder token) {
5748        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5749    }
5750
5751    @Override
5752    public String getCallingPackage(IBinder token) {
5753        synchronized (this) {
5754            ActivityRecord r = getCallingRecordLocked(token);
5755            return r != null ? r.info.packageName : null;
5756        }
5757    }
5758
5759    @Override
5760    public ComponentName getCallingActivity(IBinder token) {
5761        synchronized (this) {
5762            ActivityRecord r = getCallingRecordLocked(token);
5763            return r != null ? r.intent.getComponent() : null;
5764        }
5765    }
5766
5767    private ActivityRecord getCallingRecordLocked(IBinder token) {
5768        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5769        if (r == null) {
5770            return null;
5771        }
5772        return r.resultTo;
5773    }
5774
5775    @Override
5776    public ComponentName getActivityClassForToken(IBinder token) {
5777        synchronized(this) {
5778            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5779            if (r == null) {
5780                return null;
5781            }
5782            return r.intent.getComponent();
5783        }
5784    }
5785
5786    @Override
5787    public String getPackageForToken(IBinder token) {
5788        synchronized(this) {
5789            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5790            if (r == null) {
5791                return null;
5792            }
5793            return r.packageName;
5794        }
5795    }
5796
5797    @Override
5798    public IIntentSender getIntentSender(int type,
5799            String packageName, IBinder token, String resultWho,
5800            int requestCode, Intent[] intents, String[] resolvedTypes,
5801            int flags, Bundle options, int userId) {
5802        enforceNotIsolatedCaller("getIntentSender");
5803        // Refuse possible leaked file descriptors
5804        if (intents != null) {
5805            if (intents.length < 1) {
5806                throw new IllegalArgumentException("Intents array length must be >= 1");
5807            }
5808            for (int i=0; i<intents.length; i++) {
5809                Intent intent = intents[i];
5810                if (intent != null) {
5811                    if (intent.hasFileDescriptors()) {
5812                        throw new IllegalArgumentException("File descriptors passed in Intent");
5813                    }
5814                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5815                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5816                        throw new IllegalArgumentException(
5817                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5818                    }
5819                    intents[i] = new Intent(intent);
5820                }
5821            }
5822            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5823                throw new IllegalArgumentException(
5824                        "Intent array length does not match resolvedTypes length");
5825            }
5826        }
5827        if (options != null) {
5828            if (options.hasFileDescriptors()) {
5829                throw new IllegalArgumentException("File descriptors passed in options");
5830            }
5831        }
5832
5833        synchronized(this) {
5834            int callingUid = Binder.getCallingUid();
5835            int origUserId = userId;
5836            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5837                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5838                    ALLOW_NON_FULL, "getIntentSender", null);
5839            if (origUserId == UserHandle.USER_CURRENT) {
5840                // We don't want to evaluate this until the pending intent is
5841                // actually executed.  However, we do want to always do the
5842                // security checking for it above.
5843                userId = UserHandle.USER_CURRENT;
5844            }
5845            try {
5846                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5847                    int uid = AppGlobals.getPackageManager()
5848                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5849                    if (!UserHandle.isSameApp(callingUid, uid)) {
5850                        String msg = "Permission Denial: getIntentSender() from pid="
5851                            + Binder.getCallingPid()
5852                            + ", uid=" + Binder.getCallingUid()
5853                            + ", (need uid=" + uid + ")"
5854                            + " is not allowed to send as package " + packageName;
5855                        Slog.w(TAG, msg);
5856                        throw new SecurityException(msg);
5857                    }
5858                }
5859
5860                return getIntentSenderLocked(type, packageName, callingUid, userId,
5861                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5862
5863            } catch (RemoteException e) {
5864                throw new SecurityException(e);
5865            }
5866        }
5867    }
5868
5869    IIntentSender getIntentSenderLocked(int type, String packageName,
5870            int callingUid, int userId, IBinder token, String resultWho,
5871            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5872            Bundle options) {
5873        if (DEBUG_MU)
5874            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5875        ActivityRecord activity = null;
5876        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5877            activity = ActivityRecord.isInStackLocked(token);
5878            if (activity == null) {
5879                return null;
5880            }
5881            if (activity.finishing) {
5882                return null;
5883            }
5884        }
5885
5886        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5887        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5888        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5889        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5890                |PendingIntent.FLAG_UPDATE_CURRENT);
5891
5892        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5893                type, packageName, activity, resultWho,
5894                requestCode, intents, resolvedTypes, flags, options, userId);
5895        WeakReference<PendingIntentRecord> ref;
5896        ref = mIntentSenderRecords.get(key);
5897        PendingIntentRecord rec = ref != null ? ref.get() : null;
5898        if (rec != null) {
5899            if (!cancelCurrent) {
5900                if (updateCurrent) {
5901                    if (rec.key.requestIntent != null) {
5902                        rec.key.requestIntent.replaceExtras(intents != null ?
5903                                intents[intents.length - 1] : null);
5904                    }
5905                    if (intents != null) {
5906                        intents[intents.length-1] = rec.key.requestIntent;
5907                        rec.key.allIntents = intents;
5908                        rec.key.allResolvedTypes = resolvedTypes;
5909                    } else {
5910                        rec.key.allIntents = null;
5911                        rec.key.allResolvedTypes = null;
5912                    }
5913                }
5914                return rec;
5915            }
5916            rec.canceled = true;
5917            mIntentSenderRecords.remove(key);
5918        }
5919        if (noCreate) {
5920            return rec;
5921        }
5922        rec = new PendingIntentRecord(this, key, callingUid);
5923        mIntentSenderRecords.put(key, rec.ref);
5924        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5925            if (activity.pendingResults == null) {
5926                activity.pendingResults
5927                        = new HashSet<WeakReference<PendingIntentRecord>>();
5928            }
5929            activity.pendingResults.add(rec.ref);
5930        }
5931        return rec;
5932    }
5933
5934    @Override
5935    public void cancelIntentSender(IIntentSender sender) {
5936        if (!(sender instanceof PendingIntentRecord)) {
5937            return;
5938        }
5939        synchronized(this) {
5940            PendingIntentRecord rec = (PendingIntentRecord)sender;
5941            try {
5942                int uid = AppGlobals.getPackageManager()
5943                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5944                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5945                    String msg = "Permission Denial: cancelIntentSender() from pid="
5946                        + Binder.getCallingPid()
5947                        + ", uid=" + Binder.getCallingUid()
5948                        + " is not allowed to cancel packges "
5949                        + rec.key.packageName;
5950                    Slog.w(TAG, msg);
5951                    throw new SecurityException(msg);
5952                }
5953            } catch (RemoteException e) {
5954                throw new SecurityException(e);
5955            }
5956            cancelIntentSenderLocked(rec, true);
5957        }
5958    }
5959
5960    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5961        rec.canceled = true;
5962        mIntentSenderRecords.remove(rec.key);
5963        if (cleanActivity && rec.key.activity != null) {
5964            rec.key.activity.pendingResults.remove(rec.ref);
5965        }
5966    }
5967
5968    @Override
5969    public String getPackageForIntentSender(IIntentSender pendingResult) {
5970        if (!(pendingResult instanceof PendingIntentRecord)) {
5971            return null;
5972        }
5973        try {
5974            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5975            return res.key.packageName;
5976        } catch (ClassCastException e) {
5977        }
5978        return null;
5979    }
5980
5981    @Override
5982    public int getUidForIntentSender(IIntentSender sender) {
5983        if (sender instanceof PendingIntentRecord) {
5984            try {
5985                PendingIntentRecord res = (PendingIntentRecord)sender;
5986                return res.uid;
5987            } catch (ClassCastException e) {
5988            }
5989        }
5990        return -1;
5991    }
5992
5993    @Override
5994    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5995        if (!(pendingResult instanceof PendingIntentRecord)) {
5996            return false;
5997        }
5998        try {
5999            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6000            if (res.key.allIntents == null) {
6001                return false;
6002            }
6003            for (int i=0; i<res.key.allIntents.length; i++) {
6004                Intent intent = res.key.allIntents[i];
6005                if (intent.getPackage() != null && intent.getComponent() != null) {
6006                    return false;
6007                }
6008            }
6009            return true;
6010        } catch (ClassCastException e) {
6011        }
6012        return false;
6013    }
6014
6015    @Override
6016    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6017        if (!(pendingResult instanceof PendingIntentRecord)) {
6018            return false;
6019        }
6020        try {
6021            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6022            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6023                return true;
6024            }
6025            return false;
6026        } catch (ClassCastException e) {
6027        }
6028        return false;
6029    }
6030
6031    @Override
6032    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6033        if (!(pendingResult instanceof PendingIntentRecord)) {
6034            return null;
6035        }
6036        try {
6037            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6038            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6039        } catch (ClassCastException e) {
6040        }
6041        return null;
6042    }
6043
6044    @Override
6045    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6046        if (!(pendingResult instanceof PendingIntentRecord)) {
6047            return null;
6048        }
6049        try {
6050            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6051            Intent intent = res.key.requestIntent;
6052            if (intent != null) {
6053                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6054                        || res.lastTagPrefix.equals(prefix))) {
6055                    return res.lastTag;
6056                }
6057                res.lastTagPrefix = prefix;
6058                StringBuilder sb = new StringBuilder(128);
6059                if (prefix != null) {
6060                    sb.append(prefix);
6061                }
6062                if (intent.getAction() != null) {
6063                    sb.append(intent.getAction());
6064                } else if (intent.getComponent() != null) {
6065                    intent.getComponent().appendShortString(sb);
6066                } else {
6067                    sb.append("?");
6068                }
6069                return res.lastTag = sb.toString();
6070            }
6071        } catch (ClassCastException e) {
6072        }
6073        return null;
6074    }
6075
6076    @Override
6077    public void setProcessLimit(int max) {
6078        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6079                "setProcessLimit()");
6080        synchronized (this) {
6081            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6082            mProcessLimitOverride = max;
6083        }
6084        trimApplications();
6085    }
6086
6087    @Override
6088    public int getProcessLimit() {
6089        synchronized (this) {
6090            return mProcessLimitOverride;
6091        }
6092    }
6093
6094    void foregroundTokenDied(ForegroundToken token) {
6095        synchronized (ActivityManagerService.this) {
6096            synchronized (mPidsSelfLocked) {
6097                ForegroundToken cur
6098                    = mForegroundProcesses.get(token.pid);
6099                if (cur != token) {
6100                    return;
6101                }
6102                mForegroundProcesses.remove(token.pid);
6103                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6104                if (pr == null) {
6105                    return;
6106                }
6107                pr.forcingToForeground = null;
6108                updateProcessForegroundLocked(pr, false, false);
6109            }
6110            updateOomAdjLocked();
6111        }
6112    }
6113
6114    @Override
6115    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6116        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6117                "setProcessForeground()");
6118        synchronized(this) {
6119            boolean changed = false;
6120
6121            synchronized (mPidsSelfLocked) {
6122                ProcessRecord pr = mPidsSelfLocked.get(pid);
6123                if (pr == null && isForeground) {
6124                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6125                    return;
6126                }
6127                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6128                if (oldToken != null) {
6129                    oldToken.token.unlinkToDeath(oldToken, 0);
6130                    mForegroundProcesses.remove(pid);
6131                    if (pr != null) {
6132                        pr.forcingToForeground = null;
6133                    }
6134                    changed = true;
6135                }
6136                if (isForeground && token != null) {
6137                    ForegroundToken newToken = new ForegroundToken() {
6138                        @Override
6139                        public void binderDied() {
6140                            foregroundTokenDied(this);
6141                        }
6142                    };
6143                    newToken.pid = pid;
6144                    newToken.token = token;
6145                    try {
6146                        token.linkToDeath(newToken, 0);
6147                        mForegroundProcesses.put(pid, newToken);
6148                        pr.forcingToForeground = token;
6149                        changed = true;
6150                    } catch (RemoteException e) {
6151                        // If the process died while doing this, we will later
6152                        // do the cleanup with the process death link.
6153                    }
6154                }
6155            }
6156
6157            if (changed) {
6158                updateOomAdjLocked();
6159            }
6160        }
6161    }
6162
6163    // =========================================================
6164    // PERMISSIONS
6165    // =========================================================
6166
6167    static class PermissionController extends IPermissionController.Stub {
6168        ActivityManagerService mActivityManagerService;
6169        PermissionController(ActivityManagerService activityManagerService) {
6170            mActivityManagerService = activityManagerService;
6171        }
6172
6173        @Override
6174        public boolean checkPermission(String permission, int pid, int uid) {
6175            return mActivityManagerService.checkPermission(permission, pid,
6176                    uid) == PackageManager.PERMISSION_GRANTED;
6177        }
6178    }
6179
6180    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6181        @Override
6182        public int checkComponentPermission(String permission, int pid, int uid,
6183                int owningUid, boolean exported) {
6184            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6185                    owningUid, exported);
6186        }
6187
6188        @Override
6189        public Object getAMSLock() {
6190            return ActivityManagerService.this;
6191        }
6192    }
6193
6194    /**
6195     * This can be called with or without the global lock held.
6196     */
6197    int checkComponentPermission(String permission, int pid, int uid,
6198            int owningUid, boolean exported) {
6199        // We might be performing an operation on behalf of an indirect binder
6200        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6201        // client identity accordingly before proceeding.
6202        Identity tlsIdentity = sCallerIdentity.get();
6203        if (tlsIdentity != null) {
6204            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6205                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6206            uid = tlsIdentity.uid;
6207            pid = tlsIdentity.pid;
6208        }
6209
6210        if (pid == MY_PID) {
6211            return PackageManager.PERMISSION_GRANTED;
6212        }
6213
6214        return ActivityManager.checkComponentPermission(permission, uid,
6215                owningUid, exported);
6216    }
6217
6218    /**
6219     * As the only public entry point for permissions checking, this method
6220     * can enforce the semantic that requesting a check on a null global
6221     * permission is automatically denied.  (Internally a null permission
6222     * string is used when calling {@link #checkComponentPermission} in cases
6223     * when only uid-based security is needed.)
6224     *
6225     * This can be called with or without the global lock held.
6226     */
6227    @Override
6228    public int checkPermission(String permission, int pid, int uid) {
6229        if (permission == null) {
6230            return PackageManager.PERMISSION_DENIED;
6231        }
6232        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6233    }
6234
6235    /**
6236     * Binder IPC calls go through the public entry point.
6237     * This can be called with or without the global lock held.
6238     */
6239    int checkCallingPermission(String permission) {
6240        return checkPermission(permission,
6241                Binder.getCallingPid(),
6242                UserHandle.getAppId(Binder.getCallingUid()));
6243    }
6244
6245    /**
6246     * This can be called with or without the global lock held.
6247     */
6248    void enforceCallingPermission(String permission, String func) {
6249        if (checkCallingPermission(permission)
6250                == PackageManager.PERMISSION_GRANTED) {
6251            return;
6252        }
6253
6254        String msg = "Permission Denial: " + func + " from pid="
6255                + Binder.getCallingPid()
6256                + ", uid=" + Binder.getCallingUid()
6257                + " requires " + permission;
6258        Slog.w(TAG, msg);
6259        throw new SecurityException(msg);
6260    }
6261
6262    /**
6263     * Determine if UID is holding permissions required to access {@link Uri} in
6264     * the given {@link ProviderInfo}. Final permission checking is always done
6265     * in {@link ContentProvider}.
6266     */
6267    private final boolean checkHoldingPermissionsLocked(
6268            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6269        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6270                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6271        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6272            return false;
6273        }
6274        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6275    }
6276
6277    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6278            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6279        if (pi.applicationInfo.uid == uid) {
6280            return true;
6281        } else if (!pi.exported) {
6282            return false;
6283        }
6284
6285        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6286        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6287        try {
6288            // check if target holds top-level <provider> permissions
6289            if (!readMet && pi.readPermission != null && considerUidPermissions
6290                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6291                readMet = true;
6292            }
6293            if (!writeMet && pi.writePermission != null && considerUidPermissions
6294                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6295                writeMet = true;
6296            }
6297
6298            // track if unprotected read/write is allowed; any denied
6299            // <path-permission> below removes this ability
6300            boolean allowDefaultRead = pi.readPermission == null;
6301            boolean allowDefaultWrite = pi.writePermission == null;
6302
6303            // check if target holds any <path-permission> that match uri
6304            final PathPermission[] pps = pi.pathPermissions;
6305            if (pps != null) {
6306                final String path = grantUri.uri.getPath();
6307                int i = pps.length;
6308                while (i > 0 && (!readMet || !writeMet)) {
6309                    i--;
6310                    PathPermission pp = pps[i];
6311                    if (pp.match(path)) {
6312                        if (!readMet) {
6313                            final String pprperm = pp.getReadPermission();
6314                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6315                                    + pprperm + " for " + pp.getPath()
6316                                    + ": match=" + pp.match(path)
6317                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6318                            if (pprperm != null) {
6319                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6320                                        == PERMISSION_GRANTED) {
6321                                    readMet = true;
6322                                } else {
6323                                    allowDefaultRead = false;
6324                                }
6325                            }
6326                        }
6327                        if (!writeMet) {
6328                            final String ppwperm = pp.getWritePermission();
6329                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6330                                    + ppwperm + " for " + pp.getPath()
6331                                    + ": match=" + pp.match(path)
6332                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6333                            if (ppwperm != null) {
6334                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6335                                        == PERMISSION_GRANTED) {
6336                                    writeMet = true;
6337                                } else {
6338                                    allowDefaultWrite = false;
6339                                }
6340                            }
6341                        }
6342                    }
6343                }
6344            }
6345
6346            // grant unprotected <provider> read/write, if not blocked by
6347            // <path-permission> above
6348            if (allowDefaultRead) readMet = true;
6349            if (allowDefaultWrite) writeMet = true;
6350
6351        } catch (RemoteException e) {
6352            return false;
6353        }
6354
6355        return readMet && writeMet;
6356    }
6357
6358    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6359        ProviderInfo pi = null;
6360        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6361        if (cpr != null) {
6362            pi = cpr.info;
6363        } else {
6364            try {
6365                pi = AppGlobals.getPackageManager().resolveContentProvider(
6366                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6367            } catch (RemoteException ex) {
6368            }
6369        }
6370        return pi;
6371    }
6372
6373    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6374        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6375        if (targetUris != null) {
6376            return targetUris.get(grantUri);
6377        }
6378        return null;
6379    }
6380
6381    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6382            String targetPkg, int targetUid, GrantUri grantUri) {
6383        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6384        if (targetUris == null) {
6385            targetUris = Maps.newArrayMap();
6386            mGrantedUriPermissions.put(targetUid, targetUris);
6387        }
6388
6389        UriPermission perm = targetUris.get(grantUri);
6390        if (perm == null) {
6391            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6392            targetUris.put(grantUri, perm);
6393        }
6394
6395        return perm;
6396    }
6397
6398    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6399            final int modeFlags) {
6400        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6401        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6402                : UriPermission.STRENGTH_OWNED;
6403
6404        // Root gets to do everything.
6405        if (uid == 0) {
6406            return true;
6407        }
6408
6409        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6410        if (perms == null) return false;
6411
6412        // First look for exact match
6413        final UriPermission exactPerm = perms.get(grantUri);
6414        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6415            return true;
6416        }
6417
6418        // No exact match, look for prefixes
6419        final int N = perms.size();
6420        for (int i = 0; i < N; i++) {
6421            final UriPermission perm = perms.valueAt(i);
6422            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6423                    && perm.getStrength(modeFlags) >= minStrength) {
6424                return true;
6425            }
6426        }
6427
6428        return false;
6429    }
6430
6431    @Override
6432    public int checkUriPermission(Uri uri, int pid, int uid,
6433            final int modeFlags, int userId) {
6434        enforceNotIsolatedCaller("checkUriPermission");
6435
6436        // Another redirected-binder-call permissions check as in
6437        // {@link checkComponentPermission}.
6438        Identity tlsIdentity = sCallerIdentity.get();
6439        if (tlsIdentity != null) {
6440            uid = tlsIdentity.uid;
6441            pid = tlsIdentity.pid;
6442        }
6443
6444        // Our own process gets to do everything.
6445        if (pid == MY_PID) {
6446            return PackageManager.PERMISSION_GRANTED;
6447        }
6448        synchronized (this) {
6449            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6450                    ? PackageManager.PERMISSION_GRANTED
6451                    : PackageManager.PERMISSION_DENIED;
6452        }
6453    }
6454
6455    /**
6456     * Check if the targetPkg can be granted permission to access uri by
6457     * the callingUid using the given modeFlags.  Throws a security exception
6458     * if callingUid is not allowed to do this.  Returns the uid of the target
6459     * if the URI permission grant should be performed; returns -1 if it is not
6460     * needed (for example targetPkg already has permission to access the URI).
6461     * If you already know the uid of the target, you can supply it in
6462     * lastTargetUid else set that to -1.
6463     */
6464    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6465            final int modeFlags, int lastTargetUid) {
6466        if (!Intent.isAccessUriMode(modeFlags)) {
6467            return -1;
6468        }
6469
6470        if (targetPkg != null) {
6471            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6472                    "Checking grant " + targetPkg + " permission to " + grantUri);
6473        }
6474
6475        final IPackageManager pm = AppGlobals.getPackageManager();
6476
6477        // If this is not a content: uri, we can't do anything with it.
6478        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6479            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6480                    "Can't grant URI permission for non-content URI: " + grantUri);
6481            return -1;
6482        }
6483
6484        final String authority = grantUri.uri.getAuthority();
6485        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6486        if (pi == null) {
6487            Slog.w(TAG, "No content provider found for permission check: " +
6488                    grantUri.uri.toSafeString());
6489            return -1;
6490        }
6491
6492        int targetUid = lastTargetUid;
6493        if (targetUid < 0 && targetPkg != null) {
6494            try {
6495                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6496                if (targetUid < 0) {
6497                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6498                            "Can't grant URI permission no uid for: " + targetPkg);
6499                    return -1;
6500                }
6501            } catch (RemoteException ex) {
6502                return -1;
6503            }
6504        }
6505
6506        if (targetUid >= 0) {
6507            // First...  does the target actually need this permission?
6508            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6509                // No need to grant the target this permission.
6510                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6511                        "Target " + targetPkg + " already has full permission to " + grantUri);
6512                return -1;
6513            }
6514        } else {
6515            // First...  there is no target package, so can anyone access it?
6516            boolean allowed = pi.exported;
6517            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6518                if (pi.readPermission != null) {
6519                    allowed = false;
6520                }
6521            }
6522            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6523                if (pi.writePermission != null) {
6524                    allowed = false;
6525                }
6526            }
6527            if (allowed) {
6528                return -1;
6529            }
6530        }
6531
6532        /* There is a special cross user grant if:
6533         * - The target is on another user.
6534         * - Apps on the current user can access the uri without any uid permissions.
6535         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6536         * grant uri permissions.
6537         */
6538        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6539                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6540                modeFlags, false /*without considering the uid permissions*/);
6541
6542        // Second...  is the provider allowing granting of URI permissions?
6543        if (!specialCrossUserGrant) {
6544            if (!pi.grantUriPermissions) {
6545                throw new SecurityException("Provider " + pi.packageName
6546                        + "/" + pi.name
6547                        + " does not allow granting of Uri permissions (uri "
6548                        + grantUri + ")");
6549            }
6550            if (pi.uriPermissionPatterns != null) {
6551                final int N = pi.uriPermissionPatterns.length;
6552                boolean allowed = false;
6553                for (int i=0; i<N; i++) {
6554                    if (pi.uriPermissionPatterns[i] != null
6555                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6556                        allowed = true;
6557                        break;
6558                    }
6559                }
6560                if (!allowed) {
6561                    throw new SecurityException("Provider " + pi.packageName
6562                            + "/" + pi.name
6563                            + " does not allow granting of permission to path of Uri "
6564                            + grantUri);
6565                }
6566            }
6567        }
6568
6569        // Third...  does the caller itself have permission to access
6570        // this uri?
6571        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6572            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6573                // Require they hold a strong enough Uri permission
6574                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6575                    throw new SecurityException("Uid " + callingUid
6576                            + " does not have permission to uri " + grantUri);
6577                }
6578            }
6579        }
6580        return targetUid;
6581    }
6582
6583    @Override
6584    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6585            final int modeFlags, int userId) {
6586        enforceNotIsolatedCaller("checkGrantUriPermission");
6587        synchronized(this) {
6588            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6589                    new GrantUri(userId, uri, false), modeFlags, -1);
6590        }
6591    }
6592
6593    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6594            final int modeFlags, UriPermissionOwner owner) {
6595        if (!Intent.isAccessUriMode(modeFlags)) {
6596            return;
6597        }
6598
6599        // So here we are: the caller has the assumed permission
6600        // to the uri, and the target doesn't.  Let's now give this to
6601        // the target.
6602
6603        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6604                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6605
6606        final String authority = grantUri.uri.getAuthority();
6607        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6608        if (pi == null) {
6609            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6610            return;
6611        }
6612
6613        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6614            grantUri.prefix = true;
6615        }
6616        final UriPermission perm = findOrCreateUriPermissionLocked(
6617                pi.packageName, targetPkg, targetUid, grantUri);
6618        perm.grantModes(modeFlags, owner);
6619    }
6620
6621    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6622            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6623        if (targetPkg == null) {
6624            throw new NullPointerException("targetPkg");
6625        }
6626        int targetUid;
6627        final IPackageManager pm = AppGlobals.getPackageManager();
6628        try {
6629            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6630        } catch (RemoteException ex) {
6631            return;
6632        }
6633
6634        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6635                targetUid);
6636        if (targetUid < 0) {
6637            return;
6638        }
6639
6640        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6641                owner);
6642    }
6643
6644    static class NeededUriGrants extends ArrayList<GrantUri> {
6645        final String targetPkg;
6646        final int targetUid;
6647        final int flags;
6648
6649        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6650            this.targetPkg = targetPkg;
6651            this.targetUid = targetUid;
6652            this.flags = flags;
6653        }
6654    }
6655
6656    /**
6657     * Like checkGrantUriPermissionLocked, but takes an Intent.
6658     */
6659    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6660            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6661        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6662                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6663                + " clip=" + (intent != null ? intent.getClipData() : null)
6664                + " from " + intent + "; flags=0x"
6665                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6666
6667        if (targetPkg == null) {
6668            throw new NullPointerException("targetPkg");
6669        }
6670
6671        if (intent == null) {
6672            return null;
6673        }
6674        Uri data = intent.getData();
6675        ClipData clip = intent.getClipData();
6676        if (data == null && clip == null) {
6677            return null;
6678        }
6679        // Default userId for uris in the intent (if they don't specify it themselves)
6680        int contentUserHint = intent.getContentUserHint();
6681        if (contentUserHint == UserHandle.USER_CURRENT) {
6682            contentUserHint = UserHandle.getUserId(callingUid);
6683        }
6684        final IPackageManager pm = AppGlobals.getPackageManager();
6685        int targetUid;
6686        if (needed != null) {
6687            targetUid = needed.targetUid;
6688        } else {
6689            try {
6690                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6691            } catch (RemoteException ex) {
6692                return null;
6693            }
6694            if (targetUid < 0) {
6695                if (DEBUG_URI_PERMISSION) {
6696                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6697                            + " on user " + targetUserId);
6698                }
6699                return null;
6700            }
6701        }
6702        if (data != null) {
6703            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6704            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6705                    targetUid);
6706            if (targetUid > 0) {
6707                if (needed == null) {
6708                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6709                }
6710                needed.add(grantUri);
6711            }
6712        }
6713        if (clip != null) {
6714            for (int i=0; i<clip.getItemCount(); i++) {
6715                Uri uri = clip.getItemAt(i).getUri();
6716                if (uri != null) {
6717                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6718                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6719                            targetUid);
6720                    if (targetUid > 0) {
6721                        if (needed == null) {
6722                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6723                        }
6724                        needed.add(grantUri);
6725                    }
6726                } else {
6727                    Intent clipIntent = clip.getItemAt(i).getIntent();
6728                    if (clipIntent != null) {
6729                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6730                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6731                        if (newNeeded != null) {
6732                            needed = newNeeded;
6733                        }
6734                    }
6735                }
6736            }
6737        }
6738
6739        return needed;
6740    }
6741
6742    /**
6743     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6744     */
6745    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6746            UriPermissionOwner owner) {
6747        if (needed != null) {
6748            for (int i=0; i<needed.size(); i++) {
6749                GrantUri grantUri = needed.get(i);
6750                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6751                        grantUri, needed.flags, owner);
6752            }
6753        }
6754    }
6755
6756    void grantUriPermissionFromIntentLocked(int callingUid,
6757            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6758        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6759                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6760        if (needed == null) {
6761            return;
6762        }
6763
6764        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6765    }
6766
6767    @Override
6768    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6769            final int modeFlags, int userId) {
6770        enforceNotIsolatedCaller("grantUriPermission");
6771        GrantUri grantUri = new GrantUri(userId, uri, false);
6772        synchronized(this) {
6773            final ProcessRecord r = getRecordForAppLocked(caller);
6774            if (r == null) {
6775                throw new SecurityException("Unable to find app for caller "
6776                        + caller
6777                        + " when granting permission to uri " + grantUri);
6778            }
6779            if (targetPkg == null) {
6780                throw new IllegalArgumentException("null target");
6781            }
6782            if (grantUri == null) {
6783                throw new IllegalArgumentException("null uri");
6784            }
6785
6786            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6787                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6788                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6789                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6790
6791            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6792                    UserHandle.getUserId(r.uid));
6793        }
6794    }
6795
6796    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6797        if (perm.modeFlags == 0) {
6798            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6799                    perm.targetUid);
6800            if (perms != null) {
6801                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6802                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6803
6804                perms.remove(perm.uri);
6805                if (perms.isEmpty()) {
6806                    mGrantedUriPermissions.remove(perm.targetUid);
6807                }
6808            }
6809        }
6810    }
6811
6812    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6813        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6814
6815        final IPackageManager pm = AppGlobals.getPackageManager();
6816        final String authority = grantUri.uri.getAuthority();
6817        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6818        if (pi == null) {
6819            Slog.w(TAG, "No content provider found for permission revoke: "
6820                    + grantUri.toSafeString());
6821            return;
6822        }
6823
6824        // Does the caller have this permission on the URI?
6825        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6826            // Right now, if you are not the original owner of the permission,
6827            // you are not allowed to revoke it.
6828            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6829                throw new SecurityException("Uid " + callingUid
6830                        + " does not have permission to uri " + grantUri);
6831            //}
6832        }
6833
6834        boolean persistChanged = false;
6835
6836        // Go through all of the permissions and remove any that match.
6837        int N = mGrantedUriPermissions.size();
6838        for (int i = 0; i < N; i++) {
6839            final int targetUid = mGrantedUriPermissions.keyAt(i);
6840            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6841
6842            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6843                final UriPermission perm = it.next();
6844                if (perm.uri.sourceUserId == grantUri.sourceUserId
6845                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6846                    if (DEBUG_URI_PERMISSION)
6847                        Slog.v(TAG,
6848                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6849                    persistChanged |= perm.revokeModes(
6850                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6851                    if (perm.modeFlags == 0) {
6852                        it.remove();
6853                    }
6854                }
6855            }
6856
6857            if (perms.isEmpty()) {
6858                mGrantedUriPermissions.remove(targetUid);
6859                N--;
6860                i--;
6861            }
6862        }
6863
6864        if (persistChanged) {
6865            schedulePersistUriGrants();
6866        }
6867    }
6868
6869    @Override
6870    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6871            int userId) {
6872        enforceNotIsolatedCaller("revokeUriPermission");
6873        synchronized(this) {
6874            final ProcessRecord r = getRecordForAppLocked(caller);
6875            if (r == null) {
6876                throw new SecurityException("Unable to find app for caller "
6877                        + caller
6878                        + " when revoking permission to uri " + uri);
6879            }
6880            if (uri == null) {
6881                Slog.w(TAG, "revokeUriPermission: null uri");
6882                return;
6883            }
6884
6885            if (!Intent.isAccessUriMode(modeFlags)) {
6886                return;
6887            }
6888
6889            final IPackageManager pm = AppGlobals.getPackageManager();
6890            final String authority = uri.getAuthority();
6891            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6892            if (pi == null) {
6893                Slog.w(TAG, "No content provider found for permission revoke: "
6894                        + uri.toSafeString());
6895                return;
6896            }
6897
6898            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6899        }
6900    }
6901
6902    /**
6903     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6904     * given package.
6905     *
6906     * @param packageName Package name to match, or {@code null} to apply to all
6907     *            packages.
6908     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6909     *            to all users.
6910     * @param persistable If persistable grants should be removed.
6911     */
6912    private void removeUriPermissionsForPackageLocked(
6913            String packageName, int userHandle, boolean persistable) {
6914        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6915            throw new IllegalArgumentException("Must narrow by either package or user");
6916        }
6917
6918        boolean persistChanged = false;
6919
6920        int N = mGrantedUriPermissions.size();
6921        for (int i = 0; i < N; i++) {
6922            final int targetUid = mGrantedUriPermissions.keyAt(i);
6923            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6924
6925            // Only inspect grants matching user
6926            if (userHandle == UserHandle.USER_ALL
6927                    || userHandle == UserHandle.getUserId(targetUid)) {
6928                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6929                    final UriPermission perm = it.next();
6930
6931                    // Only inspect grants matching package
6932                    if (packageName == null || perm.sourcePkg.equals(packageName)
6933                            || perm.targetPkg.equals(packageName)) {
6934                        persistChanged |= perm.revokeModes(
6935                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6936
6937                        // Only remove when no modes remain; any persisted grants
6938                        // will keep this alive.
6939                        if (perm.modeFlags == 0) {
6940                            it.remove();
6941                        }
6942                    }
6943                }
6944
6945                if (perms.isEmpty()) {
6946                    mGrantedUriPermissions.remove(targetUid);
6947                    N--;
6948                    i--;
6949                }
6950            }
6951        }
6952
6953        if (persistChanged) {
6954            schedulePersistUriGrants();
6955        }
6956    }
6957
6958    @Override
6959    public IBinder newUriPermissionOwner(String name) {
6960        enforceNotIsolatedCaller("newUriPermissionOwner");
6961        synchronized(this) {
6962            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6963            return owner.getExternalTokenLocked();
6964        }
6965    }
6966
6967    @Override
6968    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6969            final int modeFlags, int sourceUserId, int targetUserId) {
6970        synchronized(this) {
6971            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6972            if (owner == null) {
6973                throw new IllegalArgumentException("Unknown owner: " + token);
6974            }
6975            if (fromUid != Binder.getCallingUid()) {
6976                if (Binder.getCallingUid() != Process.myUid()) {
6977                    // Only system code can grant URI permissions on behalf
6978                    // of other users.
6979                    throw new SecurityException("nice try");
6980                }
6981            }
6982            if (targetPkg == null) {
6983                throw new IllegalArgumentException("null target");
6984            }
6985            if (uri == null) {
6986                throw new IllegalArgumentException("null uri");
6987            }
6988
6989            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
6990                    modeFlags, owner, targetUserId);
6991        }
6992    }
6993
6994    @Override
6995    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6996        synchronized(this) {
6997            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6998            if (owner == null) {
6999                throw new IllegalArgumentException("Unknown owner: " + token);
7000            }
7001
7002            if (uri == null) {
7003                owner.removeUriPermissionsLocked(mode);
7004            } else {
7005                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7006            }
7007        }
7008    }
7009
7010    private void schedulePersistUriGrants() {
7011        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7012            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7013                    10 * DateUtils.SECOND_IN_MILLIS);
7014        }
7015    }
7016
7017    private void writeGrantedUriPermissions() {
7018        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7019
7020        // Snapshot permissions so we can persist without lock
7021        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7022        synchronized (this) {
7023            final int size = mGrantedUriPermissions.size();
7024            for (int i = 0; i < size; i++) {
7025                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7026                for (UriPermission perm : perms.values()) {
7027                    if (perm.persistedModeFlags != 0) {
7028                        persist.add(perm.snapshot());
7029                    }
7030                }
7031            }
7032        }
7033
7034        FileOutputStream fos = null;
7035        try {
7036            fos = mGrantFile.startWrite();
7037
7038            XmlSerializer out = new FastXmlSerializer();
7039            out.setOutput(fos, "utf-8");
7040            out.startDocument(null, true);
7041            out.startTag(null, TAG_URI_GRANTS);
7042            for (UriPermission.Snapshot perm : persist) {
7043                out.startTag(null, TAG_URI_GRANT);
7044                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7045                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7046                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7047                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7048                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7049                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7050                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7051                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7052                out.endTag(null, TAG_URI_GRANT);
7053            }
7054            out.endTag(null, TAG_URI_GRANTS);
7055            out.endDocument();
7056
7057            mGrantFile.finishWrite(fos);
7058        } catch (IOException e) {
7059            if (fos != null) {
7060                mGrantFile.failWrite(fos);
7061            }
7062        }
7063    }
7064
7065    private void readGrantedUriPermissionsLocked() {
7066        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7067
7068        final long now = System.currentTimeMillis();
7069
7070        FileInputStream fis = null;
7071        try {
7072            fis = mGrantFile.openRead();
7073            final XmlPullParser in = Xml.newPullParser();
7074            in.setInput(fis, null);
7075
7076            int type;
7077            while ((type = in.next()) != END_DOCUMENT) {
7078                final String tag = in.getName();
7079                if (type == START_TAG) {
7080                    if (TAG_URI_GRANT.equals(tag)) {
7081                        final int sourceUserId;
7082                        final int targetUserId;
7083                        final int userHandle = readIntAttribute(in,
7084                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7085                        if (userHandle != UserHandle.USER_NULL) {
7086                            // For backwards compatibility.
7087                            sourceUserId = userHandle;
7088                            targetUserId = userHandle;
7089                        } else {
7090                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7091                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7092                        }
7093                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7094                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7095                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7096                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7097                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7098                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7099
7100                        // Sanity check that provider still belongs to source package
7101                        final ProviderInfo pi = getProviderInfoLocked(
7102                                uri.getAuthority(), sourceUserId);
7103                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7104                            int targetUid = -1;
7105                            try {
7106                                targetUid = AppGlobals.getPackageManager()
7107                                        .getPackageUid(targetPkg, targetUserId);
7108                            } catch (RemoteException e) {
7109                            }
7110                            if (targetUid != -1) {
7111                                final UriPermission perm = findOrCreateUriPermissionLocked(
7112                                        sourcePkg, targetPkg, targetUid,
7113                                        new GrantUri(sourceUserId, uri, prefix));
7114                                perm.initPersistedModes(modeFlags, createdTime);
7115                            }
7116                        } else {
7117                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7118                                    + " but instead found " + pi);
7119                        }
7120                    }
7121                }
7122            }
7123        } catch (FileNotFoundException e) {
7124            // Missing grants is okay
7125        } catch (IOException e) {
7126            Log.wtf(TAG, "Failed reading Uri grants", e);
7127        } catch (XmlPullParserException e) {
7128            Log.wtf(TAG, "Failed reading Uri grants", e);
7129        } finally {
7130            IoUtils.closeQuietly(fis);
7131        }
7132    }
7133
7134    @Override
7135    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7136        enforceNotIsolatedCaller("takePersistableUriPermission");
7137
7138        Preconditions.checkFlagsArgument(modeFlags,
7139                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7140
7141        synchronized (this) {
7142            final int callingUid = Binder.getCallingUid();
7143            boolean persistChanged = false;
7144            GrantUri grantUri = new GrantUri(userId, uri, false);
7145
7146            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7147                    new GrantUri(userId, uri, false));
7148            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7149                    new GrantUri(userId, uri, true));
7150
7151            final boolean exactValid = (exactPerm != null)
7152                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7153            final boolean prefixValid = (prefixPerm != null)
7154                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7155
7156            if (!(exactValid || prefixValid)) {
7157                throw new SecurityException("No persistable permission grants found for UID "
7158                        + callingUid + " and Uri " + grantUri.toSafeString());
7159            }
7160
7161            if (exactValid) {
7162                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7163            }
7164            if (prefixValid) {
7165                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7166            }
7167
7168            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7169
7170            if (persistChanged) {
7171                schedulePersistUriGrants();
7172            }
7173        }
7174    }
7175
7176    @Override
7177    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7178        enforceNotIsolatedCaller("releasePersistableUriPermission");
7179
7180        Preconditions.checkFlagsArgument(modeFlags,
7181                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7182
7183        synchronized (this) {
7184            final int callingUid = Binder.getCallingUid();
7185            boolean persistChanged = false;
7186
7187            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7188                    new GrantUri(userId, uri, false));
7189            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7190                    new GrantUri(userId, uri, true));
7191            if (exactPerm == null && prefixPerm == null) {
7192                throw new SecurityException("No permission grants found for UID " + callingUid
7193                        + " and Uri " + uri.toSafeString());
7194            }
7195
7196            if (exactPerm != null) {
7197                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7198                removeUriPermissionIfNeededLocked(exactPerm);
7199            }
7200            if (prefixPerm != null) {
7201                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7202                removeUriPermissionIfNeededLocked(prefixPerm);
7203            }
7204
7205            if (persistChanged) {
7206                schedulePersistUriGrants();
7207            }
7208        }
7209    }
7210
7211    /**
7212     * Prune any older {@link UriPermission} for the given UID until outstanding
7213     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7214     *
7215     * @return if any mutations occured that require persisting.
7216     */
7217    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7218        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7219        if (perms == null) return false;
7220        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7221
7222        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7223        for (UriPermission perm : perms.values()) {
7224            if (perm.persistedModeFlags != 0) {
7225                persisted.add(perm);
7226            }
7227        }
7228
7229        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7230        if (trimCount <= 0) return false;
7231
7232        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7233        for (int i = 0; i < trimCount; i++) {
7234            final UriPermission perm = persisted.get(i);
7235
7236            if (DEBUG_URI_PERMISSION) {
7237                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7238            }
7239
7240            perm.releasePersistableModes(~0);
7241            removeUriPermissionIfNeededLocked(perm);
7242        }
7243
7244        return true;
7245    }
7246
7247    @Override
7248    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7249            String packageName, boolean incoming) {
7250        enforceNotIsolatedCaller("getPersistedUriPermissions");
7251        Preconditions.checkNotNull(packageName, "packageName");
7252
7253        final int callingUid = Binder.getCallingUid();
7254        final IPackageManager pm = AppGlobals.getPackageManager();
7255        try {
7256            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7257            if (packageUid != callingUid) {
7258                throw new SecurityException(
7259                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7260            }
7261        } catch (RemoteException e) {
7262            throw new SecurityException("Failed to verify package name ownership");
7263        }
7264
7265        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7266        synchronized (this) {
7267            if (incoming) {
7268                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7269                        callingUid);
7270                if (perms == null) {
7271                    Slog.w(TAG, "No permission grants found for " + packageName);
7272                } else {
7273                    for (UriPermission perm : perms.values()) {
7274                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7275                            result.add(perm.buildPersistedPublicApiObject());
7276                        }
7277                    }
7278                }
7279            } else {
7280                final int size = mGrantedUriPermissions.size();
7281                for (int i = 0; i < size; i++) {
7282                    final ArrayMap<GrantUri, UriPermission> perms =
7283                            mGrantedUriPermissions.valueAt(i);
7284                    for (UriPermission perm : perms.values()) {
7285                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7286                            result.add(perm.buildPersistedPublicApiObject());
7287                        }
7288                    }
7289                }
7290            }
7291        }
7292        return new ParceledListSlice<android.content.UriPermission>(result);
7293    }
7294
7295    @Override
7296    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7297        synchronized (this) {
7298            ProcessRecord app =
7299                who != null ? getRecordForAppLocked(who) : null;
7300            if (app == null) return;
7301
7302            Message msg = Message.obtain();
7303            msg.what = WAIT_FOR_DEBUGGER_MSG;
7304            msg.obj = app;
7305            msg.arg1 = waiting ? 1 : 0;
7306            mHandler.sendMessage(msg);
7307        }
7308    }
7309
7310    @Override
7311    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7312        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7313        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7314        outInfo.availMem = Process.getFreeMemory();
7315        outInfo.totalMem = Process.getTotalMemory();
7316        outInfo.threshold = homeAppMem;
7317        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7318        outInfo.hiddenAppThreshold = cachedAppMem;
7319        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7320                ProcessList.SERVICE_ADJ);
7321        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7322                ProcessList.VISIBLE_APP_ADJ);
7323        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7324                ProcessList.FOREGROUND_APP_ADJ);
7325    }
7326
7327    // =========================================================
7328    // TASK MANAGEMENT
7329    // =========================================================
7330
7331    @Override
7332    public List<IAppTask> getAppTasks() {
7333        final PackageManager pm = mContext.getPackageManager();
7334        int callingUid = Binder.getCallingUid();
7335        long ident = Binder.clearCallingIdentity();
7336
7337        // Compose the list of packages for this id to test against
7338        HashSet<String> packages = new HashSet<String>();
7339        String[] uidPackages = pm.getPackagesForUid(callingUid);
7340        for (int i = 0; i < uidPackages.length; i++) {
7341            packages.add(uidPackages[i]);
7342        }
7343
7344        synchronized(this) {
7345            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7346            try {
7347                if (localLOGV) Slog.v(TAG, "getAppTasks");
7348
7349                final int N = mRecentTasks.size();
7350                for (int i = 0; i < N; i++) {
7351                    TaskRecord tr = mRecentTasks.get(i);
7352                    // Skip tasks that are not created by the caller
7353                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7354                        ActivityManager.RecentTaskInfo taskInfo =
7355                                createRecentTaskInfoFromTaskRecord(tr);
7356                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7357                        list.add(taskImpl);
7358                    }
7359                }
7360            } finally {
7361                Binder.restoreCallingIdentity(ident);
7362            }
7363            return list;
7364        }
7365    }
7366
7367    @Override
7368    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7369        final int callingUid = Binder.getCallingUid();
7370        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7371
7372        synchronized(this) {
7373            if (localLOGV) Slog.v(
7374                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7375
7376            final boolean allowed = checkCallingPermission(
7377                    android.Manifest.permission.GET_TASKS)
7378                    == PackageManager.PERMISSION_GRANTED;
7379            if (!allowed) {
7380                Slog.w(TAG, "getTasks: caller " + callingUid
7381                        + " does not hold GET_TASKS; limiting output");
7382            }
7383
7384            // TODO: Improve with MRU list from all ActivityStacks.
7385            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7386        }
7387
7388        return list;
7389    }
7390
7391    TaskRecord getMostRecentTask() {
7392        return mRecentTasks.get(0);
7393    }
7394
7395    /**
7396     * Creates a new RecentTaskInfo from a TaskRecord.
7397     */
7398    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7399        // Update the task description to reflect any changes in the task stack
7400        tr.updateTaskDescription();
7401
7402        // Compose the recent task info
7403        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7404        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7405        rti.persistentId = tr.taskId;
7406        rti.baseIntent = new Intent(tr.getBaseIntent());
7407        rti.origActivity = tr.origActivity;
7408        rti.description = tr.lastDescription;
7409        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7410        rti.userId = tr.userId;
7411        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7412        rti.firstActiveTime = tr.firstActiveTime;
7413        rti.lastActiveTime = tr.lastActiveTime;
7414        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7415        return rti;
7416    }
7417
7418    @Override
7419    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7420        final int callingUid = Binder.getCallingUid();
7421        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7422                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7423
7424        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7425        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7426        synchronized (this) {
7427            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7428                    == PackageManager.PERMISSION_GRANTED;
7429            if (!allowed) {
7430                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7431                        + " does not hold GET_TASKS; limiting output");
7432            }
7433            final boolean detailed = checkCallingPermission(
7434                    android.Manifest.permission.GET_DETAILED_TASKS)
7435                    == PackageManager.PERMISSION_GRANTED;
7436
7437            IPackageManager pm = AppGlobals.getPackageManager();
7438
7439            final int N = mRecentTasks.size();
7440            ArrayList<ActivityManager.RecentTaskInfo> res
7441                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7442                            maxNum < N ? maxNum : N);
7443
7444            final Set<Integer> includedUsers;
7445            if (includeProfiles) {
7446                includedUsers = getProfileIdsLocked(userId);
7447            } else {
7448                includedUsers = new HashSet<Integer>();
7449            }
7450            includedUsers.add(Integer.valueOf(userId));
7451
7452            // Regroup affiliated tasks together.
7453            for (int i = 0; i < N; ) {
7454                TaskRecord task = mRecentTasks.remove(i);
7455                if (mTmpRecents.contains(task)) {
7456                    continue;
7457                }
7458                int affiliatedTaskId = task.mAffiliatedTaskId;
7459                while (true) {
7460                    TaskRecord next = task.mNextAffiliate;
7461                    if (next == null) {
7462                        break;
7463                    }
7464                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7465                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7466                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7467                        task.setNextAffiliate(null);
7468                        if (next.mPrevAffiliate == task) {
7469                            next.setPrevAffiliate(null);
7470                        }
7471                        break;
7472                    }
7473                    if (next.mPrevAffiliate != task) {
7474                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7475                                next.mPrevAffiliate + " task=" + task);
7476                        next.setPrevAffiliate(null);
7477                        break;
7478                    }
7479                    if (!mRecentTasks.contains(next)) {
7480                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7481                        task.setNextAffiliate(null);
7482                        if (next.mPrevAffiliate == task) {
7483                            next.setPrevAffiliate(null);
7484                        }
7485                        break;
7486                    }
7487                    task = next;
7488                }
7489                // task is now the end of the list
7490                do {
7491                    mRecentTasks.remove(task);
7492                    mRecentTasks.add(i++, task);
7493                    mTmpRecents.add(task);
7494                } while ((task = task.mPrevAffiliate) != null);
7495            }
7496            mTmpRecents.clear();
7497            // mRecentTasks is now in sorted, affiliated order.
7498
7499            for (int i=0; i<N && maxNum > 0; i++) {
7500                TaskRecord tr = mRecentTasks.get(i);
7501                // Only add calling user or related users recent tasks
7502                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7503
7504                // Return the entry if desired by the caller.  We always return
7505                // the first entry, because callers always expect this to be the
7506                // foreground app.  We may filter others if the caller has
7507                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7508                // we should exclude the entry.
7509
7510                if (i == 0
7511                        || withExcluded
7512                        || (tr.intent == null)
7513                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7514                                == 0)) {
7515                    if (!allowed) {
7516                        // If the caller doesn't have the GET_TASKS permission, then only
7517                        // allow them to see a small subset of tasks -- their own and home.
7518                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7519                            continue;
7520                        }
7521                    }
7522                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7523                        // Don't include auto remove tasks that are finished or finishing.
7524                        continue;
7525                    }
7526
7527                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7528                    if (!detailed) {
7529                        rti.baseIntent.replaceExtras((Bundle)null);
7530                    }
7531
7532                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7533                        // Check whether this activity is currently available.
7534                        try {
7535                            if (rti.origActivity != null) {
7536                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7537                                        == null) {
7538                                    continue;
7539                                }
7540                            } else if (rti.baseIntent != null) {
7541                                if (pm.queryIntentActivities(rti.baseIntent,
7542                                        null, 0, userId) == null) {
7543                                    continue;
7544                                }
7545                            }
7546                        } catch (RemoteException e) {
7547                            // Will never happen.
7548                        }
7549                    }
7550
7551                    res.add(rti);
7552                    maxNum--;
7553                }
7554            }
7555            return res;
7556        }
7557    }
7558
7559    private TaskRecord recentTaskForIdLocked(int id) {
7560        final int N = mRecentTasks.size();
7561            for (int i=0; i<N; i++) {
7562                TaskRecord tr = mRecentTasks.get(i);
7563                if (tr.taskId == id) {
7564                    return tr;
7565                }
7566            }
7567            return null;
7568    }
7569
7570    @Override
7571    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7572        synchronized (this) {
7573            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7574                    "getTaskThumbnail()");
7575            TaskRecord tr = recentTaskForIdLocked(id);
7576            if (tr != null) {
7577                return tr.getTaskThumbnailLocked();
7578            }
7579        }
7580        return null;
7581    }
7582
7583    @Override
7584    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7585        synchronized (this) {
7586            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7587            if (r != null) {
7588                r.taskDescription = td;
7589                r.task.updateTaskDescription();
7590            }
7591        }
7592    }
7593
7594    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7595        if (!pr.killedByAm) {
7596            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7597            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7598                    pr.processName, pr.setAdj, reason);
7599            pr.killedByAm = true;
7600            Process.killProcessQuiet(pr.pid);
7601            Process.killProcessGroup(pr.info.uid, pr.pid);
7602        }
7603    }
7604
7605    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7606        tr.disposeThumbnail();
7607        mRecentTasks.remove(tr);
7608        tr.closeRecentsChain();
7609        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7610        Intent baseIntent = new Intent(
7611                tr.intent != null ? tr.intent : tr.affinityIntent);
7612        ComponentName component = baseIntent.getComponent();
7613        if (component == null) {
7614            Slog.w(TAG, "Now component for base intent of task: " + tr);
7615            return;
7616        }
7617
7618        // Find any running services associated with this app.
7619        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7620
7621        if (killProcesses) {
7622            // Find any running processes associated with this app.
7623            final String pkg = component.getPackageName();
7624            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7625            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7626            for (int i=0; i<pmap.size(); i++) {
7627                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7628                for (int j=0; j<uids.size(); j++) {
7629                    ProcessRecord proc = uids.valueAt(j);
7630                    if (proc.userId != tr.userId) {
7631                        continue;
7632                    }
7633                    if (!proc.pkgList.containsKey(pkg)) {
7634                        continue;
7635                    }
7636                    procs.add(proc);
7637                }
7638            }
7639
7640            // Kill the running processes.
7641            for (int i=0; i<procs.size(); i++) {
7642                ProcessRecord pr = procs.get(i);
7643                if (pr == mHomeProcess) {
7644                    // Don't kill the home process along with tasks from the same package.
7645                    continue;
7646                }
7647                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7648                    killUnneededProcessLocked(pr, "remove task");
7649                } else {
7650                    pr.waitingToKill = "remove task";
7651                }
7652            }
7653        }
7654    }
7655
7656    /**
7657     * Removes the task with the specified task id.
7658     *
7659     * @param taskId Identifier of the task to be removed.
7660     * @param flags Additional operational flags.  May be 0 or
7661     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7662     * @return Returns true if the given task was found and removed.
7663     */
7664    private boolean removeTaskByIdLocked(int taskId, int flags) {
7665        TaskRecord tr = recentTaskForIdLocked(taskId);
7666        if (tr != null) {
7667            tr.removeTaskActivitiesLocked();
7668            cleanUpRemovedTaskLocked(tr, flags);
7669            if (tr.isPersistable) {
7670                notifyTaskPersisterLocked(null, true);
7671            }
7672            return true;
7673        }
7674        return false;
7675    }
7676
7677    @Override
7678    public boolean removeTask(int taskId, int flags) {
7679        synchronized (this) {
7680            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7681                    "removeTask()");
7682            long ident = Binder.clearCallingIdentity();
7683            try {
7684                return removeTaskByIdLocked(taskId, flags);
7685            } finally {
7686                Binder.restoreCallingIdentity(ident);
7687            }
7688        }
7689    }
7690
7691    /**
7692     * TODO: Add mController hook
7693     */
7694    @Override
7695    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7696        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7697                "moveTaskToFront()");
7698
7699        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7700        synchronized(this) {
7701            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7702                    Binder.getCallingUid(), "Task to front")) {
7703                ActivityOptions.abort(options);
7704                return;
7705            }
7706            final long origId = Binder.clearCallingIdentity();
7707            try {
7708                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7709                if (task == null) {
7710                    return;
7711                }
7712                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7713                    mStackSupervisor.showLockTaskToast();
7714                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7715                    return;
7716                }
7717                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7718                if (prev != null && prev.isRecentsActivity()) {
7719                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7720                }
7721                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7722            } finally {
7723                Binder.restoreCallingIdentity(origId);
7724            }
7725            ActivityOptions.abort(options);
7726        }
7727    }
7728
7729    @Override
7730    public void moveTaskToBack(int taskId) {
7731        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7732                "moveTaskToBack()");
7733
7734        synchronized(this) {
7735            TaskRecord tr = recentTaskForIdLocked(taskId);
7736            if (tr != null) {
7737                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7738                ActivityStack stack = tr.stack;
7739                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7740                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7741                            Binder.getCallingUid(), "Task to back")) {
7742                        return;
7743                    }
7744                }
7745                final long origId = Binder.clearCallingIdentity();
7746                try {
7747                    stack.moveTaskToBackLocked(taskId, null);
7748                } finally {
7749                    Binder.restoreCallingIdentity(origId);
7750                }
7751            }
7752        }
7753    }
7754
7755    /**
7756     * Moves an activity, and all of the other activities within the same task, to the bottom
7757     * of the history stack.  The activity's order within the task is unchanged.
7758     *
7759     * @param token A reference to the activity we wish to move
7760     * @param nonRoot If false then this only works if the activity is the root
7761     *                of a task; if true it will work for any activity in a task.
7762     * @return Returns true if the move completed, false if not.
7763     */
7764    @Override
7765    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7766        enforceNotIsolatedCaller("moveActivityTaskToBack");
7767        synchronized(this) {
7768            final long origId = Binder.clearCallingIdentity();
7769            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7770            if (taskId >= 0) {
7771                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7772            }
7773            Binder.restoreCallingIdentity(origId);
7774        }
7775        return false;
7776    }
7777
7778    @Override
7779    public void moveTaskBackwards(int task) {
7780        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7781                "moveTaskBackwards()");
7782
7783        synchronized(this) {
7784            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7785                    Binder.getCallingUid(), "Task backwards")) {
7786                return;
7787            }
7788            final long origId = Binder.clearCallingIdentity();
7789            moveTaskBackwardsLocked(task);
7790            Binder.restoreCallingIdentity(origId);
7791        }
7792    }
7793
7794    private final void moveTaskBackwardsLocked(int task) {
7795        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7796    }
7797
7798    @Override
7799    public IBinder getHomeActivityToken() throws RemoteException {
7800        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7801                "getHomeActivityToken()");
7802        synchronized (this) {
7803            return mStackSupervisor.getHomeActivityToken();
7804        }
7805    }
7806
7807    @Override
7808    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7809            IActivityContainerCallback callback) throws RemoteException {
7810        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7811                "createActivityContainer()");
7812        synchronized (this) {
7813            if (parentActivityToken == null) {
7814                throw new IllegalArgumentException("parent token must not be null");
7815            }
7816            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7817            if (r == null) {
7818                return null;
7819            }
7820            if (callback == null) {
7821                throw new IllegalArgumentException("callback must not be null");
7822            }
7823            return mStackSupervisor.createActivityContainer(r, callback);
7824        }
7825    }
7826
7827    @Override
7828    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7829        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7830                "deleteActivityContainer()");
7831        synchronized (this) {
7832            mStackSupervisor.deleteActivityContainer(container);
7833        }
7834    }
7835
7836    @Override
7837    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7838            throws RemoteException {
7839        synchronized (this) {
7840            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7841            if (stack != null) {
7842                return stack.mActivityContainer;
7843            }
7844            return null;
7845        }
7846    }
7847
7848    @Override
7849    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7850        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7851                "moveTaskToStack()");
7852        if (stackId == HOME_STACK_ID) {
7853            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7854                    new RuntimeException("here").fillInStackTrace());
7855        }
7856        synchronized (this) {
7857            long ident = Binder.clearCallingIdentity();
7858            try {
7859                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7860                        + stackId + " toTop=" + toTop);
7861                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7862            } finally {
7863                Binder.restoreCallingIdentity(ident);
7864            }
7865        }
7866    }
7867
7868    @Override
7869    public void resizeStack(int stackBoxId, Rect bounds) {
7870        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7871                "resizeStackBox()");
7872        long ident = Binder.clearCallingIdentity();
7873        try {
7874            mWindowManager.resizeStack(stackBoxId, bounds);
7875        } finally {
7876            Binder.restoreCallingIdentity(ident);
7877        }
7878    }
7879
7880    @Override
7881    public List<StackInfo> getAllStackInfos() {
7882        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7883                "getAllStackInfos()");
7884        long ident = Binder.clearCallingIdentity();
7885        try {
7886            synchronized (this) {
7887                return mStackSupervisor.getAllStackInfosLocked();
7888            }
7889        } finally {
7890            Binder.restoreCallingIdentity(ident);
7891        }
7892    }
7893
7894    @Override
7895    public StackInfo getStackInfo(int stackId) {
7896        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7897                "getStackInfo()");
7898        long ident = Binder.clearCallingIdentity();
7899        try {
7900            synchronized (this) {
7901                return mStackSupervisor.getStackInfoLocked(stackId);
7902            }
7903        } finally {
7904            Binder.restoreCallingIdentity(ident);
7905        }
7906    }
7907
7908    @Override
7909    public boolean isInHomeStack(int taskId) {
7910        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7911                "getStackInfo()");
7912        long ident = Binder.clearCallingIdentity();
7913        try {
7914            synchronized (this) {
7915                TaskRecord tr = recentTaskForIdLocked(taskId);
7916                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7917            }
7918        } finally {
7919            Binder.restoreCallingIdentity(ident);
7920        }
7921    }
7922
7923    @Override
7924    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7925        synchronized(this) {
7926            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7927        }
7928    }
7929
7930    private boolean isLockTaskAuthorized(String pkg) {
7931        final DevicePolicyManager dpm = (DevicePolicyManager)
7932                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7933        try {
7934            int uid = mContext.getPackageManager().getPackageUid(pkg,
7935                    Binder.getCallingUserHandle().getIdentifier());
7936            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7937        } catch (NameNotFoundException e) {
7938            return false;
7939        }
7940    }
7941
7942    void startLockTaskMode(TaskRecord task) {
7943        final String pkg;
7944        synchronized (this) {
7945            pkg = task.intent.getComponent().getPackageName();
7946        }
7947        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7948        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7949            final TaskRecord taskRecord = task;
7950            mHandler.post(new Runnable() {
7951                @Override
7952                public void run() {
7953                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7954                }
7955            });
7956            return;
7957        }
7958        long ident = Binder.clearCallingIdentity();
7959        try {
7960            synchronized (this) {
7961                // Since we lost lock on task, make sure it is still there.
7962                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7963                if (task != null) {
7964                    if (!isSystemInitiated
7965                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7966                        throw new IllegalArgumentException("Invalid task, not in foreground");
7967                    }
7968                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7969                }
7970            }
7971        } finally {
7972            Binder.restoreCallingIdentity(ident);
7973        }
7974    }
7975
7976    @Override
7977    public void startLockTaskMode(int taskId) {
7978        final TaskRecord task;
7979        long ident = Binder.clearCallingIdentity();
7980        try {
7981            synchronized (this) {
7982                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7983            }
7984        } finally {
7985            Binder.restoreCallingIdentity(ident);
7986        }
7987        if (task != null) {
7988            startLockTaskMode(task);
7989        }
7990    }
7991
7992    @Override
7993    public void startLockTaskMode(IBinder token) {
7994        final TaskRecord task;
7995        long ident = Binder.clearCallingIdentity();
7996        try {
7997            synchronized (this) {
7998                final ActivityRecord r = ActivityRecord.forToken(token);
7999                if (r == null) {
8000                    return;
8001                }
8002                task = r.task;
8003            }
8004        } finally {
8005            Binder.restoreCallingIdentity(ident);
8006        }
8007        if (task != null) {
8008            startLockTaskMode(task);
8009        }
8010    }
8011
8012    @Override
8013    public void startLockTaskModeOnCurrent() throws RemoteException {
8014        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8015        ActivityRecord r = null;
8016        synchronized (this) {
8017            r = mStackSupervisor.topRunningActivityLocked();
8018        }
8019        startLockTaskMode(r.task);
8020    }
8021
8022    @Override
8023    public void stopLockTaskMode() {
8024        // Verify that the user matches the package of the intent for the TaskRecord
8025        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8026        // and stopLockTaskMode.
8027        final int callingUid = Binder.getCallingUid();
8028        if (callingUid != Process.SYSTEM_UID) {
8029            try {
8030                String pkg =
8031                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8032                int uid = mContext.getPackageManager().getPackageUid(pkg,
8033                        Binder.getCallingUserHandle().getIdentifier());
8034                if (uid != callingUid) {
8035                    throw new SecurityException("Invalid uid, expected " + uid);
8036                }
8037            } catch (NameNotFoundException e) {
8038                Log.d(TAG, "stopLockTaskMode " + e);
8039                return;
8040            }
8041        }
8042        long ident = Binder.clearCallingIdentity();
8043        try {
8044            Log.d(TAG, "stopLockTaskMode");
8045            // Stop lock task
8046            synchronized (this) {
8047                mStackSupervisor.setLockTaskModeLocked(null, false);
8048            }
8049        } finally {
8050            Binder.restoreCallingIdentity(ident);
8051        }
8052    }
8053
8054    @Override
8055    public void stopLockTaskModeOnCurrent() throws RemoteException {
8056        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8057        long ident = Binder.clearCallingIdentity();
8058        try {
8059            stopLockTaskMode();
8060        } finally {
8061            Binder.restoreCallingIdentity(ident);
8062        }
8063    }
8064
8065    @Override
8066    public boolean isInLockTaskMode() {
8067        synchronized (this) {
8068            return mStackSupervisor.isInLockTaskMode();
8069        }
8070    }
8071
8072    // =========================================================
8073    // CONTENT PROVIDERS
8074    // =========================================================
8075
8076    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8077        List<ProviderInfo> providers = null;
8078        try {
8079            providers = AppGlobals.getPackageManager().
8080                queryContentProviders(app.processName, app.uid,
8081                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8082        } catch (RemoteException ex) {
8083        }
8084        if (DEBUG_MU)
8085            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8086        int userId = app.userId;
8087        if (providers != null) {
8088            int N = providers.size();
8089            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8090            for (int i=0; i<N; i++) {
8091                ProviderInfo cpi =
8092                    (ProviderInfo)providers.get(i);
8093                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8094                        cpi.name, cpi.flags);
8095                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8096                    // This is a singleton provider, but a user besides the
8097                    // default user is asking to initialize a process it runs
8098                    // in...  well, no, it doesn't actually run in this process,
8099                    // it runs in the process of the default user.  Get rid of it.
8100                    providers.remove(i);
8101                    N--;
8102                    i--;
8103                    continue;
8104                }
8105
8106                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8107                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8108                if (cpr == null) {
8109                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8110                    mProviderMap.putProviderByClass(comp, cpr);
8111                }
8112                if (DEBUG_MU)
8113                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8114                app.pubProviders.put(cpi.name, cpr);
8115                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8116                    // Don't add this if it is a platform component that is marked
8117                    // to run in multiple processes, because this is actually
8118                    // part of the framework so doesn't make sense to track as a
8119                    // separate apk in the process.
8120                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8121                            mProcessStats);
8122                }
8123                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8124            }
8125        }
8126        return providers;
8127    }
8128
8129    /**
8130     * Check if {@link ProcessRecord} has a possible chance at accessing the
8131     * given {@link ProviderInfo}. Final permission checking is always done
8132     * in {@link ContentProvider}.
8133     */
8134    private final String checkContentProviderPermissionLocked(
8135            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8136        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8137        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8138        boolean checkedGrants = false;
8139        if (checkUser) {
8140            // Looking for cross-user grants before enforcing the typical cross-users permissions
8141            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8142            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8143                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8144                    return null;
8145                }
8146                checkedGrants = true;
8147            }
8148            userId = handleIncomingUser(callingPid, callingUid, userId,
8149                    false, ALLOW_NON_FULL,
8150                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8151            if (userId != tmpTargetUserId) {
8152                // When we actually went to determine the final targer user ID, this ended
8153                // up different than our initial check for the authority.  This is because
8154                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8155                // SELF.  So we need to re-check the grants again.
8156                checkedGrants = false;
8157            }
8158        }
8159        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8160                cpi.applicationInfo.uid, cpi.exported)
8161                == PackageManager.PERMISSION_GRANTED) {
8162            return null;
8163        }
8164        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8165                cpi.applicationInfo.uid, cpi.exported)
8166                == PackageManager.PERMISSION_GRANTED) {
8167            return null;
8168        }
8169
8170        PathPermission[] pps = cpi.pathPermissions;
8171        if (pps != null) {
8172            int i = pps.length;
8173            while (i > 0) {
8174                i--;
8175                PathPermission pp = pps[i];
8176                String pprperm = pp.getReadPermission();
8177                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8178                        cpi.applicationInfo.uid, cpi.exported)
8179                        == PackageManager.PERMISSION_GRANTED) {
8180                    return null;
8181                }
8182                String ppwperm = pp.getWritePermission();
8183                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8184                        cpi.applicationInfo.uid, cpi.exported)
8185                        == PackageManager.PERMISSION_GRANTED) {
8186                    return null;
8187                }
8188            }
8189        }
8190        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8191            return null;
8192        }
8193
8194        String msg;
8195        if (!cpi.exported) {
8196            msg = "Permission Denial: opening provider " + cpi.name
8197                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8198                    + ", uid=" + callingUid + ") that is not exported from uid "
8199                    + cpi.applicationInfo.uid;
8200        } else {
8201            msg = "Permission Denial: opening provider " + cpi.name
8202                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8203                    + ", uid=" + callingUid + ") requires "
8204                    + cpi.readPermission + " or " + cpi.writePermission;
8205        }
8206        Slog.w(TAG, msg);
8207        return msg;
8208    }
8209
8210    /**
8211     * Returns if the ContentProvider has granted a uri to callingUid
8212     */
8213    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8214        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8215        if (perms != null) {
8216            for (int i=perms.size()-1; i>=0; i--) {
8217                GrantUri grantUri = perms.keyAt(i);
8218                if (grantUri.sourceUserId == userId || !checkUser) {
8219                    if (matchesProvider(grantUri.uri, cpi)) {
8220                        return true;
8221                    }
8222                }
8223            }
8224        }
8225        return false;
8226    }
8227
8228    /**
8229     * Returns true if the uri authority is one of the authorities specified in the provider.
8230     */
8231    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8232        String uriAuth = uri.getAuthority();
8233        String cpiAuth = cpi.authority;
8234        if (cpiAuth.indexOf(';') == -1) {
8235            return cpiAuth.equals(uriAuth);
8236        }
8237        String[] cpiAuths = cpiAuth.split(";");
8238        int length = cpiAuths.length;
8239        for (int i = 0; i < length; i++) {
8240            if (cpiAuths[i].equals(uriAuth)) return true;
8241        }
8242        return false;
8243    }
8244
8245    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8246            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8247        if (r != null) {
8248            for (int i=0; i<r.conProviders.size(); i++) {
8249                ContentProviderConnection conn = r.conProviders.get(i);
8250                if (conn.provider == cpr) {
8251                    if (DEBUG_PROVIDER) Slog.v(TAG,
8252                            "Adding provider requested by "
8253                            + r.processName + " from process "
8254                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8255                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8256                    if (stable) {
8257                        conn.stableCount++;
8258                        conn.numStableIncs++;
8259                    } else {
8260                        conn.unstableCount++;
8261                        conn.numUnstableIncs++;
8262                    }
8263                    return conn;
8264                }
8265            }
8266            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8267            if (stable) {
8268                conn.stableCount = 1;
8269                conn.numStableIncs = 1;
8270            } else {
8271                conn.unstableCount = 1;
8272                conn.numUnstableIncs = 1;
8273            }
8274            cpr.connections.add(conn);
8275            r.conProviders.add(conn);
8276            return conn;
8277        }
8278        cpr.addExternalProcessHandleLocked(externalProcessToken);
8279        return null;
8280    }
8281
8282    boolean decProviderCountLocked(ContentProviderConnection conn,
8283            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8284        if (conn != null) {
8285            cpr = conn.provider;
8286            if (DEBUG_PROVIDER) Slog.v(TAG,
8287                    "Removing provider requested by "
8288                    + conn.client.processName + " from process "
8289                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8290                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8291            if (stable) {
8292                conn.stableCount--;
8293            } else {
8294                conn.unstableCount--;
8295            }
8296            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8297                cpr.connections.remove(conn);
8298                conn.client.conProviders.remove(conn);
8299                return true;
8300            }
8301            return false;
8302        }
8303        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8304        return false;
8305    }
8306
8307    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8308            String name, IBinder token, boolean stable, int userId) {
8309        ContentProviderRecord cpr;
8310        ContentProviderConnection conn = null;
8311        ProviderInfo cpi = null;
8312
8313        synchronized(this) {
8314            ProcessRecord r = null;
8315            if (caller != null) {
8316                r = getRecordForAppLocked(caller);
8317                if (r == null) {
8318                    throw new SecurityException(
8319                            "Unable to find app for caller " + caller
8320                          + " (pid=" + Binder.getCallingPid()
8321                          + ") when getting content provider " + name);
8322                }
8323            }
8324
8325            boolean checkCrossUser = true;
8326
8327            // First check if this content provider has been published...
8328            cpr = mProviderMap.getProviderByName(name, userId);
8329            // If that didn't work, check if it exists for user 0 and then
8330            // verify that it's a singleton provider before using it.
8331            if (cpr == null && userId != UserHandle.USER_OWNER) {
8332                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8333                if (cpr != null) {
8334                    cpi = cpr.info;
8335                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8336                            cpi.name, cpi.flags)
8337                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8338                        userId = UserHandle.USER_OWNER;
8339                        checkCrossUser = false;
8340                    } else {
8341                        cpr = null;
8342                        cpi = null;
8343                    }
8344                }
8345            }
8346
8347            boolean providerRunning = cpr != null;
8348            if (providerRunning) {
8349                cpi = cpr.info;
8350                String msg;
8351                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8352                        != null) {
8353                    throw new SecurityException(msg);
8354                }
8355
8356                if (r != null && cpr.canRunHere(r)) {
8357                    // This provider has been published or is in the process
8358                    // of being published...  but it is also allowed to run
8359                    // in the caller's process, so don't make a connection
8360                    // and just let the caller instantiate its own instance.
8361                    ContentProviderHolder holder = cpr.newHolder(null);
8362                    // don't give caller the provider object, it needs
8363                    // to make its own.
8364                    holder.provider = null;
8365                    return holder;
8366                }
8367
8368                final long origId = Binder.clearCallingIdentity();
8369
8370                // In this case the provider instance already exists, so we can
8371                // return it right away.
8372                conn = incProviderCountLocked(r, cpr, token, stable);
8373                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8374                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8375                        // If this is a perceptible app accessing the provider,
8376                        // make sure to count it as being accessed and thus
8377                        // back up on the LRU list.  This is good because
8378                        // content providers are often expensive to start.
8379                        updateLruProcessLocked(cpr.proc, false, null);
8380                    }
8381                }
8382
8383                if (cpr.proc != null) {
8384                    if (false) {
8385                        if (cpr.name.flattenToShortString().equals(
8386                                "com.android.providers.calendar/.CalendarProvider2")) {
8387                            Slog.v(TAG, "****************** KILLING "
8388                                + cpr.name.flattenToShortString());
8389                            Process.killProcess(cpr.proc.pid);
8390                        }
8391                    }
8392                    boolean success = updateOomAdjLocked(cpr.proc);
8393                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8394                    // NOTE: there is still a race here where a signal could be
8395                    // pending on the process even though we managed to update its
8396                    // adj level.  Not sure what to do about this, but at least
8397                    // the race is now smaller.
8398                    if (!success) {
8399                        // Uh oh...  it looks like the provider's process
8400                        // has been killed on us.  We need to wait for a new
8401                        // process to be started, and make sure its death
8402                        // doesn't kill our process.
8403                        Slog.i(TAG,
8404                                "Existing provider " + cpr.name.flattenToShortString()
8405                                + " is crashing; detaching " + r);
8406                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8407                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8408                        if (!lastRef) {
8409                            // This wasn't the last ref our process had on
8410                            // the provider...  we have now been killed, bail.
8411                            return null;
8412                        }
8413                        providerRunning = false;
8414                        conn = null;
8415                    }
8416                }
8417
8418                Binder.restoreCallingIdentity(origId);
8419            }
8420
8421            boolean singleton;
8422            if (!providerRunning) {
8423                try {
8424                    cpi = AppGlobals.getPackageManager().
8425                        resolveContentProvider(name,
8426                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8427                } catch (RemoteException ex) {
8428                }
8429                if (cpi == null) {
8430                    return null;
8431                }
8432                // If the provider is a singleton AND
8433                // (it's a call within the same user || the provider is a
8434                // privileged app)
8435                // Then allow connecting to the singleton provider
8436                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8437                        cpi.name, cpi.flags)
8438                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8439                if (singleton) {
8440                    userId = UserHandle.USER_OWNER;
8441                }
8442                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8443
8444                String msg;
8445                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8446                        != null) {
8447                    throw new SecurityException(msg);
8448                }
8449
8450                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8451                        && !cpi.processName.equals("system")) {
8452                    // If this content provider does not run in the system
8453                    // process, and the system is not yet ready to run other
8454                    // processes, then fail fast instead of hanging.
8455                    throw new IllegalArgumentException(
8456                            "Attempt to launch content provider before system ready");
8457                }
8458
8459                // Make sure that the user who owns this provider is started.  If not,
8460                // we don't want to allow it to run.
8461                if (mStartedUsers.get(userId) == null) {
8462                    Slog.w(TAG, "Unable to launch app "
8463                            + cpi.applicationInfo.packageName + "/"
8464                            + cpi.applicationInfo.uid + " for provider "
8465                            + name + ": user " + userId + " is stopped");
8466                    return null;
8467                }
8468
8469                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8470                cpr = mProviderMap.getProviderByClass(comp, userId);
8471                final boolean firstClass = cpr == null;
8472                if (firstClass) {
8473                    try {
8474                        ApplicationInfo ai =
8475                            AppGlobals.getPackageManager().
8476                                getApplicationInfo(
8477                                        cpi.applicationInfo.packageName,
8478                                        STOCK_PM_FLAGS, userId);
8479                        if (ai == null) {
8480                            Slog.w(TAG, "No package info for content provider "
8481                                    + cpi.name);
8482                            return null;
8483                        }
8484                        ai = getAppInfoForUser(ai, userId);
8485                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8486                    } catch (RemoteException ex) {
8487                        // pm is in same process, this will never happen.
8488                    }
8489                }
8490
8491                if (r != null && cpr.canRunHere(r)) {
8492                    // If this is a multiprocess provider, then just return its
8493                    // info and allow the caller to instantiate it.  Only do
8494                    // this if the provider is the same user as the caller's
8495                    // process, or can run as root (so can be in any process).
8496                    return cpr.newHolder(null);
8497                }
8498
8499                if (DEBUG_PROVIDER) {
8500                    RuntimeException e = new RuntimeException("here");
8501                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8502                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8503                }
8504
8505                // This is single process, and our app is now connecting to it.
8506                // See if we are already in the process of launching this
8507                // provider.
8508                final int N = mLaunchingProviders.size();
8509                int i;
8510                for (i=0; i<N; i++) {
8511                    if (mLaunchingProviders.get(i) == cpr) {
8512                        break;
8513                    }
8514                }
8515
8516                // If the provider is not already being launched, then get it
8517                // started.
8518                if (i >= N) {
8519                    final long origId = Binder.clearCallingIdentity();
8520
8521                    try {
8522                        // Content provider is now in use, its package can't be stopped.
8523                        try {
8524                            AppGlobals.getPackageManager().setPackageStoppedState(
8525                                    cpr.appInfo.packageName, false, userId);
8526                        } catch (RemoteException e) {
8527                        } catch (IllegalArgumentException e) {
8528                            Slog.w(TAG, "Failed trying to unstop package "
8529                                    + cpr.appInfo.packageName + ": " + e);
8530                        }
8531
8532                        // Use existing process if already started
8533                        ProcessRecord proc = getProcessRecordLocked(
8534                                cpi.processName, cpr.appInfo.uid, false);
8535                        if (proc != null && proc.thread != null) {
8536                            if (DEBUG_PROVIDER) {
8537                                Slog.d(TAG, "Installing in existing process " + proc);
8538                            }
8539                            proc.pubProviders.put(cpi.name, cpr);
8540                            try {
8541                                proc.thread.scheduleInstallProvider(cpi);
8542                            } catch (RemoteException e) {
8543                            }
8544                        } else {
8545                            proc = startProcessLocked(cpi.processName,
8546                                    cpr.appInfo, false, 0, "content provider",
8547                                    new ComponentName(cpi.applicationInfo.packageName,
8548                                            cpi.name), false, false, false);
8549                            if (proc == null) {
8550                                Slog.w(TAG, "Unable to launch app "
8551                                        + cpi.applicationInfo.packageName + "/"
8552                                        + cpi.applicationInfo.uid + " for provider "
8553                                        + name + ": process is bad");
8554                                return null;
8555                            }
8556                        }
8557                        cpr.launchingApp = proc;
8558                        mLaunchingProviders.add(cpr);
8559                    } finally {
8560                        Binder.restoreCallingIdentity(origId);
8561                    }
8562                }
8563
8564                // Make sure the provider is published (the same provider class
8565                // may be published under multiple names).
8566                if (firstClass) {
8567                    mProviderMap.putProviderByClass(comp, cpr);
8568                }
8569
8570                mProviderMap.putProviderByName(name, cpr);
8571                conn = incProviderCountLocked(r, cpr, token, stable);
8572                if (conn != null) {
8573                    conn.waiting = true;
8574                }
8575            }
8576        }
8577
8578        // Wait for the provider to be published...
8579        synchronized (cpr) {
8580            while (cpr.provider == null) {
8581                if (cpr.launchingApp == null) {
8582                    Slog.w(TAG, "Unable to launch app "
8583                            + cpi.applicationInfo.packageName + "/"
8584                            + cpi.applicationInfo.uid + " for provider "
8585                            + name + ": launching app became null");
8586                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8587                            UserHandle.getUserId(cpi.applicationInfo.uid),
8588                            cpi.applicationInfo.packageName,
8589                            cpi.applicationInfo.uid, name);
8590                    return null;
8591                }
8592                try {
8593                    if (DEBUG_MU) {
8594                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8595                                + cpr.launchingApp);
8596                    }
8597                    if (conn != null) {
8598                        conn.waiting = true;
8599                    }
8600                    cpr.wait();
8601                } catch (InterruptedException ex) {
8602                } finally {
8603                    if (conn != null) {
8604                        conn.waiting = false;
8605                    }
8606                }
8607            }
8608        }
8609        return cpr != null ? cpr.newHolder(conn) : null;
8610    }
8611
8612    @Override
8613    public final ContentProviderHolder getContentProvider(
8614            IApplicationThread caller, String name, int userId, boolean stable) {
8615        enforceNotIsolatedCaller("getContentProvider");
8616        if (caller == null) {
8617            String msg = "null IApplicationThread when getting content provider "
8618                    + name;
8619            Slog.w(TAG, msg);
8620            throw new SecurityException(msg);
8621        }
8622        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8623        // with cross-user grant.
8624        return getContentProviderImpl(caller, name, null, stable, userId);
8625    }
8626
8627    public ContentProviderHolder getContentProviderExternal(
8628            String name, int userId, IBinder token) {
8629        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8630            "Do not have permission in call getContentProviderExternal()");
8631        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8632                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8633        return getContentProviderExternalUnchecked(name, token, userId);
8634    }
8635
8636    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8637            IBinder token, int userId) {
8638        return getContentProviderImpl(null, name, token, true, userId);
8639    }
8640
8641    /**
8642     * Drop a content provider from a ProcessRecord's bookkeeping
8643     */
8644    public void removeContentProvider(IBinder connection, boolean stable) {
8645        enforceNotIsolatedCaller("removeContentProvider");
8646        long ident = Binder.clearCallingIdentity();
8647        try {
8648            synchronized (this) {
8649                ContentProviderConnection conn;
8650                try {
8651                    conn = (ContentProviderConnection)connection;
8652                } catch (ClassCastException e) {
8653                    String msg ="removeContentProvider: " + connection
8654                            + " not a ContentProviderConnection";
8655                    Slog.w(TAG, msg);
8656                    throw new IllegalArgumentException(msg);
8657                }
8658                if (conn == null) {
8659                    throw new NullPointerException("connection is null");
8660                }
8661                if (decProviderCountLocked(conn, null, null, stable)) {
8662                    updateOomAdjLocked();
8663                }
8664            }
8665        } finally {
8666            Binder.restoreCallingIdentity(ident);
8667        }
8668    }
8669
8670    public void removeContentProviderExternal(String name, IBinder token) {
8671        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8672            "Do not have permission in call removeContentProviderExternal()");
8673        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8674    }
8675
8676    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8677        synchronized (this) {
8678            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8679            if(cpr == null) {
8680                //remove from mProvidersByClass
8681                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8682                return;
8683            }
8684
8685            //update content provider record entry info
8686            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8687            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8688            if (localCpr.hasExternalProcessHandles()) {
8689                if (localCpr.removeExternalProcessHandleLocked(token)) {
8690                    updateOomAdjLocked();
8691                } else {
8692                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8693                            + " with no external reference for token: "
8694                            + token + ".");
8695                }
8696            } else {
8697                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8698                        + " with no external references.");
8699            }
8700        }
8701    }
8702
8703    public final void publishContentProviders(IApplicationThread caller,
8704            List<ContentProviderHolder> providers) {
8705        if (providers == null) {
8706            return;
8707        }
8708
8709        enforceNotIsolatedCaller("publishContentProviders");
8710        synchronized (this) {
8711            final ProcessRecord r = getRecordForAppLocked(caller);
8712            if (DEBUG_MU)
8713                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8714            if (r == null) {
8715                throw new SecurityException(
8716                        "Unable to find app for caller " + caller
8717                      + " (pid=" + Binder.getCallingPid()
8718                      + ") when publishing content providers");
8719            }
8720
8721            final long origId = Binder.clearCallingIdentity();
8722
8723            final int N = providers.size();
8724            for (int i=0; i<N; i++) {
8725                ContentProviderHolder src = providers.get(i);
8726                if (src == null || src.info == null || src.provider == null) {
8727                    continue;
8728                }
8729                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8730                if (DEBUG_MU)
8731                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8732                if (dst != null) {
8733                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8734                    mProviderMap.putProviderByClass(comp, dst);
8735                    String names[] = dst.info.authority.split(";");
8736                    for (int j = 0; j < names.length; j++) {
8737                        mProviderMap.putProviderByName(names[j], dst);
8738                    }
8739
8740                    int NL = mLaunchingProviders.size();
8741                    int j;
8742                    for (j=0; j<NL; j++) {
8743                        if (mLaunchingProviders.get(j) == dst) {
8744                            mLaunchingProviders.remove(j);
8745                            j--;
8746                            NL--;
8747                        }
8748                    }
8749                    synchronized (dst) {
8750                        dst.provider = src.provider;
8751                        dst.proc = r;
8752                        dst.notifyAll();
8753                    }
8754                    updateOomAdjLocked(r);
8755                }
8756            }
8757
8758            Binder.restoreCallingIdentity(origId);
8759        }
8760    }
8761
8762    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8763        ContentProviderConnection conn;
8764        try {
8765            conn = (ContentProviderConnection)connection;
8766        } catch (ClassCastException e) {
8767            String msg ="refContentProvider: " + connection
8768                    + " not a ContentProviderConnection";
8769            Slog.w(TAG, msg);
8770            throw new IllegalArgumentException(msg);
8771        }
8772        if (conn == null) {
8773            throw new NullPointerException("connection is null");
8774        }
8775
8776        synchronized (this) {
8777            if (stable > 0) {
8778                conn.numStableIncs += stable;
8779            }
8780            stable = conn.stableCount + stable;
8781            if (stable < 0) {
8782                throw new IllegalStateException("stableCount < 0: " + stable);
8783            }
8784
8785            if (unstable > 0) {
8786                conn.numUnstableIncs += unstable;
8787            }
8788            unstable = conn.unstableCount + unstable;
8789            if (unstable < 0) {
8790                throw new IllegalStateException("unstableCount < 0: " + unstable);
8791            }
8792
8793            if ((stable+unstable) <= 0) {
8794                throw new IllegalStateException("ref counts can't go to zero here: stable="
8795                        + stable + " unstable=" + unstable);
8796            }
8797            conn.stableCount = stable;
8798            conn.unstableCount = unstable;
8799            return !conn.dead;
8800        }
8801    }
8802
8803    public void unstableProviderDied(IBinder connection) {
8804        ContentProviderConnection conn;
8805        try {
8806            conn = (ContentProviderConnection)connection;
8807        } catch (ClassCastException e) {
8808            String msg ="refContentProvider: " + connection
8809                    + " not a ContentProviderConnection";
8810            Slog.w(TAG, msg);
8811            throw new IllegalArgumentException(msg);
8812        }
8813        if (conn == null) {
8814            throw new NullPointerException("connection is null");
8815        }
8816
8817        // Safely retrieve the content provider associated with the connection.
8818        IContentProvider provider;
8819        synchronized (this) {
8820            provider = conn.provider.provider;
8821        }
8822
8823        if (provider == null) {
8824            // Um, yeah, we're way ahead of you.
8825            return;
8826        }
8827
8828        // Make sure the caller is being honest with us.
8829        if (provider.asBinder().pingBinder()) {
8830            // Er, no, still looks good to us.
8831            synchronized (this) {
8832                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8833                        + " says " + conn + " died, but we don't agree");
8834                return;
8835            }
8836        }
8837
8838        // Well look at that!  It's dead!
8839        synchronized (this) {
8840            if (conn.provider.provider != provider) {
8841                // But something changed...  good enough.
8842                return;
8843            }
8844
8845            ProcessRecord proc = conn.provider.proc;
8846            if (proc == null || proc.thread == null) {
8847                // Seems like the process is already cleaned up.
8848                return;
8849            }
8850
8851            // As far as we're concerned, this is just like receiving a
8852            // death notification...  just a bit prematurely.
8853            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8854                    + ") early provider death");
8855            final long ident = Binder.clearCallingIdentity();
8856            try {
8857                appDiedLocked(proc, proc.pid, proc.thread);
8858            } finally {
8859                Binder.restoreCallingIdentity(ident);
8860            }
8861        }
8862    }
8863
8864    @Override
8865    public void appNotRespondingViaProvider(IBinder connection) {
8866        enforceCallingPermission(
8867                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8868
8869        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8870        if (conn == null) {
8871            Slog.w(TAG, "ContentProviderConnection is null");
8872            return;
8873        }
8874
8875        final ProcessRecord host = conn.provider.proc;
8876        if (host == null) {
8877            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8878            return;
8879        }
8880
8881        final long token = Binder.clearCallingIdentity();
8882        try {
8883            appNotResponding(host, null, null, false, "ContentProvider not responding");
8884        } finally {
8885            Binder.restoreCallingIdentity(token);
8886        }
8887    }
8888
8889    public final void installSystemProviders() {
8890        List<ProviderInfo> providers;
8891        synchronized (this) {
8892            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8893            providers = generateApplicationProvidersLocked(app);
8894            if (providers != null) {
8895                for (int i=providers.size()-1; i>=0; i--) {
8896                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8897                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8898                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8899                                + ": not system .apk");
8900                        providers.remove(i);
8901                    }
8902                }
8903            }
8904        }
8905        if (providers != null) {
8906            mSystemThread.installSystemProviders(providers);
8907        }
8908
8909        mCoreSettingsObserver = new CoreSettingsObserver(this);
8910
8911        //mUsageStatsService.monitorPackages();
8912    }
8913
8914    /**
8915     * Allows app to retrieve the MIME type of a URI without having permission
8916     * to access its content provider.
8917     *
8918     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8919     *
8920     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8921     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8922     */
8923    public String getProviderMimeType(Uri uri, int userId) {
8924        enforceNotIsolatedCaller("getProviderMimeType");
8925        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8926                userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null);
8927        final String name = uri.getAuthority();
8928        final long ident = Binder.clearCallingIdentity();
8929        ContentProviderHolder holder = null;
8930
8931        try {
8932            holder = getContentProviderExternalUnchecked(name, null, userId);
8933            if (holder != null) {
8934                return holder.provider.getType(uri);
8935            }
8936        } catch (RemoteException e) {
8937            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8938            return null;
8939        } finally {
8940            if (holder != null) {
8941                removeContentProviderExternalUnchecked(name, null, userId);
8942            }
8943            Binder.restoreCallingIdentity(ident);
8944        }
8945
8946        return null;
8947    }
8948
8949    // =========================================================
8950    // GLOBAL MANAGEMENT
8951    // =========================================================
8952
8953    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8954            boolean isolated) {
8955        String proc = customProcess != null ? customProcess : info.processName;
8956        BatteryStatsImpl.Uid.Proc ps = null;
8957        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8958        int uid = info.uid;
8959        if (isolated) {
8960            int userId = UserHandle.getUserId(uid);
8961            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8962            while (true) {
8963                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8964                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8965                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8966                }
8967                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8968                mNextIsolatedProcessUid++;
8969                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8970                    // No process for this uid, use it.
8971                    break;
8972                }
8973                stepsLeft--;
8974                if (stepsLeft <= 0) {
8975                    return null;
8976                }
8977            }
8978        }
8979        return new ProcessRecord(stats, info, proc, uid);
8980    }
8981
8982    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8983            String abiOverride) {
8984        ProcessRecord app;
8985        if (!isolated) {
8986            app = getProcessRecordLocked(info.processName, info.uid, true);
8987        } else {
8988            app = null;
8989        }
8990
8991        if (app == null) {
8992            app = newProcessRecordLocked(info, null, isolated);
8993            mProcessNames.put(info.processName, app.uid, app);
8994            if (isolated) {
8995                mIsolatedProcesses.put(app.uid, app);
8996            }
8997            updateLruProcessLocked(app, false, null);
8998            updateOomAdjLocked();
8999        }
9000
9001        // This package really, really can not be stopped.
9002        try {
9003            AppGlobals.getPackageManager().setPackageStoppedState(
9004                    info.packageName, false, UserHandle.getUserId(app.uid));
9005        } catch (RemoteException e) {
9006        } catch (IllegalArgumentException e) {
9007            Slog.w(TAG, "Failed trying to unstop package "
9008                    + info.packageName + ": " + e);
9009        }
9010
9011        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9012                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9013            app.persistent = true;
9014            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9015        }
9016        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9017            mPersistentStartingProcesses.add(app);
9018            startProcessLocked(app, "added application", app.processName,
9019                    abiOverride);
9020        }
9021
9022        return app;
9023    }
9024
9025    public void unhandledBack() {
9026        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9027                "unhandledBack()");
9028
9029        synchronized(this) {
9030            final long origId = Binder.clearCallingIdentity();
9031            try {
9032                getFocusedStack().unhandledBackLocked();
9033            } finally {
9034                Binder.restoreCallingIdentity(origId);
9035            }
9036        }
9037    }
9038
9039    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9040        enforceNotIsolatedCaller("openContentUri");
9041        final int userId = UserHandle.getCallingUserId();
9042        String name = uri.getAuthority();
9043        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9044        ParcelFileDescriptor pfd = null;
9045        if (cph != null) {
9046            // We record the binder invoker's uid in thread-local storage before
9047            // going to the content provider to open the file.  Later, in the code
9048            // that handles all permissions checks, we look for this uid and use
9049            // that rather than the Activity Manager's own uid.  The effect is that
9050            // we do the check against the caller's permissions even though it looks
9051            // to the content provider like the Activity Manager itself is making
9052            // the request.
9053            sCallerIdentity.set(new Identity(
9054                    Binder.getCallingPid(), Binder.getCallingUid()));
9055            try {
9056                pfd = cph.provider.openFile(null, uri, "r", null);
9057            } catch (FileNotFoundException e) {
9058                // do nothing; pfd will be returned null
9059            } finally {
9060                // Ensure that whatever happens, we clean up the identity state
9061                sCallerIdentity.remove();
9062            }
9063
9064            // We've got the fd now, so we're done with the provider.
9065            removeContentProviderExternalUnchecked(name, null, userId);
9066        } else {
9067            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9068        }
9069        return pfd;
9070    }
9071
9072    // Actually is sleeping or shutting down or whatever else in the future
9073    // is an inactive state.
9074    public boolean isSleepingOrShuttingDown() {
9075        return mSleeping || mShuttingDown;
9076    }
9077
9078    public boolean isSleeping() {
9079        return mSleeping;
9080    }
9081
9082    void goingToSleep() {
9083        synchronized(this) {
9084            mWentToSleep = true;
9085            updateEventDispatchingLocked();
9086            goToSleepIfNeededLocked();
9087        }
9088    }
9089
9090    void finishRunningVoiceLocked() {
9091        if (mRunningVoice) {
9092            mRunningVoice = false;
9093            goToSleepIfNeededLocked();
9094        }
9095    }
9096
9097    void goToSleepIfNeededLocked() {
9098        if (mWentToSleep && !mRunningVoice) {
9099            if (!mSleeping) {
9100                mSleeping = true;
9101                mStackSupervisor.goingToSleepLocked();
9102
9103                // Initialize the wake times of all processes.
9104                checkExcessivePowerUsageLocked(false);
9105                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9106                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9107                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9108            }
9109        }
9110    }
9111
9112    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9113        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9114            // Never persist the home stack.
9115            return;
9116        }
9117        mTaskPersister.wakeup(task, flush);
9118    }
9119
9120    @Override
9121    public boolean shutdown(int timeout) {
9122        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9123                != PackageManager.PERMISSION_GRANTED) {
9124            throw new SecurityException("Requires permission "
9125                    + android.Manifest.permission.SHUTDOWN);
9126        }
9127
9128        boolean timedout = false;
9129
9130        synchronized(this) {
9131            mShuttingDown = true;
9132            updateEventDispatchingLocked();
9133            timedout = mStackSupervisor.shutdownLocked(timeout);
9134        }
9135
9136        mAppOpsService.shutdown();
9137        if (mUsageStatsService != null) {
9138            mUsageStatsService.prepareShutdown();
9139        }
9140        mBatteryStatsService.shutdown();
9141        synchronized (this) {
9142            mProcessStats.shutdownLocked();
9143        }
9144        notifyTaskPersisterLocked(null, true);
9145
9146        return timedout;
9147    }
9148
9149    public final void activitySlept(IBinder token) {
9150        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9151
9152        final long origId = Binder.clearCallingIdentity();
9153
9154        synchronized (this) {
9155            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9156            if (r != null) {
9157                mStackSupervisor.activitySleptLocked(r);
9158            }
9159        }
9160
9161        Binder.restoreCallingIdentity(origId);
9162    }
9163
9164    void logLockScreen(String msg) {
9165        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9166                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9167                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9168                mStackSupervisor.mDismissKeyguardOnNextActivity);
9169    }
9170
9171    private void comeOutOfSleepIfNeededLocked() {
9172        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9173            if (mSleeping) {
9174                mSleeping = false;
9175                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9176            }
9177        }
9178    }
9179
9180    void wakingUp() {
9181        synchronized(this) {
9182            mWentToSleep = false;
9183            updateEventDispatchingLocked();
9184            comeOutOfSleepIfNeededLocked();
9185        }
9186    }
9187
9188    void startRunningVoiceLocked() {
9189        if (!mRunningVoice) {
9190            mRunningVoice = true;
9191            comeOutOfSleepIfNeededLocked();
9192        }
9193    }
9194
9195    private void updateEventDispatchingLocked() {
9196        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9197    }
9198
9199    public void setLockScreenShown(boolean shown) {
9200        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9201                != PackageManager.PERMISSION_GRANTED) {
9202            throw new SecurityException("Requires permission "
9203                    + android.Manifest.permission.DEVICE_POWER);
9204        }
9205
9206        synchronized(this) {
9207            long ident = Binder.clearCallingIdentity();
9208            try {
9209                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9210                mLockScreenShown = shown;
9211                comeOutOfSleepIfNeededLocked();
9212            } finally {
9213                Binder.restoreCallingIdentity(ident);
9214            }
9215        }
9216    }
9217
9218    @Override
9219    public void stopAppSwitches() {
9220        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9221                != PackageManager.PERMISSION_GRANTED) {
9222            throw new SecurityException("Requires permission "
9223                    + android.Manifest.permission.STOP_APP_SWITCHES);
9224        }
9225
9226        synchronized(this) {
9227            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9228                    + APP_SWITCH_DELAY_TIME;
9229            mDidAppSwitch = false;
9230            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9231            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9232            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9233        }
9234    }
9235
9236    public void resumeAppSwitches() {
9237        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9238                != PackageManager.PERMISSION_GRANTED) {
9239            throw new SecurityException("Requires permission "
9240                    + android.Manifest.permission.STOP_APP_SWITCHES);
9241        }
9242
9243        synchronized(this) {
9244            // Note that we don't execute any pending app switches... we will
9245            // let those wait until either the timeout, or the next start
9246            // activity request.
9247            mAppSwitchesAllowedTime = 0;
9248        }
9249    }
9250
9251    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9252            String name) {
9253        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9254            return true;
9255        }
9256
9257        final int perm = checkComponentPermission(
9258                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9259                callingUid, -1, true);
9260        if (perm == PackageManager.PERMISSION_GRANTED) {
9261            return true;
9262        }
9263
9264        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9265        return false;
9266    }
9267
9268    public void setDebugApp(String packageName, boolean waitForDebugger,
9269            boolean persistent) {
9270        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9271                "setDebugApp()");
9272
9273        long ident = Binder.clearCallingIdentity();
9274        try {
9275            // Note that this is not really thread safe if there are multiple
9276            // callers into it at the same time, but that's not a situation we
9277            // care about.
9278            if (persistent) {
9279                final ContentResolver resolver = mContext.getContentResolver();
9280                Settings.Global.putString(
9281                    resolver, Settings.Global.DEBUG_APP,
9282                    packageName);
9283                Settings.Global.putInt(
9284                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9285                    waitForDebugger ? 1 : 0);
9286            }
9287
9288            synchronized (this) {
9289                if (!persistent) {
9290                    mOrigDebugApp = mDebugApp;
9291                    mOrigWaitForDebugger = mWaitForDebugger;
9292                }
9293                mDebugApp = packageName;
9294                mWaitForDebugger = waitForDebugger;
9295                mDebugTransient = !persistent;
9296                if (packageName != null) {
9297                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9298                            false, UserHandle.USER_ALL, "set debug app");
9299                }
9300            }
9301        } finally {
9302            Binder.restoreCallingIdentity(ident);
9303        }
9304    }
9305
9306    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9307        synchronized (this) {
9308            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9309            if (!isDebuggable) {
9310                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9311                    throw new SecurityException("Process not debuggable: " + app.packageName);
9312                }
9313            }
9314
9315            mOpenGlTraceApp = processName;
9316        }
9317    }
9318
9319    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9320            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9321        synchronized (this) {
9322            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9323            if (!isDebuggable) {
9324                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9325                    throw new SecurityException("Process not debuggable: " + app.packageName);
9326                }
9327            }
9328            mProfileApp = processName;
9329            mProfileFile = profileFile;
9330            if (mProfileFd != null) {
9331                try {
9332                    mProfileFd.close();
9333                } catch (IOException e) {
9334                }
9335                mProfileFd = null;
9336            }
9337            mProfileFd = profileFd;
9338            mProfileType = 0;
9339            mAutoStopProfiler = autoStopProfiler;
9340        }
9341    }
9342
9343    @Override
9344    public void setAlwaysFinish(boolean enabled) {
9345        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9346                "setAlwaysFinish()");
9347
9348        Settings.Global.putInt(
9349                mContext.getContentResolver(),
9350                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9351
9352        synchronized (this) {
9353            mAlwaysFinishActivities = enabled;
9354        }
9355    }
9356
9357    @Override
9358    public void setActivityController(IActivityController controller) {
9359        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9360                "setActivityController()");
9361        synchronized (this) {
9362            mController = controller;
9363            Watchdog.getInstance().setActivityController(controller);
9364        }
9365    }
9366
9367    @Override
9368    public void setUserIsMonkey(boolean userIsMonkey) {
9369        synchronized (this) {
9370            synchronized (mPidsSelfLocked) {
9371                final int callingPid = Binder.getCallingPid();
9372                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9373                if (precessRecord == null) {
9374                    throw new SecurityException("Unknown process: " + callingPid);
9375                }
9376                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9377                    throw new SecurityException("Only an instrumentation process "
9378                            + "with a UiAutomation can call setUserIsMonkey");
9379                }
9380            }
9381            mUserIsMonkey = userIsMonkey;
9382        }
9383    }
9384
9385    @Override
9386    public boolean isUserAMonkey() {
9387        synchronized (this) {
9388            // If there is a controller also implies the user is a monkey.
9389            return (mUserIsMonkey || mController != null);
9390        }
9391    }
9392
9393    public void requestBugReport() {
9394        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9395        SystemProperties.set("ctl.start", "bugreport");
9396    }
9397
9398    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9399        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9400    }
9401
9402    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9403        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9404            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9405        }
9406        return KEY_DISPATCHING_TIMEOUT;
9407    }
9408
9409    @Override
9410    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9411        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9412                != PackageManager.PERMISSION_GRANTED) {
9413            throw new SecurityException("Requires permission "
9414                    + android.Manifest.permission.FILTER_EVENTS);
9415        }
9416        ProcessRecord proc;
9417        long timeout;
9418        synchronized (this) {
9419            synchronized (mPidsSelfLocked) {
9420                proc = mPidsSelfLocked.get(pid);
9421            }
9422            timeout = getInputDispatchingTimeoutLocked(proc);
9423        }
9424
9425        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9426            return -1;
9427        }
9428
9429        return timeout;
9430    }
9431
9432    /**
9433     * Handle input dispatching timeouts.
9434     * Returns whether input dispatching should be aborted or not.
9435     */
9436    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9437            final ActivityRecord activity, final ActivityRecord parent,
9438            final boolean aboveSystem, String reason) {
9439        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9440                != PackageManager.PERMISSION_GRANTED) {
9441            throw new SecurityException("Requires permission "
9442                    + android.Manifest.permission.FILTER_EVENTS);
9443        }
9444
9445        final String annotation;
9446        if (reason == null) {
9447            annotation = "Input dispatching timed out";
9448        } else {
9449            annotation = "Input dispatching timed out (" + reason + ")";
9450        }
9451
9452        if (proc != null) {
9453            synchronized (this) {
9454                if (proc.debugging) {
9455                    return false;
9456                }
9457
9458                if (mDidDexOpt) {
9459                    // Give more time since we were dexopting.
9460                    mDidDexOpt = false;
9461                    return false;
9462                }
9463
9464                if (proc.instrumentationClass != null) {
9465                    Bundle info = new Bundle();
9466                    info.putString("shortMsg", "keyDispatchingTimedOut");
9467                    info.putString("longMsg", annotation);
9468                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9469                    return true;
9470                }
9471            }
9472            mHandler.post(new Runnable() {
9473                @Override
9474                public void run() {
9475                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9476                }
9477            });
9478        }
9479
9480        return true;
9481    }
9482
9483    public Bundle getAssistContextExtras(int requestType) {
9484        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9485                "getAssistContextExtras()");
9486        PendingAssistExtras pae;
9487        Bundle extras = new Bundle();
9488        synchronized (this) {
9489            ActivityRecord activity = getFocusedStack().mResumedActivity;
9490            if (activity == null) {
9491                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9492                return null;
9493            }
9494            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9495            if (activity.app == null || activity.app.thread == null) {
9496                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9497                return extras;
9498            }
9499            if (activity.app.pid == Binder.getCallingPid()) {
9500                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9501                return extras;
9502            }
9503            pae = new PendingAssistExtras(activity);
9504            try {
9505                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9506                        requestType);
9507                mPendingAssistExtras.add(pae);
9508                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9509            } catch (RemoteException e) {
9510                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9511                return extras;
9512            }
9513        }
9514        synchronized (pae) {
9515            while (!pae.haveResult) {
9516                try {
9517                    pae.wait();
9518                } catch (InterruptedException e) {
9519                }
9520            }
9521            if (pae.result != null) {
9522                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9523            }
9524        }
9525        synchronized (this) {
9526            mPendingAssistExtras.remove(pae);
9527            mHandler.removeCallbacks(pae);
9528        }
9529        return extras;
9530    }
9531
9532    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9533        PendingAssistExtras pae = (PendingAssistExtras)token;
9534        synchronized (pae) {
9535            pae.result = extras;
9536            pae.haveResult = true;
9537            pae.notifyAll();
9538        }
9539    }
9540
9541    public void registerProcessObserver(IProcessObserver observer) {
9542        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9543                "registerProcessObserver()");
9544        synchronized (this) {
9545            mProcessObservers.register(observer);
9546        }
9547    }
9548
9549    @Override
9550    public void unregisterProcessObserver(IProcessObserver observer) {
9551        synchronized (this) {
9552            mProcessObservers.unregister(observer);
9553        }
9554    }
9555
9556    @Override
9557    public boolean convertFromTranslucent(IBinder token) {
9558        final long origId = Binder.clearCallingIdentity();
9559        try {
9560            synchronized (this) {
9561                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9562                if (r == null) {
9563                    return false;
9564                }
9565                if (r.changeWindowTranslucency(true)) {
9566                    mWindowManager.setAppFullscreen(token, true);
9567                    r.task.stack.releaseMediaResources();
9568                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9569                    return true;
9570                }
9571                return false;
9572            }
9573        } finally {
9574            Binder.restoreCallingIdentity(origId);
9575        }
9576    }
9577
9578    @Override
9579    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9580        final long origId = Binder.clearCallingIdentity();
9581        try {
9582            synchronized (this) {
9583                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9584                if (r == null) {
9585                    return false;
9586                }
9587                int index = r.task.mActivities.lastIndexOf(r);
9588                if (index > 0) {
9589                    ActivityRecord under = r.task.mActivities.get(index - 1);
9590                    under.returningOptions = options;
9591                }
9592                if (r.changeWindowTranslucency(false)) {
9593                    r.task.stack.convertToTranslucent(r);
9594                    mWindowManager.setAppFullscreen(token, false);
9595                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9596                    return true;
9597                } else {
9598                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9599                    return false;
9600                }
9601            }
9602        } finally {
9603            Binder.restoreCallingIdentity(origId);
9604        }
9605    }
9606
9607    @Override
9608    public boolean setMediaPlaying(IBinder token, boolean playing) {
9609        final long origId = Binder.clearCallingIdentity();
9610        try {
9611            synchronized (this) {
9612                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9613                if (r != null) {
9614                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9615                }
9616            }
9617            return false;
9618        } finally {
9619            Binder.restoreCallingIdentity(origId);
9620        }
9621    }
9622
9623    @Override
9624    public boolean isBackgroundMediaPlaying(IBinder token) {
9625        final long origId = Binder.clearCallingIdentity();
9626        try {
9627            synchronized (this) {
9628                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9629                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9630                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9631                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9632                return playing;
9633            }
9634        } finally {
9635            Binder.restoreCallingIdentity(origId);
9636        }
9637    }
9638
9639    @Override
9640    public ActivityOptions getActivityOptions(IBinder token) {
9641        final long origId = Binder.clearCallingIdentity();
9642        try {
9643            synchronized (this) {
9644                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9645                if (r != null) {
9646                    final ActivityOptions activityOptions = r.pendingOptions;
9647                    r.pendingOptions = null;
9648                    return activityOptions;
9649                }
9650                return null;
9651            }
9652        } finally {
9653            Binder.restoreCallingIdentity(origId);
9654        }
9655    }
9656
9657    @Override
9658    public void setImmersive(IBinder token, boolean immersive) {
9659        synchronized(this) {
9660            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9661            if (r == null) {
9662                throw new IllegalArgumentException();
9663            }
9664            r.immersive = immersive;
9665
9666            // update associated state if we're frontmost
9667            if (r == mFocusedActivity) {
9668                if (DEBUG_IMMERSIVE) {
9669                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9670                }
9671                applyUpdateLockStateLocked(r);
9672            }
9673        }
9674    }
9675
9676    @Override
9677    public boolean isImmersive(IBinder token) {
9678        synchronized (this) {
9679            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9680            if (r == null) {
9681                throw new IllegalArgumentException();
9682            }
9683            return r.immersive;
9684        }
9685    }
9686
9687    public boolean isTopActivityImmersive() {
9688        enforceNotIsolatedCaller("startActivity");
9689        synchronized (this) {
9690            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9691            return (r != null) ? r.immersive : false;
9692        }
9693    }
9694
9695    @Override
9696    public boolean isTopOfTask(IBinder token) {
9697        synchronized (this) {
9698            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9699            if (r == null) {
9700                throw new IllegalArgumentException();
9701            }
9702            return r.task.getTopActivity() == r;
9703        }
9704    }
9705
9706    public final void enterSafeMode() {
9707        synchronized(this) {
9708            // It only makes sense to do this before the system is ready
9709            // and started launching other packages.
9710            if (!mSystemReady) {
9711                try {
9712                    AppGlobals.getPackageManager().enterSafeMode();
9713                } catch (RemoteException e) {
9714                }
9715            }
9716
9717            mSafeMode = true;
9718        }
9719    }
9720
9721    public final void showSafeModeOverlay() {
9722        View v = LayoutInflater.from(mContext).inflate(
9723                com.android.internal.R.layout.safe_mode, null);
9724        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9725        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9726        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9727        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9728        lp.gravity = Gravity.BOTTOM | Gravity.START;
9729        lp.format = v.getBackground().getOpacity();
9730        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9731                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9732        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9733        ((WindowManager)mContext.getSystemService(
9734                Context.WINDOW_SERVICE)).addView(v, lp);
9735    }
9736
9737    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9738        if (!(sender instanceof PendingIntentRecord)) {
9739            return;
9740        }
9741        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9742        synchronized (stats) {
9743            if (mBatteryStatsService.isOnBattery()) {
9744                mBatteryStatsService.enforceCallingPermission();
9745                PendingIntentRecord rec = (PendingIntentRecord)sender;
9746                int MY_UID = Binder.getCallingUid();
9747                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9748                BatteryStatsImpl.Uid.Pkg pkg =
9749                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9750                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9751                pkg.incWakeupsLocked();
9752            }
9753        }
9754    }
9755
9756    public boolean killPids(int[] pids, String pReason, boolean secure) {
9757        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9758            throw new SecurityException("killPids only available to the system");
9759        }
9760        String reason = (pReason == null) ? "Unknown" : pReason;
9761        // XXX Note: don't acquire main activity lock here, because the window
9762        // manager calls in with its locks held.
9763
9764        boolean killed = false;
9765        synchronized (mPidsSelfLocked) {
9766            int[] types = new int[pids.length];
9767            int worstType = 0;
9768            for (int i=0; i<pids.length; i++) {
9769                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9770                if (proc != null) {
9771                    int type = proc.setAdj;
9772                    types[i] = type;
9773                    if (type > worstType) {
9774                        worstType = type;
9775                    }
9776                }
9777            }
9778
9779            // If the worst oom_adj is somewhere in the cached proc LRU range,
9780            // then constrain it so we will kill all cached procs.
9781            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9782                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9783                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9784            }
9785
9786            // If this is not a secure call, don't let it kill processes that
9787            // are important.
9788            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9789                worstType = ProcessList.SERVICE_ADJ;
9790            }
9791
9792            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9793            for (int i=0; i<pids.length; i++) {
9794                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9795                if (proc == null) {
9796                    continue;
9797                }
9798                int adj = proc.setAdj;
9799                if (adj >= worstType && !proc.killedByAm) {
9800                    killUnneededProcessLocked(proc, reason);
9801                    killed = true;
9802                }
9803            }
9804        }
9805        return killed;
9806    }
9807
9808    @Override
9809    public void killUid(int uid, String reason) {
9810        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9811            throw new SecurityException("killUid only available to the system");
9812        }
9813        synchronized (this) {
9814            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9815                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9816                    reason != null ? reason : "kill uid");
9817        }
9818    }
9819
9820    @Override
9821    public boolean killProcessesBelowForeground(String reason) {
9822        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9823            throw new SecurityException("killProcessesBelowForeground() only available to system");
9824        }
9825
9826        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9827    }
9828
9829    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9830        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9831            throw new SecurityException("killProcessesBelowAdj() only available to system");
9832        }
9833
9834        boolean killed = false;
9835        synchronized (mPidsSelfLocked) {
9836            final int size = mPidsSelfLocked.size();
9837            for (int i = 0; i < size; i++) {
9838                final int pid = mPidsSelfLocked.keyAt(i);
9839                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9840                if (proc == null) continue;
9841
9842                final int adj = proc.setAdj;
9843                if (adj > belowAdj && !proc.killedByAm) {
9844                    killUnneededProcessLocked(proc, reason);
9845                    killed = true;
9846                }
9847            }
9848        }
9849        return killed;
9850    }
9851
9852    @Override
9853    public void hang(final IBinder who, boolean allowRestart) {
9854        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9855                != PackageManager.PERMISSION_GRANTED) {
9856            throw new SecurityException("Requires permission "
9857                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9858        }
9859
9860        final IBinder.DeathRecipient death = new DeathRecipient() {
9861            @Override
9862            public void binderDied() {
9863                synchronized (this) {
9864                    notifyAll();
9865                }
9866            }
9867        };
9868
9869        try {
9870            who.linkToDeath(death, 0);
9871        } catch (RemoteException e) {
9872            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9873            return;
9874        }
9875
9876        synchronized (this) {
9877            Watchdog.getInstance().setAllowRestart(allowRestart);
9878            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9879            synchronized (death) {
9880                while (who.isBinderAlive()) {
9881                    try {
9882                        death.wait();
9883                    } catch (InterruptedException e) {
9884                    }
9885                }
9886            }
9887            Watchdog.getInstance().setAllowRestart(true);
9888        }
9889    }
9890
9891    @Override
9892    public void restart() {
9893        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9894                != PackageManager.PERMISSION_GRANTED) {
9895            throw new SecurityException("Requires permission "
9896                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9897        }
9898
9899        Log.i(TAG, "Sending shutdown broadcast...");
9900
9901        BroadcastReceiver br = new BroadcastReceiver() {
9902            @Override public void onReceive(Context context, Intent intent) {
9903                // Now the broadcast is done, finish up the low-level shutdown.
9904                Log.i(TAG, "Shutting down activity manager...");
9905                shutdown(10000);
9906                Log.i(TAG, "Shutdown complete, restarting!");
9907                Process.killProcess(Process.myPid());
9908                System.exit(10);
9909            }
9910        };
9911
9912        // First send the high-level shut down broadcast.
9913        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9914        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9915        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9916        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9917        mContext.sendOrderedBroadcastAsUser(intent,
9918                UserHandle.ALL, null, br, mHandler, 0, null, null);
9919        */
9920        br.onReceive(mContext, intent);
9921    }
9922
9923    private long getLowRamTimeSinceIdle(long now) {
9924        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9925    }
9926
9927    @Override
9928    public void performIdleMaintenance() {
9929        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9930                != PackageManager.PERMISSION_GRANTED) {
9931            throw new SecurityException("Requires permission "
9932                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9933        }
9934
9935        synchronized (this) {
9936            final long now = SystemClock.uptimeMillis();
9937            final long timeSinceLastIdle = now - mLastIdleTime;
9938            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9939            mLastIdleTime = now;
9940            mLowRamTimeSinceLastIdle = 0;
9941            if (mLowRamStartTime != 0) {
9942                mLowRamStartTime = now;
9943            }
9944
9945            StringBuilder sb = new StringBuilder(128);
9946            sb.append("Idle maintenance over ");
9947            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9948            sb.append(" low RAM for ");
9949            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9950            Slog.i(TAG, sb.toString());
9951
9952            // If at least 1/3 of our time since the last idle period has been spent
9953            // with RAM low, then we want to kill processes.
9954            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9955
9956            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9957                ProcessRecord proc = mLruProcesses.get(i);
9958                if (proc.notCachedSinceIdle) {
9959                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9960                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9961                        if (doKilling && proc.initialIdlePss != 0
9962                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9963                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9964                                    + " from " + proc.initialIdlePss + ")");
9965                        }
9966                    }
9967                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9968                    proc.notCachedSinceIdle = true;
9969                    proc.initialIdlePss = 0;
9970                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9971                            isSleeping(), now);
9972                }
9973            }
9974
9975            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9976            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9977        }
9978    }
9979
9980    private void retrieveSettings() {
9981        final ContentResolver resolver = mContext.getContentResolver();
9982        String debugApp = Settings.Global.getString(
9983            resolver, Settings.Global.DEBUG_APP);
9984        boolean waitForDebugger = Settings.Global.getInt(
9985            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9986        boolean alwaysFinishActivities = Settings.Global.getInt(
9987            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9988        boolean forceRtl = Settings.Global.getInt(
9989                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9990        // Transfer any global setting for forcing RTL layout, into a System Property
9991        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9992
9993        Configuration configuration = new Configuration();
9994        Settings.System.getConfiguration(resolver, configuration);
9995        if (forceRtl) {
9996            // This will take care of setting the correct layout direction flags
9997            configuration.setLayoutDirection(configuration.locale);
9998        }
9999
10000        synchronized (this) {
10001            mDebugApp = mOrigDebugApp = debugApp;
10002            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10003            mAlwaysFinishActivities = alwaysFinishActivities;
10004            // This happens before any activities are started, so we can
10005            // change mConfiguration in-place.
10006            updateConfigurationLocked(configuration, null, false, true);
10007            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10008        }
10009    }
10010
10011    public boolean testIsSystemReady() {
10012        // no need to synchronize(this) just to read & return the value
10013        return mSystemReady;
10014    }
10015
10016    private static File getCalledPreBootReceiversFile() {
10017        File dataDir = Environment.getDataDirectory();
10018        File systemDir = new File(dataDir, "system");
10019        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10020        return fname;
10021    }
10022
10023    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10024        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10025        File file = getCalledPreBootReceiversFile();
10026        FileInputStream fis = null;
10027        try {
10028            fis = new FileInputStream(file);
10029            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10030            int fvers = dis.readInt();
10031            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10032                String vers = dis.readUTF();
10033                String codename = dis.readUTF();
10034                String build = dis.readUTF();
10035                if (android.os.Build.VERSION.RELEASE.equals(vers)
10036                        && android.os.Build.VERSION.CODENAME.equals(codename)
10037                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10038                    int num = dis.readInt();
10039                    while (num > 0) {
10040                        num--;
10041                        String pkg = dis.readUTF();
10042                        String cls = dis.readUTF();
10043                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10044                    }
10045                }
10046            }
10047        } catch (FileNotFoundException e) {
10048        } catch (IOException e) {
10049            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10050        } finally {
10051            if (fis != null) {
10052                try {
10053                    fis.close();
10054                } catch (IOException e) {
10055                }
10056            }
10057        }
10058        return lastDoneReceivers;
10059    }
10060
10061    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10062        File file = getCalledPreBootReceiversFile();
10063        FileOutputStream fos = null;
10064        DataOutputStream dos = null;
10065        try {
10066            fos = new FileOutputStream(file);
10067            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10068            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10069            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10070            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10071            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10072            dos.writeInt(list.size());
10073            for (int i=0; i<list.size(); i++) {
10074                dos.writeUTF(list.get(i).getPackageName());
10075                dos.writeUTF(list.get(i).getClassName());
10076            }
10077        } catch (IOException e) {
10078            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10079            file.delete();
10080        } finally {
10081            FileUtils.sync(fos);
10082            if (dos != null) {
10083                try {
10084                    dos.close();
10085                } catch (IOException e) {
10086                    // TODO Auto-generated catch block
10087                    e.printStackTrace();
10088                }
10089            }
10090        }
10091    }
10092
10093    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10094            ArrayList<ComponentName> doneReceivers, int userId) {
10095        boolean waitingUpdate = false;
10096        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10097        List<ResolveInfo> ris = null;
10098        try {
10099            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10100                    intent, null, 0, userId);
10101        } catch (RemoteException e) {
10102        }
10103        if (ris != null) {
10104            for (int i=ris.size()-1; i>=0; i--) {
10105                if ((ris.get(i).activityInfo.applicationInfo.flags
10106                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10107                    ris.remove(i);
10108                }
10109            }
10110            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10111
10112            // For User 0, load the version number. When delivering to a new user, deliver
10113            // to all receivers.
10114            if (userId == UserHandle.USER_OWNER) {
10115                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10116                for (int i=0; i<ris.size(); i++) {
10117                    ActivityInfo ai = ris.get(i).activityInfo;
10118                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10119                    if (lastDoneReceivers.contains(comp)) {
10120                        // We already did the pre boot receiver for this app with the current
10121                        // platform version, so don't do it again...
10122                        ris.remove(i);
10123                        i--;
10124                        // ...however, do keep it as one that has been done, so we don't
10125                        // forget about it when rewriting the file of last done receivers.
10126                        doneReceivers.add(comp);
10127                    }
10128                }
10129            }
10130
10131            // If primary user, send broadcast to all available users, else just to userId
10132            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10133                    : new int[] { userId };
10134            for (int i = 0; i < ris.size(); i++) {
10135                ActivityInfo ai = ris.get(i).activityInfo;
10136                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10137                doneReceivers.add(comp);
10138                intent.setComponent(comp);
10139                for (int j=0; j<users.length; j++) {
10140                    IIntentReceiver finisher = null;
10141                    // On last receiver and user, set up a completion callback
10142                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10143                        finisher = new IIntentReceiver.Stub() {
10144                            public void performReceive(Intent intent, int resultCode,
10145                                    String data, Bundle extras, boolean ordered,
10146                                    boolean sticky, int sendingUser) {
10147                                // The raw IIntentReceiver interface is called
10148                                // with the AM lock held, so redispatch to
10149                                // execute our code without the lock.
10150                                mHandler.post(onFinishCallback);
10151                            }
10152                        };
10153                    }
10154                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10155                            + " for user " + users[j]);
10156                    broadcastIntentLocked(null, null, intent, null, finisher,
10157                            0, null, null, null, AppOpsManager.OP_NONE,
10158                            true, false, MY_PID, Process.SYSTEM_UID,
10159                            users[j]);
10160                    if (finisher != null) {
10161                        waitingUpdate = true;
10162                    }
10163                }
10164            }
10165        }
10166
10167        return waitingUpdate;
10168    }
10169
10170    public void systemReady(final Runnable goingCallback) {
10171        synchronized(this) {
10172            if (mSystemReady) {
10173                // If we're done calling all the receivers, run the next "boot phase" passed in
10174                // by the SystemServer
10175                if (goingCallback != null) {
10176                    goingCallback.run();
10177                }
10178                return;
10179            }
10180
10181            // Make sure we have the current profile info, since it is needed for
10182            // security checks.
10183            updateCurrentProfileIdsLocked();
10184
10185            if (mRecentTasks == null) {
10186                mRecentTasks = mTaskPersister.restoreTasksLocked();
10187                if (!mRecentTasks.isEmpty()) {
10188                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10189                }
10190                mTaskPersister.startPersisting();
10191            }
10192
10193            // Check to see if there are any update receivers to run.
10194            if (!mDidUpdate) {
10195                if (mWaitingUpdate) {
10196                    return;
10197                }
10198                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10199                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10200                    public void run() {
10201                        synchronized (ActivityManagerService.this) {
10202                            mDidUpdate = true;
10203                        }
10204                        writeLastDonePreBootReceivers(doneReceivers);
10205                        showBootMessage(mContext.getText(
10206                                R.string.android_upgrading_complete),
10207                                false);
10208                        systemReady(goingCallback);
10209                    }
10210                }, doneReceivers, UserHandle.USER_OWNER);
10211
10212                if (mWaitingUpdate) {
10213                    return;
10214                }
10215                mDidUpdate = true;
10216            }
10217
10218            mAppOpsService.systemReady();
10219            mSystemReady = true;
10220        }
10221
10222        ArrayList<ProcessRecord> procsToKill = null;
10223        synchronized(mPidsSelfLocked) {
10224            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10225                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10226                if (!isAllowedWhileBooting(proc.info)){
10227                    if (procsToKill == null) {
10228                        procsToKill = new ArrayList<ProcessRecord>();
10229                    }
10230                    procsToKill.add(proc);
10231                }
10232            }
10233        }
10234
10235        synchronized(this) {
10236            if (procsToKill != null) {
10237                for (int i=procsToKill.size()-1; i>=0; i--) {
10238                    ProcessRecord proc = procsToKill.get(i);
10239                    Slog.i(TAG, "Removing system update proc: " + proc);
10240                    removeProcessLocked(proc, true, false, "system update done");
10241                }
10242            }
10243
10244            // Now that we have cleaned up any update processes, we
10245            // are ready to start launching real processes and know that
10246            // we won't trample on them any more.
10247            mProcessesReady = true;
10248        }
10249
10250        Slog.i(TAG, "System now ready");
10251        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10252            SystemClock.uptimeMillis());
10253
10254        synchronized(this) {
10255            // Make sure we have no pre-ready processes sitting around.
10256
10257            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10258                ResolveInfo ri = mContext.getPackageManager()
10259                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10260                                STOCK_PM_FLAGS);
10261                CharSequence errorMsg = null;
10262                if (ri != null) {
10263                    ActivityInfo ai = ri.activityInfo;
10264                    ApplicationInfo app = ai.applicationInfo;
10265                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10266                        mTopAction = Intent.ACTION_FACTORY_TEST;
10267                        mTopData = null;
10268                        mTopComponent = new ComponentName(app.packageName,
10269                                ai.name);
10270                    } else {
10271                        errorMsg = mContext.getResources().getText(
10272                                com.android.internal.R.string.factorytest_not_system);
10273                    }
10274                } else {
10275                    errorMsg = mContext.getResources().getText(
10276                            com.android.internal.R.string.factorytest_no_action);
10277                }
10278                if (errorMsg != null) {
10279                    mTopAction = null;
10280                    mTopData = null;
10281                    mTopComponent = null;
10282                    Message msg = Message.obtain();
10283                    msg.what = SHOW_FACTORY_ERROR_MSG;
10284                    msg.getData().putCharSequence("msg", errorMsg);
10285                    mHandler.sendMessage(msg);
10286                }
10287            }
10288        }
10289
10290        retrieveSettings();
10291
10292        synchronized (this) {
10293            readGrantedUriPermissionsLocked();
10294        }
10295
10296        if (goingCallback != null) goingCallback.run();
10297
10298        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10299                Integer.toString(mCurrentUserId), mCurrentUserId);
10300        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10301                Integer.toString(mCurrentUserId), mCurrentUserId);
10302        mSystemServiceManager.startUser(mCurrentUserId);
10303
10304        synchronized (this) {
10305            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10306                try {
10307                    List apps = AppGlobals.getPackageManager().
10308                        getPersistentApplications(STOCK_PM_FLAGS);
10309                    if (apps != null) {
10310                        int N = apps.size();
10311                        int i;
10312                        for (i=0; i<N; i++) {
10313                            ApplicationInfo info
10314                                = (ApplicationInfo)apps.get(i);
10315                            if (info != null &&
10316                                    !info.packageName.equals("android")) {
10317                                addAppLocked(info, false, null /* ABI override */);
10318                            }
10319                        }
10320                    }
10321                } catch (RemoteException ex) {
10322                    // pm is in same process, this will never happen.
10323                }
10324            }
10325
10326            // Start up initial activity.
10327            mBooting = true;
10328
10329            try {
10330                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10331                    Message msg = Message.obtain();
10332                    msg.what = SHOW_UID_ERROR_MSG;
10333                    mHandler.sendMessage(msg);
10334                }
10335            } catch (RemoteException e) {
10336            }
10337
10338            long ident = Binder.clearCallingIdentity();
10339            try {
10340                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10341                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10342                        | Intent.FLAG_RECEIVER_FOREGROUND);
10343                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10344                broadcastIntentLocked(null, null, intent,
10345                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10346                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10347                intent = new Intent(Intent.ACTION_USER_STARTING);
10348                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10349                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10350                broadcastIntentLocked(null, null, intent,
10351                        null, new IIntentReceiver.Stub() {
10352                            @Override
10353                            public void performReceive(Intent intent, int resultCode, String data,
10354                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10355                                    throws RemoteException {
10356                            }
10357                        }, 0, null, null,
10358                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10359                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10360            } catch (Throwable t) {
10361                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10362            } finally {
10363                Binder.restoreCallingIdentity(ident);
10364            }
10365            mStackSupervisor.resumeTopActivitiesLocked();
10366            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10367        }
10368    }
10369
10370    private boolean makeAppCrashingLocked(ProcessRecord app,
10371            String shortMsg, String longMsg, String stackTrace) {
10372        app.crashing = true;
10373        app.crashingReport = generateProcessError(app,
10374                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10375        startAppProblemLocked(app);
10376        app.stopFreezingAllLocked();
10377        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10378    }
10379
10380    private void makeAppNotRespondingLocked(ProcessRecord app,
10381            String activity, String shortMsg, String longMsg) {
10382        app.notResponding = true;
10383        app.notRespondingReport = generateProcessError(app,
10384                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10385                activity, shortMsg, longMsg, null);
10386        startAppProblemLocked(app);
10387        app.stopFreezingAllLocked();
10388    }
10389
10390    /**
10391     * Generate a process error record, suitable for attachment to a ProcessRecord.
10392     *
10393     * @param app The ProcessRecord in which the error occurred.
10394     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10395     *                      ActivityManager.AppErrorStateInfo
10396     * @param activity The activity associated with the crash, if known.
10397     * @param shortMsg Short message describing the crash.
10398     * @param longMsg Long message describing the crash.
10399     * @param stackTrace Full crash stack trace, may be null.
10400     *
10401     * @return Returns a fully-formed AppErrorStateInfo record.
10402     */
10403    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10404            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10405        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10406
10407        report.condition = condition;
10408        report.processName = app.processName;
10409        report.pid = app.pid;
10410        report.uid = app.info.uid;
10411        report.tag = activity;
10412        report.shortMsg = shortMsg;
10413        report.longMsg = longMsg;
10414        report.stackTrace = stackTrace;
10415
10416        return report;
10417    }
10418
10419    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10420        synchronized (this) {
10421            app.crashing = false;
10422            app.crashingReport = null;
10423            app.notResponding = false;
10424            app.notRespondingReport = null;
10425            if (app.anrDialog == fromDialog) {
10426                app.anrDialog = null;
10427            }
10428            if (app.waitDialog == fromDialog) {
10429                app.waitDialog = null;
10430            }
10431            if (app.pid > 0 && app.pid != MY_PID) {
10432                handleAppCrashLocked(app, null, null, null);
10433                killUnneededProcessLocked(app, "user request after error");
10434            }
10435        }
10436    }
10437
10438    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10439            String stackTrace) {
10440        long now = SystemClock.uptimeMillis();
10441
10442        Long crashTime;
10443        if (!app.isolated) {
10444            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10445        } else {
10446            crashTime = null;
10447        }
10448        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10449            // This process loses!
10450            Slog.w(TAG, "Process " + app.info.processName
10451                    + " has crashed too many times: killing!");
10452            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10453                    app.userId, app.info.processName, app.uid);
10454            mStackSupervisor.handleAppCrashLocked(app);
10455            if (!app.persistent) {
10456                // We don't want to start this process again until the user
10457                // explicitly does so...  but for persistent process, we really
10458                // need to keep it running.  If a persistent process is actually
10459                // repeatedly crashing, then badness for everyone.
10460                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10461                        app.info.processName);
10462                if (!app.isolated) {
10463                    // XXX We don't have a way to mark isolated processes
10464                    // as bad, since they don't have a peristent identity.
10465                    mBadProcesses.put(app.info.processName, app.uid,
10466                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10467                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10468                }
10469                app.bad = true;
10470                app.removed = true;
10471                // Don't let services in this process be restarted and potentially
10472                // annoy the user repeatedly.  Unless it is persistent, since those
10473                // processes run critical code.
10474                removeProcessLocked(app, false, false, "crash");
10475                mStackSupervisor.resumeTopActivitiesLocked();
10476                return false;
10477            }
10478            mStackSupervisor.resumeTopActivitiesLocked();
10479        } else {
10480            mStackSupervisor.finishTopRunningActivityLocked(app);
10481        }
10482
10483        // Bump up the crash count of any services currently running in the proc.
10484        for (int i=app.services.size()-1; i>=0; i--) {
10485            // Any services running in the application need to be placed
10486            // back in the pending list.
10487            ServiceRecord sr = app.services.valueAt(i);
10488            sr.crashCount++;
10489        }
10490
10491        // If the crashing process is what we consider to be the "home process" and it has been
10492        // replaced by a third-party app, clear the package preferred activities from packages
10493        // with a home activity running in the process to prevent a repeatedly crashing app
10494        // from blocking the user to manually clear the list.
10495        final ArrayList<ActivityRecord> activities = app.activities;
10496        if (app == mHomeProcess && activities.size() > 0
10497                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10498            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10499                final ActivityRecord r = activities.get(activityNdx);
10500                if (r.isHomeActivity()) {
10501                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10502                    try {
10503                        ActivityThread.getPackageManager()
10504                                .clearPackagePreferredActivities(r.packageName);
10505                    } catch (RemoteException c) {
10506                        // pm is in same process, this will never happen.
10507                    }
10508                }
10509            }
10510        }
10511
10512        if (!app.isolated) {
10513            // XXX Can't keep track of crash times for isolated processes,
10514            // because they don't have a perisistent identity.
10515            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10516        }
10517
10518        return true;
10519    }
10520
10521    void startAppProblemLocked(ProcessRecord app) {
10522        if (app.userId == mCurrentUserId) {
10523            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10524                    mContext, app.info.packageName, app.info.flags);
10525        } else {
10526            // If this app is not running under the current user, then we
10527            // can't give it a report button because that would require
10528            // launching the report UI under a different user.
10529            app.errorReportReceiver = null;
10530        }
10531        skipCurrentReceiverLocked(app);
10532    }
10533
10534    void skipCurrentReceiverLocked(ProcessRecord app) {
10535        for (BroadcastQueue queue : mBroadcastQueues) {
10536            queue.skipCurrentReceiverLocked(app);
10537        }
10538    }
10539
10540    /**
10541     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10542     * The application process will exit immediately after this call returns.
10543     * @param app object of the crashing app, null for the system server
10544     * @param crashInfo describing the exception
10545     */
10546    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10547        ProcessRecord r = findAppProcess(app, "Crash");
10548        final String processName = app == null ? "system_server"
10549                : (r == null ? "unknown" : r.processName);
10550
10551        handleApplicationCrashInner("crash", r, processName, crashInfo);
10552    }
10553
10554    /* Native crash reporting uses this inner version because it needs to be somewhat
10555     * decoupled from the AM-managed cleanup lifecycle
10556     */
10557    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10558            ApplicationErrorReport.CrashInfo crashInfo) {
10559        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10560                UserHandle.getUserId(Binder.getCallingUid()), processName,
10561                r == null ? -1 : r.info.flags,
10562                crashInfo.exceptionClassName,
10563                crashInfo.exceptionMessage,
10564                crashInfo.throwFileName,
10565                crashInfo.throwLineNumber);
10566
10567        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10568
10569        crashApplication(r, crashInfo);
10570    }
10571
10572    public void handleApplicationStrictModeViolation(
10573            IBinder app,
10574            int violationMask,
10575            StrictMode.ViolationInfo info) {
10576        ProcessRecord r = findAppProcess(app, "StrictMode");
10577        if (r == null) {
10578            return;
10579        }
10580
10581        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10582            Integer stackFingerprint = info.hashCode();
10583            boolean logIt = true;
10584            synchronized (mAlreadyLoggedViolatedStacks) {
10585                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10586                    logIt = false;
10587                    // TODO: sub-sample into EventLog for these, with
10588                    // the info.durationMillis?  Then we'd get
10589                    // the relative pain numbers, without logging all
10590                    // the stack traces repeatedly.  We'd want to do
10591                    // likewise in the client code, which also does
10592                    // dup suppression, before the Binder call.
10593                } else {
10594                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10595                        mAlreadyLoggedViolatedStacks.clear();
10596                    }
10597                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10598                }
10599            }
10600            if (logIt) {
10601                logStrictModeViolationToDropBox(r, info);
10602            }
10603        }
10604
10605        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10606            AppErrorResult result = new AppErrorResult();
10607            synchronized (this) {
10608                final long origId = Binder.clearCallingIdentity();
10609
10610                Message msg = Message.obtain();
10611                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10612                HashMap<String, Object> data = new HashMap<String, Object>();
10613                data.put("result", result);
10614                data.put("app", r);
10615                data.put("violationMask", violationMask);
10616                data.put("info", info);
10617                msg.obj = data;
10618                mHandler.sendMessage(msg);
10619
10620                Binder.restoreCallingIdentity(origId);
10621            }
10622            int res = result.get();
10623            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10624        }
10625    }
10626
10627    // Depending on the policy in effect, there could be a bunch of
10628    // these in quick succession so we try to batch these together to
10629    // minimize disk writes, number of dropbox entries, and maximize
10630    // compression, by having more fewer, larger records.
10631    private void logStrictModeViolationToDropBox(
10632            ProcessRecord process,
10633            StrictMode.ViolationInfo info) {
10634        if (info == null) {
10635            return;
10636        }
10637        final boolean isSystemApp = process == null ||
10638                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10639                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10640        final String processName = process == null ? "unknown" : process.processName;
10641        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10642        final DropBoxManager dbox = (DropBoxManager)
10643                mContext.getSystemService(Context.DROPBOX_SERVICE);
10644
10645        // Exit early if the dropbox isn't configured to accept this report type.
10646        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10647
10648        boolean bufferWasEmpty;
10649        boolean needsFlush;
10650        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10651        synchronized (sb) {
10652            bufferWasEmpty = sb.length() == 0;
10653            appendDropBoxProcessHeaders(process, processName, sb);
10654            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10655            sb.append("System-App: ").append(isSystemApp).append("\n");
10656            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10657            if (info.violationNumThisLoop != 0) {
10658                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10659            }
10660            if (info.numAnimationsRunning != 0) {
10661                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10662            }
10663            if (info.broadcastIntentAction != null) {
10664                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10665            }
10666            if (info.durationMillis != -1) {
10667                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10668            }
10669            if (info.numInstances != -1) {
10670                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10671            }
10672            if (info.tags != null) {
10673                for (String tag : info.tags) {
10674                    sb.append("Span-Tag: ").append(tag).append("\n");
10675                }
10676            }
10677            sb.append("\n");
10678            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10679                sb.append(info.crashInfo.stackTrace);
10680            }
10681            sb.append("\n");
10682
10683            // Only buffer up to ~64k.  Various logging bits truncate
10684            // things at 128k.
10685            needsFlush = (sb.length() > 64 * 1024);
10686        }
10687
10688        // Flush immediately if the buffer's grown too large, or this
10689        // is a non-system app.  Non-system apps are isolated with a
10690        // different tag & policy and not batched.
10691        //
10692        // Batching is useful during internal testing with
10693        // StrictMode settings turned up high.  Without batching,
10694        // thousands of separate files could be created on boot.
10695        if (!isSystemApp || needsFlush) {
10696            new Thread("Error dump: " + dropboxTag) {
10697                @Override
10698                public void run() {
10699                    String report;
10700                    synchronized (sb) {
10701                        report = sb.toString();
10702                        sb.delete(0, sb.length());
10703                        sb.trimToSize();
10704                    }
10705                    if (report.length() != 0) {
10706                        dbox.addText(dropboxTag, report);
10707                    }
10708                }
10709            }.start();
10710            return;
10711        }
10712
10713        // System app batching:
10714        if (!bufferWasEmpty) {
10715            // An existing dropbox-writing thread is outstanding, so
10716            // we don't need to start it up.  The existing thread will
10717            // catch the buffer appends we just did.
10718            return;
10719        }
10720
10721        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10722        // (After this point, we shouldn't access AMS internal data structures.)
10723        new Thread("Error dump: " + dropboxTag) {
10724            @Override
10725            public void run() {
10726                // 5 second sleep to let stacks arrive and be batched together
10727                try {
10728                    Thread.sleep(5000);  // 5 seconds
10729                } catch (InterruptedException e) {}
10730
10731                String errorReport;
10732                synchronized (mStrictModeBuffer) {
10733                    errorReport = mStrictModeBuffer.toString();
10734                    if (errorReport.length() == 0) {
10735                        return;
10736                    }
10737                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10738                    mStrictModeBuffer.trimToSize();
10739                }
10740                dbox.addText(dropboxTag, errorReport);
10741            }
10742        }.start();
10743    }
10744
10745    /**
10746     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10747     * @param app object of the crashing app, null for the system server
10748     * @param tag reported by the caller
10749     * @param crashInfo describing the context of the error
10750     * @return true if the process should exit immediately (WTF is fatal)
10751     */
10752    public boolean handleApplicationWtf(IBinder app, String tag,
10753            ApplicationErrorReport.CrashInfo crashInfo) {
10754        ProcessRecord r = findAppProcess(app, "WTF");
10755        final String processName = app == null ? "system_server"
10756                : (r == null ? "unknown" : r.processName);
10757
10758        EventLog.writeEvent(EventLogTags.AM_WTF,
10759                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10760                processName,
10761                r == null ? -1 : r.info.flags,
10762                tag, crashInfo.exceptionMessage);
10763
10764        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10765
10766        if (r != null && r.pid != Process.myPid() &&
10767                Settings.Global.getInt(mContext.getContentResolver(),
10768                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10769            crashApplication(r, crashInfo);
10770            return true;
10771        } else {
10772            return false;
10773        }
10774    }
10775
10776    /**
10777     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10778     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10779     */
10780    private ProcessRecord findAppProcess(IBinder app, String reason) {
10781        if (app == null) {
10782            return null;
10783        }
10784
10785        synchronized (this) {
10786            final int NP = mProcessNames.getMap().size();
10787            for (int ip=0; ip<NP; ip++) {
10788                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10789                final int NA = apps.size();
10790                for (int ia=0; ia<NA; ia++) {
10791                    ProcessRecord p = apps.valueAt(ia);
10792                    if (p.thread != null && p.thread.asBinder() == app) {
10793                        return p;
10794                    }
10795                }
10796            }
10797
10798            Slog.w(TAG, "Can't find mystery application for " + reason
10799                    + " from pid=" + Binder.getCallingPid()
10800                    + " uid=" + Binder.getCallingUid() + ": " + app);
10801            return null;
10802        }
10803    }
10804
10805    /**
10806     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10807     * to append various headers to the dropbox log text.
10808     */
10809    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10810            StringBuilder sb) {
10811        // Watchdog thread ends up invoking this function (with
10812        // a null ProcessRecord) to add the stack file to dropbox.
10813        // Do not acquire a lock on this (am) in such cases, as it
10814        // could cause a potential deadlock, if and when watchdog
10815        // is invoked due to unavailability of lock on am and it
10816        // would prevent watchdog from killing system_server.
10817        if (process == null) {
10818            sb.append("Process: ").append(processName).append("\n");
10819            return;
10820        }
10821        // Note: ProcessRecord 'process' is guarded by the service
10822        // instance.  (notably process.pkgList, which could otherwise change
10823        // concurrently during execution of this method)
10824        synchronized (this) {
10825            sb.append("Process: ").append(processName).append("\n");
10826            int flags = process.info.flags;
10827            IPackageManager pm = AppGlobals.getPackageManager();
10828            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10829            for (int ip=0; ip<process.pkgList.size(); ip++) {
10830                String pkg = process.pkgList.keyAt(ip);
10831                sb.append("Package: ").append(pkg);
10832                try {
10833                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10834                    if (pi != null) {
10835                        sb.append(" v").append(pi.versionCode);
10836                        if (pi.versionName != null) {
10837                            sb.append(" (").append(pi.versionName).append(")");
10838                        }
10839                    }
10840                } catch (RemoteException e) {
10841                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10842                }
10843                sb.append("\n");
10844            }
10845        }
10846    }
10847
10848    private static String processClass(ProcessRecord process) {
10849        if (process == null || process.pid == MY_PID) {
10850            return "system_server";
10851        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10852            return "system_app";
10853        } else {
10854            return "data_app";
10855        }
10856    }
10857
10858    /**
10859     * Write a description of an error (crash, WTF, ANR) to the drop box.
10860     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10861     * @param process which caused the error, null means the system server
10862     * @param activity which triggered the error, null if unknown
10863     * @param parent activity related to the error, null if unknown
10864     * @param subject line related to the error, null if absent
10865     * @param report in long form describing the error, null if absent
10866     * @param logFile to include in the report, null if none
10867     * @param crashInfo giving an application stack trace, null if absent
10868     */
10869    public void addErrorToDropBox(String eventType,
10870            ProcessRecord process, String processName, ActivityRecord activity,
10871            ActivityRecord parent, String subject,
10872            final String report, final File logFile,
10873            final ApplicationErrorReport.CrashInfo crashInfo) {
10874        // NOTE -- this must never acquire the ActivityManagerService lock,
10875        // otherwise the watchdog may be prevented from resetting the system.
10876
10877        final String dropboxTag = processClass(process) + "_" + eventType;
10878        final DropBoxManager dbox = (DropBoxManager)
10879                mContext.getSystemService(Context.DROPBOX_SERVICE);
10880
10881        // Exit early if the dropbox isn't configured to accept this report type.
10882        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10883
10884        final StringBuilder sb = new StringBuilder(1024);
10885        appendDropBoxProcessHeaders(process, processName, sb);
10886        if (activity != null) {
10887            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10888        }
10889        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10890            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10891        }
10892        if (parent != null && parent != activity) {
10893            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10894        }
10895        if (subject != null) {
10896            sb.append("Subject: ").append(subject).append("\n");
10897        }
10898        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10899        if (Debug.isDebuggerConnected()) {
10900            sb.append("Debugger: Connected\n");
10901        }
10902        sb.append("\n");
10903
10904        // Do the rest in a worker thread to avoid blocking the caller on I/O
10905        // (After this point, we shouldn't access AMS internal data structures.)
10906        Thread worker = new Thread("Error dump: " + dropboxTag) {
10907            @Override
10908            public void run() {
10909                if (report != null) {
10910                    sb.append(report);
10911                }
10912                if (logFile != null) {
10913                    try {
10914                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10915                                    "\n\n[[TRUNCATED]]"));
10916                    } catch (IOException e) {
10917                        Slog.e(TAG, "Error reading " + logFile, e);
10918                    }
10919                }
10920                if (crashInfo != null && crashInfo.stackTrace != null) {
10921                    sb.append(crashInfo.stackTrace);
10922                }
10923
10924                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10925                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10926                if (lines > 0) {
10927                    sb.append("\n");
10928
10929                    // Merge several logcat streams, and take the last N lines
10930                    InputStreamReader input = null;
10931                    try {
10932                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10933                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10934                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10935
10936                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10937                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10938                        input = new InputStreamReader(logcat.getInputStream());
10939
10940                        int num;
10941                        char[] buf = new char[8192];
10942                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10943                    } catch (IOException e) {
10944                        Slog.e(TAG, "Error running logcat", e);
10945                    } finally {
10946                        if (input != null) try { input.close(); } catch (IOException e) {}
10947                    }
10948                }
10949
10950                dbox.addText(dropboxTag, sb.toString());
10951            }
10952        };
10953
10954        if (process == null) {
10955            // If process is null, we are being called from some internal code
10956            // and may be about to die -- run this synchronously.
10957            worker.run();
10958        } else {
10959            worker.start();
10960        }
10961    }
10962
10963    /**
10964     * Bring up the "unexpected error" dialog box for a crashing app.
10965     * Deal with edge cases (intercepts from instrumented applications,
10966     * ActivityController, error intent receivers, that sort of thing).
10967     * @param r the application crashing
10968     * @param crashInfo describing the failure
10969     */
10970    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10971        long timeMillis = System.currentTimeMillis();
10972        String shortMsg = crashInfo.exceptionClassName;
10973        String longMsg = crashInfo.exceptionMessage;
10974        String stackTrace = crashInfo.stackTrace;
10975        if (shortMsg != null && longMsg != null) {
10976            longMsg = shortMsg + ": " + longMsg;
10977        } else if (shortMsg != null) {
10978            longMsg = shortMsg;
10979        }
10980
10981        AppErrorResult result = new AppErrorResult();
10982        synchronized (this) {
10983            if (mController != null) {
10984                try {
10985                    String name = r != null ? r.processName : null;
10986                    int pid = r != null ? r.pid : Binder.getCallingPid();
10987                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
10988                    if (!mController.appCrashed(name, pid,
10989                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10990                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
10991                                && "Native crash".equals(crashInfo.exceptionClassName)) {
10992                            Slog.w(TAG, "Skip killing native crashed app " + name
10993                                    + "(" + pid + ") during testing");
10994                        } else {
10995                            Slog.w(TAG, "Force-killing crashed app " + name
10996                                    + " at watcher's request");
10997                            Process.killProcess(pid);
10998                            if (r != null) {
10999                                Process.killProcessGroup(uid, pid);
11000                            }
11001                        }
11002                        return;
11003                    }
11004                } catch (RemoteException e) {
11005                    mController = null;
11006                    Watchdog.getInstance().setActivityController(null);
11007                }
11008            }
11009
11010            final long origId = Binder.clearCallingIdentity();
11011
11012            // If this process is running instrumentation, finish it.
11013            if (r != null && r.instrumentationClass != null) {
11014                Slog.w(TAG, "Error in app " + r.processName
11015                      + " running instrumentation " + r.instrumentationClass + ":");
11016                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11017                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11018                Bundle info = new Bundle();
11019                info.putString("shortMsg", shortMsg);
11020                info.putString("longMsg", longMsg);
11021                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11022                Binder.restoreCallingIdentity(origId);
11023                return;
11024            }
11025
11026            // If we can't identify the process or it's already exceeded its crash quota,
11027            // quit right away without showing a crash dialog.
11028            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11029                Binder.restoreCallingIdentity(origId);
11030                return;
11031            }
11032
11033            Message msg = Message.obtain();
11034            msg.what = SHOW_ERROR_MSG;
11035            HashMap data = new HashMap();
11036            data.put("result", result);
11037            data.put("app", r);
11038            msg.obj = data;
11039            mHandler.sendMessage(msg);
11040
11041            Binder.restoreCallingIdentity(origId);
11042        }
11043
11044        int res = result.get();
11045
11046        Intent appErrorIntent = null;
11047        synchronized (this) {
11048            if (r != null && !r.isolated) {
11049                // XXX Can't keep track of crash time for isolated processes,
11050                // since they don't have a persistent identity.
11051                mProcessCrashTimes.put(r.info.processName, r.uid,
11052                        SystemClock.uptimeMillis());
11053            }
11054            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11055                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11056            }
11057        }
11058
11059        if (appErrorIntent != null) {
11060            try {
11061                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11062            } catch (ActivityNotFoundException e) {
11063                Slog.w(TAG, "bug report receiver dissappeared", e);
11064            }
11065        }
11066    }
11067
11068    Intent createAppErrorIntentLocked(ProcessRecord r,
11069            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11070        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11071        if (report == null) {
11072            return null;
11073        }
11074        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11075        result.setComponent(r.errorReportReceiver);
11076        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11077        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11078        return result;
11079    }
11080
11081    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11082            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11083        if (r.errorReportReceiver == null) {
11084            return null;
11085        }
11086
11087        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11088            return null;
11089        }
11090
11091        ApplicationErrorReport report = new ApplicationErrorReport();
11092        report.packageName = r.info.packageName;
11093        report.installerPackageName = r.errorReportReceiver.getPackageName();
11094        report.processName = r.processName;
11095        report.time = timeMillis;
11096        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11097
11098        if (r.crashing || r.forceCrashReport) {
11099            report.type = ApplicationErrorReport.TYPE_CRASH;
11100            report.crashInfo = crashInfo;
11101        } else if (r.notResponding) {
11102            report.type = ApplicationErrorReport.TYPE_ANR;
11103            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11104
11105            report.anrInfo.activity = r.notRespondingReport.tag;
11106            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11107            report.anrInfo.info = r.notRespondingReport.longMsg;
11108        }
11109
11110        return report;
11111    }
11112
11113    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11114        enforceNotIsolatedCaller("getProcessesInErrorState");
11115        // assume our apps are happy - lazy create the list
11116        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11117
11118        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11119                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11120        int userId = UserHandle.getUserId(Binder.getCallingUid());
11121
11122        synchronized (this) {
11123
11124            // iterate across all processes
11125            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11126                ProcessRecord app = mLruProcesses.get(i);
11127                if (!allUsers && app.userId != userId) {
11128                    continue;
11129                }
11130                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11131                    // This one's in trouble, so we'll generate a report for it
11132                    // crashes are higher priority (in case there's a crash *and* an anr)
11133                    ActivityManager.ProcessErrorStateInfo report = null;
11134                    if (app.crashing) {
11135                        report = app.crashingReport;
11136                    } else if (app.notResponding) {
11137                        report = app.notRespondingReport;
11138                    }
11139
11140                    if (report != null) {
11141                        if (errList == null) {
11142                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11143                        }
11144                        errList.add(report);
11145                    } else {
11146                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11147                                " crashing = " + app.crashing +
11148                                " notResponding = " + app.notResponding);
11149                    }
11150                }
11151            }
11152        }
11153
11154        return errList;
11155    }
11156
11157    static int procStateToImportance(int procState, int memAdj,
11158            ActivityManager.RunningAppProcessInfo currApp) {
11159        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11160        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11161            currApp.lru = memAdj;
11162        } else {
11163            currApp.lru = 0;
11164        }
11165        return imp;
11166    }
11167
11168    private void fillInProcMemInfo(ProcessRecord app,
11169            ActivityManager.RunningAppProcessInfo outInfo) {
11170        outInfo.pid = app.pid;
11171        outInfo.uid = app.info.uid;
11172        if (mHeavyWeightProcess == app) {
11173            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11174        }
11175        if (app.persistent) {
11176            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11177        }
11178        if (app.activities.size() > 0) {
11179            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11180        }
11181        outInfo.lastTrimLevel = app.trimMemoryLevel;
11182        int adj = app.curAdj;
11183        int procState = app.curProcState;
11184        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11185        outInfo.importanceReasonCode = app.adjTypeCode;
11186        outInfo.processState = app.curProcState;
11187    }
11188
11189    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11190        enforceNotIsolatedCaller("getRunningAppProcesses");
11191        // Lazy instantiation of list
11192        List<ActivityManager.RunningAppProcessInfo> runList = null;
11193        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11194                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11195        int userId = UserHandle.getUserId(Binder.getCallingUid());
11196        synchronized (this) {
11197            // Iterate across all processes
11198            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11199                ProcessRecord app = mLruProcesses.get(i);
11200                if (!allUsers && app.userId != userId) {
11201                    continue;
11202                }
11203                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11204                    // Generate process state info for running application
11205                    ActivityManager.RunningAppProcessInfo currApp =
11206                        new ActivityManager.RunningAppProcessInfo(app.processName,
11207                                app.pid, app.getPackageList());
11208                    fillInProcMemInfo(app, currApp);
11209                    if (app.adjSource instanceof ProcessRecord) {
11210                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11211                        currApp.importanceReasonImportance =
11212                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11213                                        app.adjSourceProcState);
11214                    } else if (app.adjSource instanceof ActivityRecord) {
11215                        ActivityRecord r = (ActivityRecord)app.adjSource;
11216                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11217                    }
11218                    if (app.adjTarget instanceof ComponentName) {
11219                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11220                    }
11221                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11222                    //        + " lru=" + currApp.lru);
11223                    if (runList == null) {
11224                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11225                    }
11226                    runList.add(currApp);
11227                }
11228            }
11229        }
11230        return runList;
11231    }
11232
11233    public List<ApplicationInfo> getRunningExternalApplications() {
11234        enforceNotIsolatedCaller("getRunningExternalApplications");
11235        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11236        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11237        if (runningApps != null && runningApps.size() > 0) {
11238            Set<String> extList = new HashSet<String>();
11239            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11240                if (app.pkgList != null) {
11241                    for (String pkg : app.pkgList) {
11242                        extList.add(pkg);
11243                    }
11244                }
11245            }
11246            IPackageManager pm = AppGlobals.getPackageManager();
11247            for (String pkg : extList) {
11248                try {
11249                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11250                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11251                        retList.add(info);
11252                    }
11253                } catch (RemoteException e) {
11254                }
11255            }
11256        }
11257        return retList;
11258    }
11259
11260    @Override
11261    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11262        enforceNotIsolatedCaller("getMyMemoryState");
11263        synchronized (this) {
11264            ProcessRecord proc;
11265            synchronized (mPidsSelfLocked) {
11266                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11267            }
11268            fillInProcMemInfo(proc, outInfo);
11269        }
11270    }
11271
11272    @Override
11273    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11274        if (checkCallingPermission(android.Manifest.permission.DUMP)
11275                != PackageManager.PERMISSION_GRANTED) {
11276            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11277                    + Binder.getCallingPid()
11278                    + ", uid=" + Binder.getCallingUid()
11279                    + " without permission "
11280                    + android.Manifest.permission.DUMP);
11281            return;
11282        }
11283
11284        boolean dumpAll = false;
11285        boolean dumpClient = false;
11286        String dumpPackage = null;
11287
11288        int opti = 0;
11289        while (opti < args.length) {
11290            String opt = args[opti];
11291            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11292                break;
11293            }
11294            opti++;
11295            if ("-a".equals(opt)) {
11296                dumpAll = true;
11297            } else if ("-c".equals(opt)) {
11298                dumpClient = true;
11299            } else if ("-h".equals(opt)) {
11300                pw.println("Activity manager dump options:");
11301                pw.println("  [-a] [-c] [-h] [cmd] ...");
11302                pw.println("  cmd may be one of:");
11303                pw.println("    a[ctivities]: activity stack state");
11304                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11305                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11306                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11307                pw.println("    o[om]: out of memory management");
11308                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11309                pw.println("    provider [COMP_SPEC]: provider client-side state");
11310                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11311                pw.println("    service [COMP_SPEC]: service client-side state");
11312                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11313                pw.println("    all: dump all activities");
11314                pw.println("    top: dump the top activity");
11315                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11316                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11317                pw.println("    a partial substring in a component name, a");
11318                pw.println("    hex object identifier.");
11319                pw.println("  -a: include all available server state.");
11320                pw.println("  -c: include client state.");
11321                return;
11322            } else {
11323                pw.println("Unknown argument: " + opt + "; use -h for help");
11324            }
11325        }
11326
11327        long origId = Binder.clearCallingIdentity();
11328        boolean more = false;
11329        // Is the caller requesting to dump a particular piece of data?
11330        if (opti < args.length) {
11331            String cmd = args[opti];
11332            opti++;
11333            if ("activities".equals(cmd) || "a".equals(cmd)) {
11334                synchronized (this) {
11335                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11336                }
11337            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11338                String[] newArgs;
11339                String name;
11340                if (opti >= args.length) {
11341                    name = null;
11342                    newArgs = EMPTY_STRING_ARRAY;
11343                } else {
11344                    name = args[opti];
11345                    opti++;
11346                    newArgs = new String[args.length - opti];
11347                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11348                            args.length - opti);
11349                }
11350                synchronized (this) {
11351                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11352                }
11353            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11354                String[] newArgs;
11355                String name;
11356                if (opti >= args.length) {
11357                    name = null;
11358                    newArgs = EMPTY_STRING_ARRAY;
11359                } else {
11360                    name = args[opti];
11361                    opti++;
11362                    newArgs = new String[args.length - opti];
11363                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11364                            args.length - opti);
11365                }
11366                synchronized (this) {
11367                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11368                }
11369            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11370                String[] newArgs;
11371                String name;
11372                if (opti >= args.length) {
11373                    name = null;
11374                    newArgs = EMPTY_STRING_ARRAY;
11375                } else {
11376                    name = args[opti];
11377                    opti++;
11378                    newArgs = new String[args.length - opti];
11379                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11380                            args.length - opti);
11381                }
11382                synchronized (this) {
11383                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11384                }
11385            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11386                synchronized (this) {
11387                    dumpOomLocked(fd, pw, args, opti, true);
11388                }
11389            } else if ("provider".equals(cmd)) {
11390                String[] newArgs;
11391                String name;
11392                if (opti >= args.length) {
11393                    name = null;
11394                    newArgs = EMPTY_STRING_ARRAY;
11395                } else {
11396                    name = args[opti];
11397                    opti++;
11398                    newArgs = new String[args.length - opti];
11399                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11400                }
11401                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11402                    pw.println("No providers match: " + name);
11403                    pw.println("Use -h for help.");
11404                }
11405            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11406                synchronized (this) {
11407                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11408                }
11409            } else if ("service".equals(cmd)) {
11410                String[] newArgs;
11411                String name;
11412                if (opti >= args.length) {
11413                    name = null;
11414                    newArgs = EMPTY_STRING_ARRAY;
11415                } else {
11416                    name = args[opti];
11417                    opti++;
11418                    newArgs = new String[args.length - opti];
11419                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11420                            args.length - opti);
11421                }
11422                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11423                    pw.println("No services match: " + name);
11424                    pw.println("Use -h for help.");
11425                }
11426            } else if ("package".equals(cmd)) {
11427                String[] newArgs;
11428                if (opti >= args.length) {
11429                    pw.println("package: no package name specified");
11430                    pw.println("Use -h for help.");
11431                } else {
11432                    dumpPackage = args[opti];
11433                    opti++;
11434                    newArgs = new String[args.length - opti];
11435                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11436                            args.length - opti);
11437                    args = newArgs;
11438                    opti = 0;
11439                    more = true;
11440                }
11441            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11442                synchronized (this) {
11443                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11444                }
11445            } else {
11446                // Dumping a single activity?
11447                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11448                    pw.println("Bad activity command, or no activities match: " + cmd);
11449                    pw.println("Use -h for help.");
11450                }
11451            }
11452            if (!more) {
11453                Binder.restoreCallingIdentity(origId);
11454                return;
11455            }
11456        }
11457
11458        // No piece of data specified, dump everything.
11459        synchronized (this) {
11460            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11461            pw.println();
11462            if (dumpAll) {
11463                pw.println("-------------------------------------------------------------------------------");
11464            }
11465            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11466            pw.println();
11467            if (dumpAll) {
11468                pw.println("-------------------------------------------------------------------------------");
11469            }
11470            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11471            pw.println();
11472            if (dumpAll) {
11473                pw.println("-------------------------------------------------------------------------------");
11474            }
11475            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11476            pw.println();
11477            if (dumpAll) {
11478                pw.println("-------------------------------------------------------------------------------");
11479            }
11480            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11481            pw.println();
11482            if (dumpAll) {
11483                pw.println("-------------------------------------------------------------------------------");
11484            }
11485            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11486        }
11487        Binder.restoreCallingIdentity(origId);
11488    }
11489
11490    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11491            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11492        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11493
11494        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11495                dumpPackage);
11496        boolean needSep = printedAnything;
11497
11498        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11499                dumpPackage, needSep, "  mFocusedActivity: ");
11500        if (printed) {
11501            printedAnything = true;
11502            needSep = false;
11503        }
11504
11505        if (dumpPackage == null) {
11506            if (needSep) {
11507                pw.println();
11508            }
11509            needSep = true;
11510            printedAnything = true;
11511            mStackSupervisor.dump(pw, "  ");
11512        }
11513
11514        if (mRecentTasks.size() > 0) {
11515            boolean printedHeader = false;
11516
11517            final int N = mRecentTasks.size();
11518            for (int i=0; i<N; i++) {
11519                TaskRecord tr = mRecentTasks.get(i);
11520                if (dumpPackage != null) {
11521                    if (tr.realActivity == null ||
11522                            !dumpPackage.equals(tr.realActivity)) {
11523                        continue;
11524                    }
11525                }
11526                if (!printedHeader) {
11527                    if (needSep) {
11528                        pw.println();
11529                    }
11530                    pw.println("  Recent tasks:");
11531                    printedHeader = true;
11532                    printedAnything = true;
11533                }
11534                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11535                        pw.println(tr);
11536                if (dumpAll) {
11537                    mRecentTasks.get(i).dump(pw, "    ");
11538                }
11539            }
11540        }
11541
11542        if (!printedAnything) {
11543            pw.println("  (nothing)");
11544        }
11545    }
11546
11547    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11548            int opti, boolean dumpAll, String dumpPackage) {
11549        boolean needSep = false;
11550        boolean printedAnything = false;
11551        int numPers = 0;
11552
11553        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11554
11555        if (dumpAll) {
11556            final int NP = mProcessNames.getMap().size();
11557            for (int ip=0; ip<NP; ip++) {
11558                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11559                final int NA = procs.size();
11560                for (int ia=0; ia<NA; ia++) {
11561                    ProcessRecord r = procs.valueAt(ia);
11562                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11563                        continue;
11564                    }
11565                    if (!needSep) {
11566                        pw.println("  All known processes:");
11567                        needSep = true;
11568                        printedAnything = true;
11569                    }
11570                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11571                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11572                        pw.print(" "); pw.println(r);
11573                    r.dump(pw, "    ");
11574                    if (r.persistent) {
11575                        numPers++;
11576                    }
11577                }
11578            }
11579        }
11580
11581        if (mIsolatedProcesses.size() > 0) {
11582            boolean printed = false;
11583            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11584                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11585                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11586                    continue;
11587                }
11588                if (!printed) {
11589                    if (needSep) {
11590                        pw.println();
11591                    }
11592                    pw.println("  Isolated process list (sorted by uid):");
11593                    printedAnything = true;
11594                    printed = true;
11595                    needSep = true;
11596                }
11597                pw.println(String.format("%sIsolated #%2d: %s",
11598                        "    ", i, r.toString()));
11599            }
11600        }
11601
11602        if (mLruProcesses.size() > 0) {
11603            if (needSep) {
11604                pw.println();
11605            }
11606            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11607                    pw.print(" total, non-act at ");
11608                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11609                    pw.print(", non-svc at ");
11610                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11611                    pw.println("):");
11612            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11613            needSep = true;
11614            printedAnything = true;
11615        }
11616
11617        if (dumpAll || dumpPackage != null) {
11618            synchronized (mPidsSelfLocked) {
11619                boolean printed = false;
11620                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11621                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11622                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11623                        continue;
11624                    }
11625                    if (!printed) {
11626                        if (needSep) pw.println();
11627                        needSep = true;
11628                        pw.println("  PID mappings:");
11629                        printed = true;
11630                        printedAnything = true;
11631                    }
11632                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11633                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11634                }
11635            }
11636        }
11637
11638        if (mForegroundProcesses.size() > 0) {
11639            synchronized (mPidsSelfLocked) {
11640                boolean printed = false;
11641                for (int i=0; i<mForegroundProcesses.size(); i++) {
11642                    ProcessRecord r = mPidsSelfLocked.get(
11643                            mForegroundProcesses.valueAt(i).pid);
11644                    if (dumpPackage != null && (r == null
11645                            || !r.pkgList.containsKey(dumpPackage))) {
11646                        continue;
11647                    }
11648                    if (!printed) {
11649                        if (needSep) pw.println();
11650                        needSep = true;
11651                        pw.println("  Foreground Processes:");
11652                        printed = true;
11653                        printedAnything = true;
11654                    }
11655                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11656                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11657                }
11658            }
11659        }
11660
11661        if (mPersistentStartingProcesses.size() > 0) {
11662            if (needSep) pw.println();
11663            needSep = true;
11664            printedAnything = true;
11665            pw.println("  Persisent processes that are starting:");
11666            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11667                    "Starting Norm", "Restarting PERS", dumpPackage);
11668        }
11669
11670        if (mRemovedProcesses.size() > 0) {
11671            if (needSep) pw.println();
11672            needSep = true;
11673            printedAnything = true;
11674            pw.println("  Processes that are being removed:");
11675            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11676                    "Removed Norm", "Removed PERS", dumpPackage);
11677        }
11678
11679        if (mProcessesOnHold.size() > 0) {
11680            if (needSep) pw.println();
11681            needSep = true;
11682            printedAnything = true;
11683            pw.println("  Processes that are on old until the system is ready:");
11684            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11685                    "OnHold Norm", "OnHold PERS", dumpPackage);
11686        }
11687
11688        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11689
11690        if (mProcessCrashTimes.getMap().size() > 0) {
11691            boolean printed = false;
11692            long now = SystemClock.uptimeMillis();
11693            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11694            final int NP = pmap.size();
11695            for (int ip=0; ip<NP; ip++) {
11696                String pname = pmap.keyAt(ip);
11697                SparseArray<Long> uids = pmap.valueAt(ip);
11698                final int N = uids.size();
11699                for (int i=0; i<N; i++) {
11700                    int puid = uids.keyAt(i);
11701                    ProcessRecord r = mProcessNames.get(pname, puid);
11702                    if (dumpPackage != null && (r == null
11703                            || !r.pkgList.containsKey(dumpPackage))) {
11704                        continue;
11705                    }
11706                    if (!printed) {
11707                        if (needSep) pw.println();
11708                        needSep = true;
11709                        pw.println("  Time since processes crashed:");
11710                        printed = true;
11711                        printedAnything = true;
11712                    }
11713                    pw.print("    Process "); pw.print(pname);
11714                            pw.print(" uid "); pw.print(puid);
11715                            pw.print(": last crashed ");
11716                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11717                            pw.println(" ago");
11718                }
11719            }
11720        }
11721
11722        if (mBadProcesses.getMap().size() > 0) {
11723            boolean printed = false;
11724            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11725            final int NP = pmap.size();
11726            for (int ip=0; ip<NP; ip++) {
11727                String pname = pmap.keyAt(ip);
11728                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11729                final int N = uids.size();
11730                for (int i=0; i<N; i++) {
11731                    int puid = uids.keyAt(i);
11732                    ProcessRecord r = mProcessNames.get(pname, puid);
11733                    if (dumpPackage != null && (r == null
11734                            || !r.pkgList.containsKey(dumpPackage))) {
11735                        continue;
11736                    }
11737                    if (!printed) {
11738                        if (needSep) pw.println();
11739                        needSep = true;
11740                        pw.println("  Bad processes:");
11741                        printedAnything = true;
11742                    }
11743                    BadProcessInfo info = uids.valueAt(i);
11744                    pw.print("    Bad process "); pw.print(pname);
11745                            pw.print(" uid "); pw.print(puid);
11746                            pw.print(": crashed at time "); pw.println(info.time);
11747                    if (info.shortMsg != null) {
11748                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11749                    }
11750                    if (info.longMsg != null) {
11751                        pw.print("      Long msg: "); pw.println(info.longMsg);
11752                    }
11753                    if (info.stack != null) {
11754                        pw.println("      Stack:");
11755                        int lastPos = 0;
11756                        for (int pos=0; pos<info.stack.length(); pos++) {
11757                            if (info.stack.charAt(pos) == '\n') {
11758                                pw.print("        ");
11759                                pw.write(info.stack, lastPos, pos-lastPos);
11760                                pw.println();
11761                                lastPos = pos+1;
11762                            }
11763                        }
11764                        if (lastPos < info.stack.length()) {
11765                            pw.print("        ");
11766                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11767                            pw.println();
11768                        }
11769                    }
11770                }
11771            }
11772        }
11773
11774        if (dumpPackage == null) {
11775            pw.println();
11776            needSep = false;
11777            pw.println("  mStartedUsers:");
11778            for (int i=0; i<mStartedUsers.size(); i++) {
11779                UserStartedState uss = mStartedUsers.valueAt(i);
11780                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11781                        pw.print(": "); uss.dump("", pw);
11782            }
11783            pw.print("  mStartedUserArray: [");
11784            for (int i=0; i<mStartedUserArray.length; i++) {
11785                if (i > 0) pw.print(", ");
11786                pw.print(mStartedUserArray[i]);
11787            }
11788            pw.println("]");
11789            pw.print("  mUserLru: [");
11790            for (int i=0; i<mUserLru.size(); i++) {
11791                if (i > 0) pw.print(", ");
11792                pw.print(mUserLru.get(i));
11793            }
11794            pw.println("]");
11795            if (dumpAll) {
11796                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11797            }
11798            synchronized (mUserProfileGroupIdsSelfLocked) {
11799                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11800                    pw.println("  mUserProfileGroupIds:");
11801                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11802                        pw.print("    User #");
11803                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11804                        pw.print(" -> profile #");
11805                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11806                    }
11807                }
11808            }
11809        }
11810        if (mHomeProcess != null && (dumpPackage == null
11811                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11812            if (needSep) {
11813                pw.println();
11814                needSep = false;
11815            }
11816            pw.println("  mHomeProcess: " + mHomeProcess);
11817        }
11818        if (mPreviousProcess != null && (dumpPackage == null
11819                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11820            if (needSep) {
11821                pw.println();
11822                needSep = false;
11823            }
11824            pw.println("  mPreviousProcess: " + mPreviousProcess);
11825        }
11826        if (dumpAll) {
11827            StringBuilder sb = new StringBuilder(128);
11828            sb.append("  mPreviousProcessVisibleTime: ");
11829            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11830            pw.println(sb);
11831        }
11832        if (mHeavyWeightProcess != null && (dumpPackage == null
11833                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11834            if (needSep) {
11835                pw.println();
11836                needSep = false;
11837            }
11838            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11839        }
11840        if (dumpPackage == null) {
11841            pw.println("  mConfiguration: " + mConfiguration);
11842        }
11843        if (dumpAll) {
11844            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11845            if (mCompatModePackages.getPackages().size() > 0) {
11846                boolean printed = false;
11847                for (Map.Entry<String, Integer> entry
11848                        : mCompatModePackages.getPackages().entrySet()) {
11849                    String pkg = entry.getKey();
11850                    int mode = entry.getValue();
11851                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11852                        continue;
11853                    }
11854                    if (!printed) {
11855                        pw.println("  mScreenCompatPackages:");
11856                        printed = true;
11857                    }
11858                    pw.print("    "); pw.print(pkg); pw.print(": ");
11859                            pw.print(mode); pw.println();
11860                }
11861            }
11862        }
11863        if (dumpPackage == null) {
11864            if (mSleeping || mWentToSleep || mLockScreenShown) {
11865                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11866                        + " mLockScreenShown " + mLockScreenShown);
11867            }
11868            if (mShuttingDown || mRunningVoice) {
11869                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11870            }
11871        }
11872        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11873                || mOrigWaitForDebugger) {
11874            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11875                    || dumpPackage.equals(mOrigDebugApp)) {
11876                if (needSep) {
11877                    pw.println();
11878                    needSep = false;
11879                }
11880                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11881                        + " mDebugTransient=" + mDebugTransient
11882                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11883            }
11884        }
11885        if (mOpenGlTraceApp != null) {
11886            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11887                if (needSep) {
11888                    pw.println();
11889                    needSep = false;
11890                }
11891                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11892            }
11893        }
11894        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11895                || mProfileFd != null) {
11896            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11897                if (needSep) {
11898                    pw.println();
11899                    needSep = false;
11900                }
11901                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11902                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11903                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11904                        + mAutoStopProfiler);
11905            }
11906        }
11907        if (dumpPackage == null) {
11908            if (mAlwaysFinishActivities || mController != null) {
11909                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11910                        + " mController=" + mController);
11911            }
11912            if (dumpAll) {
11913                pw.println("  Total persistent processes: " + numPers);
11914                pw.println("  mProcessesReady=" + mProcessesReady
11915                        + " mSystemReady=" + mSystemReady);
11916                pw.println("  mBooting=" + mBooting
11917                        + " mBooted=" + mBooted
11918                        + " mFactoryTest=" + mFactoryTest);
11919                pw.print("  mLastPowerCheckRealtime=");
11920                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11921                        pw.println("");
11922                pw.print("  mLastPowerCheckUptime=");
11923                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11924                        pw.println("");
11925                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11926                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11927                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11928                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11929                        + " (" + mLruProcesses.size() + " total)"
11930                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11931                        + " mNumServiceProcs=" + mNumServiceProcs
11932                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11933                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11934                        + " mLastMemoryLevel" + mLastMemoryLevel
11935                        + " mLastNumProcesses" + mLastNumProcesses);
11936                long now = SystemClock.uptimeMillis();
11937                pw.print("  mLastIdleTime=");
11938                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11939                        pw.print(" mLowRamSinceLastIdle=");
11940                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11941                        pw.println();
11942            }
11943        }
11944
11945        if (!printedAnything) {
11946            pw.println("  (nothing)");
11947        }
11948    }
11949
11950    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11951            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11952        if (mProcessesToGc.size() > 0) {
11953            boolean printed = false;
11954            long now = SystemClock.uptimeMillis();
11955            for (int i=0; i<mProcessesToGc.size(); i++) {
11956                ProcessRecord proc = mProcessesToGc.get(i);
11957                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11958                    continue;
11959                }
11960                if (!printed) {
11961                    if (needSep) pw.println();
11962                    needSep = true;
11963                    pw.println("  Processes that are waiting to GC:");
11964                    printed = true;
11965                }
11966                pw.print("    Process "); pw.println(proc);
11967                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11968                        pw.print(", last gced=");
11969                        pw.print(now-proc.lastRequestedGc);
11970                        pw.print(" ms ago, last lowMem=");
11971                        pw.print(now-proc.lastLowMemory);
11972                        pw.println(" ms ago");
11973
11974            }
11975        }
11976        return needSep;
11977    }
11978
11979    void printOomLevel(PrintWriter pw, String name, int adj) {
11980        pw.print("    ");
11981        if (adj >= 0) {
11982            pw.print(' ');
11983            if (adj < 10) pw.print(' ');
11984        } else {
11985            if (adj > -10) pw.print(' ');
11986        }
11987        pw.print(adj);
11988        pw.print(": ");
11989        pw.print(name);
11990        pw.print(" (");
11991        pw.print(mProcessList.getMemLevel(adj)/1024);
11992        pw.println(" kB)");
11993    }
11994
11995    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11996            int opti, boolean dumpAll) {
11997        boolean needSep = false;
11998
11999        if (mLruProcesses.size() > 0) {
12000            if (needSep) pw.println();
12001            needSep = true;
12002            pw.println("  OOM levels:");
12003            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12004            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12005            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12006            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12007            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12008            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12009            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12010            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12011            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12012            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12013            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12014            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12015            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12016
12017            if (needSep) pw.println();
12018            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12019                    pw.print(" total, non-act at ");
12020                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12021                    pw.print(", non-svc at ");
12022                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12023                    pw.println("):");
12024            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12025            needSep = true;
12026        }
12027
12028        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12029
12030        pw.println();
12031        pw.println("  mHomeProcess: " + mHomeProcess);
12032        pw.println("  mPreviousProcess: " + mPreviousProcess);
12033        if (mHeavyWeightProcess != null) {
12034            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12035        }
12036
12037        return true;
12038    }
12039
12040    /**
12041     * There are three ways to call this:
12042     *  - no provider specified: dump all the providers
12043     *  - a flattened component name that matched an existing provider was specified as the
12044     *    first arg: dump that one provider
12045     *  - the first arg isn't the flattened component name of an existing provider:
12046     *    dump all providers whose component contains the first arg as a substring
12047     */
12048    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12049            int opti, boolean dumpAll) {
12050        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12051    }
12052
12053    static class ItemMatcher {
12054        ArrayList<ComponentName> components;
12055        ArrayList<String> strings;
12056        ArrayList<Integer> objects;
12057        boolean all;
12058
12059        ItemMatcher() {
12060            all = true;
12061        }
12062
12063        void build(String name) {
12064            ComponentName componentName = ComponentName.unflattenFromString(name);
12065            if (componentName != null) {
12066                if (components == null) {
12067                    components = new ArrayList<ComponentName>();
12068                }
12069                components.add(componentName);
12070                all = false;
12071            } else {
12072                int objectId = 0;
12073                // Not a '/' separated full component name; maybe an object ID?
12074                try {
12075                    objectId = Integer.parseInt(name, 16);
12076                    if (objects == null) {
12077                        objects = new ArrayList<Integer>();
12078                    }
12079                    objects.add(objectId);
12080                    all = false;
12081                } catch (RuntimeException e) {
12082                    // Not an integer; just do string match.
12083                    if (strings == null) {
12084                        strings = new ArrayList<String>();
12085                    }
12086                    strings.add(name);
12087                    all = false;
12088                }
12089            }
12090        }
12091
12092        int build(String[] args, int opti) {
12093            for (; opti<args.length; opti++) {
12094                String name = args[opti];
12095                if ("--".equals(name)) {
12096                    return opti+1;
12097                }
12098                build(name);
12099            }
12100            return opti;
12101        }
12102
12103        boolean match(Object object, ComponentName comp) {
12104            if (all) {
12105                return true;
12106            }
12107            if (components != null) {
12108                for (int i=0; i<components.size(); i++) {
12109                    if (components.get(i).equals(comp)) {
12110                        return true;
12111                    }
12112                }
12113            }
12114            if (objects != null) {
12115                for (int i=0; i<objects.size(); i++) {
12116                    if (System.identityHashCode(object) == objects.get(i)) {
12117                        return true;
12118                    }
12119                }
12120            }
12121            if (strings != null) {
12122                String flat = comp.flattenToString();
12123                for (int i=0; i<strings.size(); i++) {
12124                    if (flat.contains(strings.get(i))) {
12125                        return true;
12126                    }
12127                }
12128            }
12129            return false;
12130        }
12131    }
12132
12133    /**
12134     * There are three things that cmd can be:
12135     *  - a flattened component name that matches an existing activity
12136     *  - the cmd arg isn't the flattened component name of an existing activity:
12137     *    dump all activity whose component contains the cmd as a substring
12138     *  - A hex number of the ActivityRecord object instance.
12139     */
12140    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12141            int opti, boolean dumpAll) {
12142        ArrayList<ActivityRecord> activities;
12143
12144        synchronized (this) {
12145            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12146        }
12147
12148        if (activities.size() <= 0) {
12149            return false;
12150        }
12151
12152        String[] newArgs = new String[args.length - opti];
12153        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12154
12155        TaskRecord lastTask = null;
12156        boolean needSep = false;
12157        for (int i=activities.size()-1; i>=0; i--) {
12158            ActivityRecord r = activities.get(i);
12159            if (needSep) {
12160                pw.println();
12161            }
12162            needSep = true;
12163            synchronized (this) {
12164                if (lastTask != r.task) {
12165                    lastTask = r.task;
12166                    pw.print("TASK "); pw.print(lastTask.affinity);
12167                            pw.print(" id="); pw.println(lastTask.taskId);
12168                    if (dumpAll) {
12169                        lastTask.dump(pw, "  ");
12170                    }
12171                }
12172            }
12173            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12174        }
12175        return true;
12176    }
12177
12178    /**
12179     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12180     * there is a thread associated with the activity.
12181     */
12182    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12183            final ActivityRecord r, String[] args, boolean dumpAll) {
12184        String innerPrefix = prefix + "  ";
12185        synchronized (this) {
12186            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12187                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12188                    pw.print(" pid=");
12189                    if (r.app != null) pw.println(r.app.pid);
12190                    else pw.println("(not running)");
12191            if (dumpAll) {
12192                r.dump(pw, innerPrefix);
12193            }
12194        }
12195        if (r.app != null && r.app.thread != null) {
12196            // flush anything that is already in the PrintWriter since the thread is going
12197            // to write to the file descriptor directly
12198            pw.flush();
12199            try {
12200                TransferPipe tp = new TransferPipe();
12201                try {
12202                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12203                            r.appToken, innerPrefix, args);
12204                    tp.go(fd);
12205                } finally {
12206                    tp.kill();
12207                }
12208            } catch (IOException e) {
12209                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12210            } catch (RemoteException e) {
12211                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12212            }
12213        }
12214    }
12215
12216    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12217            int opti, boolean dumpAll, String dumpPackage) {
12218        boolean needSep = false;
12219        boolean onlyHistory = false;
12220        boolean printedAnything = false;
12221
12222        if ("history".equals(dumpPackage)) {
12223            if (opti < args.length && "-s".equals(args[opti])) {
12224                dumpAll = false;
12225            }
12226            onlyHistory = true;
12227            dumpPackage = null;
12228        }
12229
12230        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12231        if (!onlyHistory && dumpAll) {
12232            if (mRegisteredReceivers.size() > 0) {
12233                boolean printed = false;
12234                Iterator it = mRegisteredReceivers.values().iterator();
12235                while (it.hasNext()) {
12236                    ReceiverList r = (ReceiverList)it.next();
12237                    if (dumpPackage != null && (r.app == null ||
12238                            !dumpPackage.equals(r.app.info.packageName))) {
12239                        continue;
12240                    }
12241                    if (!printed) {
12242                        pw.println("  Registered Receivers:");
12243                        needSep = true;
12244                        printed = true;
12245                        printedAnything = true;
12246                    }
12247                    pw.print("  * "); pw.println(r);
12248                    r.dump(pw, "    ");
12249                }
12250            }
12251
12252            if (mReceiverResolver.dump(pw, needSep ?
12253                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12254                    "    ", dumpPackage, false)) {
12255                needSep = true;
12256                printedAnything = true;
12257            }
12258        }
12259
12260        for (BroadcastQueue q : mBroadcastQueues) {
12261            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12262            printedAnything |= needSep;
12263        }
12264
12265        needSep = true;
12266
12267        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12268            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12269                if (needSep) {
12270                    pw.println();
12271                }
12272                needSep = true;
12273                printedAnything = true;
12274                pw.print("  Sticky broadcasts for user ");
12275                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12276                StringBuilder sb = new StringBuilder(128);
12277                for (Map.Entry<String, ArrayList<Intent>> ent
12278                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12279                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12280                    if (dumpAll) {
12281                        pw.println(":");
12282                        ArrayList<Intent> intents = ent.getValue();
12283                        final int N = intents.size();
12284                        for (int i=0; i<N; i++) {
12285                            sb.setLength(0);
12286                            sb.append("    Intent: ");
12287                            intents.get(i).toShortString(sb, false, true, false, false);
12288                            pw.println(sb.toString());
12289                            Bundle bundle = intents.get(i).getExtras();
12290                            if (bundle != null) {
12291                                pw.print("      ");
12292                                pw.println(bundle.toString());
12293                            }
12294                        }
12295                    } else {
12296                        pw.println("");
12297                    }
12298                }
12299            }
12300        }
12301
12302        if (!onlyHistory && dumpAll) {
12303            pw.println();
12304            for (BroadcastQueue queue : mBroadcastQueues) {
12305                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12306                        + queue.mBroadcastsScheduled);
12307            }
12308            pw.println("  mHandler:");
12309            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12310            needSep = true;
12311            printedAnything = true;
12312        }
12313
12314        if (!printedAnything) {
12315            pw.println("  (nothing)");
12316        }
12317    }
12318
12319    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12320            int opti, boolean dumpAll, String dumpPackage) {
12321        boolean needSep;
12322        boolean printedAnything = false;
12323
12324        ItemMatcher matcher = new ItemMatcher();
12325        matcher.build(args, opti);
12326
12327        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12328
12329        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12330        printedAnything |= needSep;
12331
12332        if (mLaunchingProviders.size() > 0) {
12333            boolean printed = false;
12334            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12335                ContentProviderRecord r = mLaunchingProviders.get(i);
12336                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12337                    continue;
12338                }
12339                if (!printed) {
12340                    if (needSep) pw.println();
12341                    needSep = true;
12342                    pw.println("  Launching content providers:");
12343                    printed = true;
12344                    printedAnything = true;
12345                }
12346                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12347                        pw.println(r);
12348            }
12349        }
12350
12351        if (mGrantedUriPermissions.size() > 0) {
12352            boolean printed = false;
12353            int dumpUid = -2;
12354            if (dumpPackage != null) {
12355                try {
12356                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12357                } catch (NameNotFoundException e) {
12358                    dumpUid = -1;
12359                }
12360            }
12361            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12362                int uid = mGrantedUriPermissions.keyAt(i);
12363                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12364                    continue;
12365                }
12366                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12367                if (!printed) {
12368                    if (needSep) pw.println();
12369                    needSep = true;
12370                    pw.println("  Granted Uri Permissions:");
12371                    printed = true;
12372                    printedAnything = true;
12373                }
12374                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12375                for (UriPermission perm : perms.values()) {
12376                    pw.print("    "); pw.println(perm);
12377                    if (dumpAll) {
12378                        perm.dump(pw, "      ");
12379                    }
12380                }
12381            }
12382        }
12383
12384        if (!printedAnything) {
12385            pw.println("  (nothing)");
12386        }
12387    }
12388
12389    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12390            int opti, boolean dumpAll, String dumpPackage) {
12391        boolean printed = false;
12392
12393        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12394
12395        if (mIntentSenderRecords.size() > 0) {
12396            Iterator<WeakReference<PendingIntentRecord>> it
12397                    = mIntentSenderRecords.values().iterator();
12398            while (it.hasNext()) {
12399                WeakReference<PendingIntentRecord> ref = it.next();
12400                PendingIntentRecord rec = ref != null ? ref.get(): null;
12401                if (dumpPackage != null && (rec == null
12402                        || !dumpPackage.equals(rec.key.packageName))) {
12403                    continue;
12404                }
12405                printed = true;
12406                if (rec != null) {
12407                    pw.print("  * "); pw.println(rec);
12408                    if (dumpAll) {
12409                        rec.dump(pw, "    ");
12410                    }
12411                } else {
12412                    pw.print("  * "); pw.println(ref);
12413                }
12414            }
12415        }
12416
12417        if (!printed) {
12418            pw.println("  (nothing)");
12419        }
12420    }
12421
12422    private static final int dumpProcessList(PrintWriter pw,
12423            ActivityManagerService service, List list,
12424            String prefix, String normalLabel, String persistentLabel,
12425            String dumpPackage) {
12426        int numPers = 0;
12427        final int N = list.size()-1;
12428        for (int i=N; i>=0; i--) {
12429            ProcessRecord r = (ProcessRecord)list.get(i);
12430            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12431                continue;
12432            }
12433            pw.println(String.format("%s%s #%2d: %s",
12434                    prefix, (r.persistent ? persistentLabel : normalLabel),
12435                    i, r.toString()));
12436            if (r.persistent) {
12437                numPers++;
12438            }
12439        }
12440        return numPers;
12441    }
12442
12443    private static final boolean dumpProcessOomList(PrintWriter pw,
12444            ActivityManagerService service, List<ProcessRecord> origList,
12445            String prefix, String normalLabel, String persistentLabel,
12446            boolean inclDetails, String dumpPackage) {
12447
12448        ArrayList<Pair<ProcessRecord, Integer>> list
12449                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12450        for (int i=0; i<origList.size(); i++) {
12451            ProcessRecord r = origList.get(i);
12452            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12453                continue;
12454            }
12455            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12456        }
12457
12458        if (list.size() <= 0) {
12459            return false;
12460        }
12461
12462        Comparator<Pair<ProcessRecord, Integer>> comparator
12463                = new Comparator<Pair<ProcessRecord, Integer>>() {
12464            @Override
12465            public int compare(Pair<ProcessRecord, Integer> object1,
12466                    Pair<ProcessRecord, Integer> object2) {
12467                if (object1.first.setAdj != object2.first.setAdj) {
12468                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12469                }
12470                if (object1.second.intValue() != object2.second.intValue()) {
12471                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12472                }
12473                return 0;
12474            }
12475        };
12476
12477        Collections.sort(list, comparator);
12478
12479        final long curRealtime = SystemClock.elapsedRealtime();
12480        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12481        final long curUptime = SystemClock.uptimeMillis();
12482        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12483
12484        for (int i=list.size()-1; i>=0; i--) {
12485            ProcessRecord r = list.get(i).first;
12486            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12487            char schedGroup;
12488            switch (r.setSchedGroup) {
12489                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12490                    schedGroup = 'B';
12491                    break;
12492                case Process.THREAD_GROUP_DEFAULT:
12493                    schedGroup = 'F';
12494                    break;
12495                default:
12496                    schedGroup = '?';
12497                    break;
12498            }
12499            char foreground;
12500            if (r.foregroundActivities) {
12501                foreground = 'A';
12502            } else if (r.foregroundServices) {
12503                foreground = 'S';
12504            } else {
12505                foreground = ' ';
12506            }
12507            String procState = ProcessList.makeProcStateString(r.curProcState);
12508            pw.print(prefix);
12509            pw.print(r.persistent ? persistentLabel : normalLabel);
12510            pw.print(" #");
12511            int num = (origList.size()-1)-list.get(i).second;
12512            if (num < 10) pw.print(' ');
12513            pw.print(num);
12514            pw.print(": ");
12515            pw.print(oomAdj);
12516            pw.print(' ');
12517            pw.print(schedGroup);
12518            pw.print('/');
12519            pw.print(foreground);
12520            pw.print('/');
12521            pw.print(procState);
12522            pw.print(" trm:");
12523            if (r.trimMemoryLevel < 10) pw.print(' ');
12524            pw.print(r.trimMemoryLevel);
12525            pw.print(' ');
12526            pw.print(r.toShortString());
12527            pw.print(" (");
12528            pw.print(r.adjType);
12529            pw.println(')');
12530            if (r.adjSource != null || r.adjTarget != null) {
12531                pw.print(prefix);
12532                pw.print("    ");
12533                if (r.adjTarget instanceof ComponentName) {
12534                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12535                } else if (r.adjTarget != null) {
12536                    pw.print(r.adjTarget.toString());
12537                } else {
12538                    pw.print("{null}");
12539                }
12540                pw.print("<=");
12541                if (r.adjSource instanceof ProcessRecord) {
12542                    pw.print("Proc{");
12543                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12544                    pw.println("}");
12545                } else if (r.adjSource != null) {
12546                    pw.println(r.adjSource.toString());
12547                } else {
12548                    pw.println("{null}");
12549                }
12550            }
12551            if (inclDetails) {
12552                pw.print(prefix);
12553                pw.print("    ");
12554                pw.print("oom: max="); pw.print(r.maxAdj);
12555                pw.print(" curRaw="); pw.print(r.curRawAdj);
12556                pw.print(" setRaw="); pw.print(r.setRawAdj);
12557                pw.print(" cur="); pw.print(r.curAdj);
12558                pw.print(" set="); pw.println(r.setAdj);
12559                pw.print(prefix);
12560                pw.print("    ");
12561                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12562                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12563                pw.print(" lastPss="); pw.print(r.lastPss);
12564                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12565                pw.print(prefix);
12566                pw.print("    ");
12567                pw.print("cached="); pw.print(r.cached);
12568                pw.print(" empty="); pw.print(r.empty);
12569                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12570
12571                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12572                    if (r.lastWakeTime != 0) {
12573                        long wtime;
12574                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12575                        synchronized (stats) {
12576                            wtime = stats.getProcessWakeTime(r.info.uid,
12577                                    r.pid, curRealtime);
12578                        }
12579                        long timeUsed = wtime - r.lastWakeTime;
12580                        pw.print(prefix);
12581                        pw.print("    ");
12582                        pw.print("keep awake over ");
12583                        TimeUtils.formatDuration(realtimeSince, pw);
12584                        pw.print(" used ");
12585                        TimeUtils.formatDuration(timeUsed, pw);
12586                        pw.print(" (");
12587                        pw.print((timeUsed*100)/realtimeSince);
12588                        pw.println("%)");
12589                    }
12590                    if (r.lastCpuTime != 0) {
12591                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12592                        pw.print(prefix);
12593                        pw.print("    ");
12594                        pw.print("run cpu over ");
12595                        TimeUtils.formatDuration(uptimeSince, pw);
12596                        pw.print(" used ");
12597                        TimeUtils.formatDuration(timeUsed, pw);
12598                        pw.print(" (");
12599                        pw.print((timeUsed*100)/uptimeSince);
12600                        pw.println("%)");
12601                    }
12602                }
12603            }
12604        }
12605        return true;
12606    }
12607
12608    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12609        ArrayList<ProcessRecord> procs;
12610        synchronized (this) {
12611            if (args != null && args.length > start
12612                    && args[start].charAt(0) != '-') {
12613                procs = new ArrayList<ProcessRecord>();
12614                int pid = -1;
12615                try {
12616                    pid = Integer.parseInt(args[start]);
12617                } catch (NumberFormatException e) {
12618                }
12619                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12620                    ProcessRecord proc = mLruProcesses.get(i);
12621                    if (proc.pid == pid) {
12622                        procs.add(proc);
12623                    } else if (proc.processName.equals(args[start])) {
12624                        procs.add(proc);
12625                    }
12626                }
12627                if (procs.size() <= 0) {
12628                    return null;
12629                }
12630            } else {
12631                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12632            }
12633        }
12634        return procs;
12635    }
12636
12637    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12638            PrintWriter pw, String[] args) {
12639        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12640        if (procs == null) {
12641            pw.println("No process found for: " + args[0]);
12642            return;
12643        }
12644
12645        long uptime = SystemClock.uptimeMillis();
12646        long realtime = SystemClock.elapsedRealtime();
12647        pw.println("Applications Graphics Acceleration Info:");
12648        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12649
12650        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12651            ProcessRecord r = procs.get(i);
12652            if (r.thread != null) {
12653                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12654                pw.flush();
12655                try {
12656                    TransferPipe tp = new TransferPipe();
12657                    try {
12658                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12659                        tp.go(fd);
12660                    } finally {
12661                        tp.kill();
12662                    }
12663                } catch (IOException e) {
12664                    pw.println("Failure while dumping the app: " + r);
12665                    pw.flush();
12666                } catch (RemoteException e) {
12667                    pw.println("Got a RemoteException while dumping the app " + r);
12668                    pw.flush();
12669                }
12670            }
12671        }
12672    }
12673
12674    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12675        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12676        if (procs == null) {
12677            pw.println("No process found for: " + args[0]);
12678            return;
12679        }
12680
12681        pw.println("Applications Database Info:");
12682
12683        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12684            ProcessRecord r = procs.get(i);
12685            if (r.thread != null) {
12686                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12687                pw.flush();
12688                try {
12689                    TransferPipe tp = new TransferPipe();
12690                    try {
12691                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12692                        tp.go(fd);
12693                    } finally {
12694                        tp.kill();
12695                    }
12696                } catch (IOException e) {
12697                    pw.println("Failure while dumping the app: " + r);
12698                    pw.flush();
12699                } catch (RemoteException e) {
12700                    pw.println("Got a RemoteException while dumping the app " + r);
12701                    pw.flush();
12702                }
12703            }
12704        }
12705    }
12706
12707    final static class MemItem {
12708        final boolean isProc;
12709        final String label;
12710        final String shortLabel;
12711        final long pss;
12712        final int id;
12713        final boolean hasActivities;
12714        ArrayList<MemItem> subitems;
12715
12716        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12717                boolean _hasActivities) {
12718            isProc = true;
12719            label = _label;
12720            shortLabel = _shortLabel;
12721            pss = _pss;
12722            id = _id;
12723            hasActivities = _hasActivities;
12724        }
12725
12726        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12727            isProc = false;
12728            label = _label;
12729            shortLabel = _shortLabel;
12730            pss = _pss;
12731            id = _id;
12732            hasActivities = false;
12733        }
12734    }
12735
12736    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12737            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12738        if (sort && !isCompact) {
12739            Collections.sort(items, new Comparator<MemItem>() {
12740                @Override
12741                public int compare(MemItem lhs, MemItem rhs) {
12742                    if (lhs.pss < rhs.pss) {
12743                        return 1;
12744                    } else if (lhs.pss > rhs.pss) {
12745                        return -1;
12746                    }
12747                    return 0;
12748                }
12749            });
12750        }
12751
12752        for (int i=0; i<items.size(); i++) {
12753            MemItem mi = items.get(i);
12754            if (!isCompact) {
12755                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12756            } else if (mi.isProc) {
12757                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12758                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12759                pw.println(mi.hasActivities ? ",a" : ",e");
12760            } else {
12761                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12762                pw.println(mi.pss);
12763            }
12764            if (mi.subitems != null) {
12765                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12766                        true, isCompact);
12767            }
12768        }
12769    }
12770
12771    // These are in KB.
12772    static final long[] DUMP_MEM_BUCKETS = new long[] {
12773        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12774        120*1024, 160*1024, 200*1024,
12775        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12776        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12777    };
12778
12779    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12780            boolean stackLike) {
12781        int start = label.lastIndexOf('.');
12782        if (start >= 0) start++;
12783        else start = 0;
12784        int end = label.length();
12785        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12786            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12787                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12788                out.append(bucket);
12789                out.append(stackLike ? "MB." : "MB ");
12790                out.append(label, start, end);
12791                return;
12792            }
12793        }
12794        out.append(memKB/1024);
12795        out.append(stackLike ? "MB." : "MB ");
12796        out.append(label, start, end);
12797    }
12798
12799    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12800            ProcessList.NATIVE_ADJ,
12801            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12802            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12803            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12804            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12805            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12806    };
12807    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12808            "Native",
12809            "System", "Persistent", "Foreground",
12810            "Visible", "Perceptible",
12811            "Heavy Weight", "Backup",
12812            "A Services", "Home",
12813            "Previous", "B Services", "Cached"
12814    };
12815    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12816            "native",
12817            "sys", "pers", "fore",
12818            "vis", "percept",
12819            "heavy", "backup",
12820            "servicea", "home",
12821            "prev", "serviceb", "cached"
12822    };
12823
12824    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12825            long realtime, boolean isCheckinRequest, boolean isCompact) {
12826        if (isCheckinRequest || isCompact) {
12827            // short checkin version
12828            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12829        } else {
12830            pw.println("Applications Memory Usage (kB):");
12831            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12832        }
12833    }
12834
12835    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12836            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12837        boolean dumpDetails = false;
12838        boolean dumpFullDetails = false;
12839        boolean dumpDalvik = false;
12840        boolean oomOnly = false;
12841        boolean isCompact = false;
12842        boolean localOnly = false;
12843
12844        int opti = 0;
12845        while (opti < args.length) {
12846            String opt = args[opti];
12847            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12848                break;
12849            }
12850            opti++;
12851            if ("-a".equals(opt)) {
12852                dumpDetails = true;
12853                dumpFullDetails = true;
12854                dumpDalvik = true;
12855            } else if ("-d".equals(opt)) {
12856                dumpDalvik = true;
12857            } else if ("-c".equals(opt)) {
12858                isCompact = true;
12859            } else if ("--oom".equals(opt)) {
12860                oomOnly = true;
12861            } else if ("--local".equals(opt)) {
12862                localOnly = true;
12863            } else if ("-h".equals(opt)) {
12864                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12865                pw.println("  -a: include all available information for each process.");
12866                pw.println("  -d: include dalvik details when dumping process details.");
12867                pw.println("  -c: dump in a compact machine-parseable representation.");
12868                pw.println("  --oom: only show processes organized by oom adj.");
12869                pw.println("  --local: only collect details locally, don't call process.");
12870                pw.println("If [process] is specified it can be the name or ");
12871                pw.println("pid of a specific process to dump.");
12872                return;
12873            } else {
12874                pw.println("Unknown argument: " + opt + "; use -h for help");
12875            }
12876        }
12877
12878        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12879        long uptime = SystemClock.uptimeMillis();
12880        long realtime = SystemClock.elapsedRealtime();
12881        final long[] tmpLong = new long[1];
12882
12883        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12884        if (procs == null) {
12885            // No Java processes.  Maybe they want to print a native process.
12886            if (args != null && args.length > opti
12887                    && args[opti].charAt(0) != '-') {
12888                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12889                        = new ArrayList<ProcessCpuTracker.Stats>();
12890                updateCpuStatsNow();
12891                int findPid = -1;
12892                try {
12893                    findPid = Integer.parseInt(args[opti]);
12894                } catch (NumberFormatException e) {
12895                }
12896                synchronized (mProcessCpuThread) {
12897                    final int N = mProcessCpuTracker.countStats();
12898                    for (int i=0; i<N; i++) {
12899                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12900                        if (st.pid == findPid || (st.baseName != null
12901                                && st.baseName.equals(args[opti]))) {
12902                            nativeProcs.add(st);
12903                        }
12904                    }
12905                }
12906                if (nativeProcs.size() > 0) {
12907                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12908                            isCompact);
12909                    Debug.MemoryInfo mi = null;
12910                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12911                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12912                        final int pid = r.pid;
12913                        if (!isCheckinRequest && dumpDetails) {
12914                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12915                        }
12916                        if (mi == null) {
12917                            mi = new Debug.MemoryInfo();
12918                        }
12919                        if (dumpDetails || (!brief && !oomOnly)) {
12920                            Debug.getMemoryInfo(pid, mi);
12921                        } else {
12922                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12923                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12924                        }
12925                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12926                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12927                        if (isCheckinRequest) {
12928                            pw.println();
12929                        }
12930                    }
12931                    return;
12932                }
12933            }
12934            pw.println("No process found for: " + args[opti]);
12935            return;
12936        }
12937
12938        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12939            dumpDetails = true;
12940        }
12941
12942        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12943
12944        String[] innerArgs = new String[args.length-opti];
12945        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12946
12947        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12948        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12949        long nativePss=0, dalvikPss=0, otherPss=0;
12950        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12951
12952        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12953        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12954                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12955
12956        long totalPss = 0;
12957        long cachedPss = 0;
12958
12959        Debug.MemoryInfo mi = null;
12960        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12961            final ProcessRecord r = procs.get(i);
12962            final IApplicationThread thread;
12963            final int pid;
12964            final int oomAdj;
12965            final boolean hasActivities;
12966            synchronized (this) {
12967                thread = r.thread;
12968                pid = r.pid;
12969                oomAdj = r.getSetAdjWithServices();
12970                hasActivities = r.activities.size() > 0;
12971            }
12972            if (thread != null) {
12973                if (!isCheckinRequest && dumpDetails) {
12974                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12975                }
12976                if (mi == null) {
12977                    mi = new Debug.MemoryInfo();
12978                }
12979                if (dumpDetails || (!brief && !oomOnly)) {
12980                    Debug.getMemoryInfo(pid, mi);
12981                } else {
12982                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12983                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12984                }
12985                if (dumpDetails) {
12986                    if (localOnly) {
12987                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12988                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12989                        if (isCheckinRequest) {
12990                            pw.println();
12991                        }
12992                    } else {
12993                        try {
12994                            pw.flush();
12995                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12996                                    dumpDalvik, innerArgs);
12997                        } catch (RemoteException e) {
12998                            if (!isCheckinRequest) {
12999                                pw.println("Got RemoteException!");
13000                                pw.flush();
13001                            }
13002                        }
13003                    }
13004                }
13005
13006                final long myTotalPss = mi.getTotalPss();
13007                final long myTotalUss = mi.getTotalUss();
13008
13009                synchronized (this) {
13010                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13011                        // Record this for posterity if the process has been stable.
13012                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13013                    }
13014                }
13015
13016                if (!isCheckinRequest && mi != null) {
13017                    totalPss += myTotalPss;
13018                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13019                            (hasActivities ? " / activities)" : ")"),
13020                            r.processName, myTotalPss, pid, hasActivities);
13021                    procMems.add(pssItem);
13022                    procMemsMap.put(pid, pssItem);
13023
13024                    nativePss += mi.nativePss;
13025                    dalvikPss += mi.dalvikPss;
13026                    otherPss += mi.otherPss;
13027                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13028                        long mem = mi.getOtherPss(j);
13029                        miscPss[j] += mem;
13030                        otherPss -= mem;
13031                    }
13032
13033                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13034                        cachedPss += myTotalPss;
13035                    }
13036
13037                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13038                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13039                                || oomIndex == (oomPss.length-1)) {
13040                            oomPss[oomIndex] += myTotalPss;
13041                            if (oomProcs[oomIndex] == null) {
13042                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13043                            }
13044                            oomProcs[oomIndex].add(pssItem);
13045                            break;
13046                        }
13047                    }
13048                }
13049            }
13050        }
13051
13052        long nativeProcTotalPss = 0;
13053
13054        if (!isCheckinRequest && procs.size() > 1) {
13055            // If we are showing aggregations, also look for native processes to
13056            // include so that our aggregations are more accurate.
13057            updateCpuStatsNow();
13058            synchronized (mProcessCpuThread) {
13059                final int N = mProcessCpuTracker.countStats();
13060                for (int i=0; i<N; i++) {
13061                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13062                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13063                        if (mi == null) {
13064                            mi = new Debug.MemoryInfo();
13065                        }
13066                        if (!brief && !oomOnly) {
13067                            Debug.getMemoryInfo(st.pid, mi);
13068                        } else {
13069                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13070                            mi.nativePrivateDirty = (int)tmpLong[0];
13071                        }
13072
13073                        final long myTotalPss = mi.getTotalPss();
13074                        totalPss += myTotalPss;
13075                        nativeProcTotalPss += myTotalPss;
13076
13077                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13078                                st.name, myTotalPss, st.pid, false);
13079                        procMems.add(pssItem);
13080
13081                        nativePss += mi.nativePss;
13082                        dalvikPss += mi.dalvikPss;
13083                        otherPss += mi.otherPss;
13084                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13085                            long mem = mi.getOtherPss(j);
13086                            miscPss[j] += mem;
13087                            otherPss -= mem;
13088                        }
13089                        oomPss[0] += myTotalPss;
13090                        if (oomProcs[0] == null) {
13091                            oomProcs[0] = new ArrayList<MemItem>();
13092                        }
13093                        oomProcs[0].add(pssItem);
13094                    }
13095                }
13096            }
13097
13098            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13099
13100            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13101            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13102            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13103            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13104                String label = Debug.MemoryInfo.getOtherLabel(j);
13105                catMems.add(new MemItem(label, label, miscPss[j], j));
13106            }
13107
13108            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13109            for (int j=0; j<oomPss.length; j++) {
13110                if (oomPss[j] != 0) {
13111                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13112                            : DUMP_MEM_OOM_LABEL[j];
13113                    MemItem item = new MemItem(label, label, oomPss[j],
13114                            DUMP_MEM_OOM_ADJ[j]);
13115                    item.subitems = oomProcs[j];
13116                    oomMems.add(item);
13117                }
13118            }
13119
13120            if (!brief && !oomOnly && !isCompact) {
13121                pw.println();
13122                pw.println("Total PSS by process:");
13123                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13124                pw.println();
13125            }
13126            if (!isCompact) {
13127                pw.println("Total PSS by OOM adjustment:");
13128            }
13129            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13130            if (!brief && !oomOnly) {
13131                PrintWriter out = categoryPw != null ? categoryPw : pw;
13132                if (!isCompact) {
13133                    out.println();
13134                    out.println("Total PSS by category:");
13135                }
13136                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13137            }
13138            if (!isCompact) {
13139                pw.println();
13140            }
13141            MemInfoReader memInfo = new MemInfoReader();
13142            memInfo.readMemInfo();
13143            if (nativeProcTotalPss > 0) {
13144                synchronized (this) {
13145                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13146                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13147                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13148                            nativeProcTotalPss);
13149                }
13150            }
13151            if (!brief) {
13152                if (!isCompact) {
13153                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13154                    pw.print(" kB (status ");
13155                    switch (mLastMemoryLevel) {
13156                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13157                            pw.println("normal)");
13158                            break;
13159                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13160                            pw.println("moderate)");
13161                            break;
13162                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13163                            pw.println("low)");
13164                            break;
13165                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13166                            pw.println("critical)");
13167                            break;
13168                        default:
13169                            pw.print(mLastMemoryLevel);
13170                            pw.println(")");
13171                            break;
13172                    }
13173                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13174                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13175                            pw.print(cachedPss); pw.print(" cached pss + ");
13176                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13177                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13178                } else {
13179                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13180                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13181                            + memInfo.getFreeSizeKb()); pw.print(",");
13182                    pw.println(totalPss - cachedPss);
13183                }
13184            }
13185            if (!isCompact) {
13186                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13187                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13188                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13189                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13190                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13191                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13192                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13193                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13194                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13195                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13196                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13197            }
13198            if (!brief) {
13199                if (memInfo.getZramTotalSizeKb() != 0) {
13200                    if (!isCompact) {
13201                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13202                                pw.print(" kB physical used for ");
13203                                pw.print(memInfo.getSwapTotalSizeKb()
13204                                        - memInfo.getSwapFreeSizeKb());
13205                                pw.print(" kB in swap (");
13206                                pw.print(memInfo.getSwapTotalSizeKb());
13207                                pw.println(" kB total swap)");
13208                    } else {
13209                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13210                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13211                                pw.println(memInfo.getSwapFreeSizeKb());
13212                    }
13213                }
13214                final int[] SINGLE_LONG_FORMAT = new int[] {
13215                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13216                };
13217                long[] longOut = new long[1];
13218                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13219                        SINGLE_LONG_FORMAT, null, longOut, null);
13220                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13221                longOut[0] = 0;
13222                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13223                        SINGLE_LONG_FORMAT, null, longOut, null);
13224                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13225                longOut[0] = 0;
13226                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13227                        SINGLE_LONG_FORMAT, null, longOut, null);
13228                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13229                longOut[0] = 0;
13230                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13231                        SINGLE_LONG_FORMAT, null, longOut, null);
13232                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13233                if (!isCompact) {
13234                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13235                        pw.print("      KSM: "); pw.print(sharing);
13236                                pw.print(" kB saved from shared ");
13237                                pw.print(shared); pw.println(" kB");
13238                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13239                                pw.print(voltile); pw.println(" kB volatile");
13240                    }
13241                    pw.print("   Tuning: ");
13242                    pw.print(ActivityManager.staticGetMemoryClass());
13243                    pw.print(" (large ");
13244                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13245                    pw.print("), oom ");
13246                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13247                    pw.print(" kB");
13248                    pw.print(", restore limit ");
13249                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13250                    pw.print(" kB");
13251                    if (ActivityManager.isLowRamDeviceStatic()) {
13252                        pw.print(" (low-ram)");
13253                    }
13254                    if (ActivityManager.isHighEndGfx()) {
13255                        pw.print(" (high-end-gfx)");
13256                    }
13257                    pw.println();
13258                } else {
13259                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13260                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13261                    pw.println(voltile);
13262                    pw.print("tuning,");
13263                    pw.print(ActivityManager.staticGetMemoryClass());
13264                    pw.print(',');
13265                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13266                    pw.print(',');
13267                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13268                    if (ActivityManager.isLowRamDeviceStatic()) {
13269                        pw.print(",low-ram");
13270                    }
13271                    if (ActivityManager.isHighEndGfx()) {
13272                        pw.print(",high-end-gfx");
13273                    }
13274                    pw.println();
13275                }
13276            }
13277        }
13278    }
13279
13280    /**
13281     * Searches array of arguments for the specified string
13282     * @param args array of argument strings
13283     * @param value value to search for
13284     * @return true if the value is contained in the array
13285     */
13286    private static boolean scanArgs(String[] args, String value) {
13287        if (args != null) {
13288            for (String arg : args) {
13289                if (value.equals(arg)) {
13290                    return true;
13291                }
13292            }
13293        }
13294        return false;
13295    }
13296
13297    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13298            ContentProviderRecord cpr, boolean always) {
13299        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13300
13301        if (!inLaunching || always) {
13302            synchronized (cpr) {
13303                cpr.launchingApp = null;
13304                cpr.notifyAll();
13305            }
13306            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13307            String names[] = cpr.info.authority.split(";");
13308            for (int j = 0; j < names.length; j++) {
13309                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13310            }
13311        }
13312
13313        for (int i=0; i<cpr.connections.size(); i++) {
13314            ContentProviderConnection conn = cpr.connections.get(i);
13315            if (conn.waiting) {
13316                // If this connection is waiting for the provider, then we don't
13317                // need to mess with its process unless we are always removing
13318                // or for some reason the provider is not currently launching.
13319                if (inLaunching && !always) {
13320                    continue;
13321                }
13322            }
13323            ProcessRecord capp = conn.client;
13324            conn.dead = true;
13325            if (conn.stableCount > 0) {
13326                if (!capp.persistent && capp.thread != null
13327                        && capp.pid != 0
13328                        && capp.pid != MY_PID) {
13329                    killUnneededProcessLocked(capp, "depends on provider "
13330                            + cpr.name.flattenToShortString()
13331                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13332                }
13333            } else if (capp.thread != null && conn.provider.provider != null) {
13334                try {
13335                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13336                } catch (RemoteException e) {
13337                }
13338                // In the protocol here, we don't expect the client to correctly
13339                // clean up this connection, we'll just remove it.
13340                cpr.connections.remove(i);
13341                conn.client.conProviders.remove(conn);
13342            }
13343        }
13344
13345        if (inLaunching && always) {
13346            mLaunchingProviders.remove(cpr);
13347        }
13348        return inLaunching;
13349    }
13350
13351    /**
13352     * Main code for cleaning up a process when it has gone away.  This is
13353     * called both as a result of the process dying, or directly when stopping
13354     * a process when running in single process mode.
13355     */
13356    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13357            boolean restarting, boolean allowRestart, int index) {
13358        if (index >= 0) {
13359            removeLruProcessLocked(app);
13360            ProcessList.remove(app.pid);
13361        }
13362
13363        mProcessesToGc.remove(app);
13364        mPendingPssProcesses.remove(app);
13365
13366        // Dismiss any open dialogs.
13367        if (app.crashDialog != null && !app.forceCrashReport) {
13368            app.crashDialog.dismiss();
13369            app.crashDialog = null;
13370        }
13371        if (app.anrDialog != null) {
13372            app.anrDialog.dismiss();
13373            app.anrDialog = null;
13374        }
13375        if (app.waitDialog != null) {
13376            app.waitDialog.dismiss();
13377            app.waitDialog = null;
13378        }
13379
13380        app.crashing = false;
13381        app.notResponding = false;
13382
13383        app.resetPackageList(mProcessStats);
13384        app.unlinkDeathRecipient();
13385        app.makeInactive(mProcessStats);
13386        app.waitingToKill = null;
13387        app.forcingToForeground = null;
13388        updateProcessForegroundLocked(app, false, false);
13389        app.foregroundActivities = false;
13390        app.hasShownUi = false;
13391        app.treatLikeActivity = false;
13392        app.hasAboveClient = false;
13393        app.hasClientActivities = false;
13394
13395        mServices.killServicesLocked(app, allowRestart);
13396
13397        boolean restart = false;
13398
13399        // Remove published content providers.
13400        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13401            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13402            final boolean always = app.bad || !allowRestart;
13403            if (removeDyingProviderLocked(app, cpr, always) || always) {
13404                // We left the provider in the launching list, need to
13405                // restart it.
13406                restart = true;
13407            }
13408
13409            cpr.provider = null;
13410            cpr.proc = null;
13411        }
13412        app.pubProviders.clear();
13413
13414        // Take care of any launching providers waiting for this process.
13415        if (checkAppInLaunchingProvidersLocked(app, false)) {
13416            restart = true;
13417        }
13418
13419        // Unregister from connected content providers.
13420        if (!app.conProviders.isEmpty()) {
13421            for (int i=0; i<app.conProviders.size(); i++) {
13422                ContentProviderConnection conn = app.conProviders.get(i);
13423                conn.provider.connections.remove(conn);
13424            }
13425            app.conProviders.clear();
13426        }
13427
13428        // At this point there may be remaining entries in mLaunchingProviders
13429        // where we were the only one waiting, so they are no longer of use.
13430        // Look for these and clean up if found.
13431        // XXX Commented out for now.  Trying to figure out a way to reproduce
13432        // the actual situation to identify what is actually going on.
13433        if (false) {
13434            for (int i=0; i<mLaunchingProviders.size(); i++) {
13435                ContentProviderRecord cpr = (ContentProviderRecord)
13436                        mLaunchingProviders.get(i);
13437                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13438                    synchronized (cpr) {
13439                        cpr.launchingApp = null;
13440                        cpr.notifyAll();
13441                    }
13442                }
13443            }
13444        }
13445
13446        skipCurrentReceiverLocked(app);
13447
13448        // Unregister any receivers.
13449        for (int i=app.receivers.size()-1; i>=0; i--) {
13450            removeReceiverLocked(app.receivers.valueAt(i));
13451        }
13452        app.receivers.clear();
13453
13454        // If the app is undergoing backup, tell the backup manager about it
13455        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13456            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13457                    + mBackupTarget.appInfo + " died during backup");
13458            try {
13459                IBackupManager bm = IBackupManager.Stub.asInterface(
13460                        ServiceManager.getService(Context.BACKUP_SERVICE));
13461                bm.agentDisconnected(app.info.packageName);
13462            } catch (RemoteException e) {
13463                // can't happen; backup manager is local
13464            }
13465        }
13466
13467        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13468            ProcessChangeItem item = mPendingProcessChanges.get(i);
13469            if (item.pid == app.pid) {
13470                mPendingProcessChanges.remove(i);
13471                mAvailProcessChanges.add(item);
13472            }
13473        }
13474        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13475
13476        // If the caller is restarting this app, then leave it in its
13477        // current lists and let the caller take care of it.
13478        if (restarting) {
13479            return;
13480        }
13481
13482        if (!app.persistent || app.isolated) {
13483            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13484                    "Removing non-persistent process during cleanup: " + app);
13485            mProcessNames.remove(app.processName, app.uid);
13486            mIsolatedProcesses.remove(app.uid);
13487            if (mHeavyWeightProcess == app) {
13488                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13489                        mHeavyWeightProcess.userId, 0));
13490                mHeavyWeightProcess = null;
13491            }
13492        } else if (!app.removed) {
13493            // This app is persistent, so we need to keep its record around.
13494            // If it is not already on the pending app list, add it there
13495            // and start a new process for it.
13496            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13497                mPersistentStartingProcesses.add(app);
13498                restart = true;
13499            }
13500        }
13501        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13502                "Clean-up removing on hold: " + app);
13503        mProcessesOnHold.remove(app);
13504
13505        if (app == mHomeProcess) {
13506            mHomeProcess = null;
13507        }
13508        if (app == mPreviousProcess) {
13509            mPreviousProcess = null;
13510        }
13511
13512        if (restart && !app.isolated) {
13513            // We have components that still need to be running in the
13514            // process, so re-launch it.
13515            mProcessNames.put(app.processName, app.uid, app);
13516            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13517        } else if (app.pid > 0 && app.pid != MY_PID) {
13518            // Goodbye!
13519            boolean removed;
13520            synchronized (mPidsSelfLocked) {
13521                mPidsSelfLocked.remove(app.pid);
13522                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13523            }
13524            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13525            if (app.isolated) {
13526                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13527            }
13528            app.setPid(0);
13529        }
13530    }
13531
13532    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13533        // Look through the content providers we are waiting to have launched,
13534        // and if any run in this process then either schedule a restart of
13535        // the process or kill the client waiting for it if this process has
13536        // gone bad.
13537        int NL = mLaunchingProviders.size();
13538        boolean restart = false;
13539        for (int i=0; i<NL; i++) {
13540            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13541            if (cpr.launchingApp == app) {
13542                if (!alwaysBad && !app.bad) {
13543                    restart = true;
13544                } else {
13545                    removeDyingProviderLocked(app, cpr, true);
13546                    // cpr should have been removed from mLaunchingProviders
13547                    NL = mLaunchingProviders.size();
13548                    i--;
13549                }
13550            }
13551        }
13552        return restart;
13553    }
13554
13555    // =========================================================
13556    // SERVICES
13557    // =========================================================
13558
13559    @Override
13560    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13561            int flags) {
13562        enforceNotIsolatedCaller("getServices");
13563        synchronized (this) {
13564            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13565        }
13566    }
13567
13568    @Override
13569    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13570        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13571        synchronized (this) {
13572            return mServices.getRunningServiceControlPanelLocked(name);
13573        }
13574    }
13575
13576    @Override
13577    public ComponentName startService(IApplicationThread caller, Intent service,
13578            String resolvedType, int userId) {
13579        enforceNotIsolatedCaller("startService");
13580        // Refuse possible leaked file descriptors
13581        if (service != null && service.hasFileDescriptors() == true) {
13582            throw new IllegalArgumentException("File descriptors passed in Intent");
13583        }
13584
13585        if (DEBUG_SERVICE)
13586            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13587        synchronized(this) {
13588            final int callingPid = Binder.getCallingPid();
13589            final int callingUid = Binder.getCallingUid();
13590            final long origId = Binder.clearCallingIdentity();
13591            ComponentName res = mServices.startServiceLocked(caller, service,
13592                    resolvedType, callingPid, callingUid, userId);
13593            Binder.restoreCallingIdentity(origId);
13594            return res;
13595        }
13596    }
13597
13598    ComponentName startServiceInPackage(int uid,
13599            Intent service, String resolvedType, int userId) {
13600        synchronized(this) {
13601            if (DEBUG_SERVICE)
13602                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13603            final long origId = Binder.clearCallingIdentity();
13604            ComponentName res = mServices.startServiceLocked(null, service,
13605                    resolvedType, -1, uid, userId);
13606            Binder.restoreCallingIdentity(origId);
13607            return res;
13608        }
13609    }
13610
13611    @Override
13612    public int stopService(IApplicationThread caller, Intent service,
13613            String resolvedType, int userId) {
13614        enforceNotIsolatedCaller("stopService");
13615        // Refuse possible leaked file descriptors
13616        if (service != null && service.hasFileDescriptors() == true) {
13617            throw new IllegalArgumentException("File descriptors passed in Intent");
13618        }
13619
13620        synchronized(this) {
13621            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13622        }
13623    }
13624
13625    @Override
13626    public IBinder peekService(Intent service, String resolvedType) {
13627        enforceNotIsolatedCaller("peekService");
13628        // Refuse possible leaked file descriptors
13629        if (service != null && service.hasFileDescriptors() == true) {
13630            throw new IllegalArgumentException("File descriptors passed in Intent");
13631        }
13632        synchronized(this) {
13633            return mServices.peekServiceLocked(service, resolvedType);
13634        }
13635    }
13636
13637    @Override
13638    public boolean stopServiceToken(ComponentName className, IBinder token,
13639            int startId) {
13640        synchronized(this) {
13641            return mServices.stopServiceTokenLocked(className, token, startId);
13642        }
13643    }
13644
13645    @Override
13646    public void setServiceForeground(ComponentName className, IBinder token,
13647            int id, Notification notification, boolean removeNotification) {
13648        synchronized(this) {
13649            mServices.setServiceForegroundLocked(className, token, id, notification,
13650                    removeNotification);
13651        }
13652    }
13653
13654    @Override
13655    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13656            boolean requireFull, String name, String callerPackage) {
13657        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13658                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13659    }
13660
13661    int unsafeConvertIncomingUser(int userId) {
13662        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13663                ? mCurrentUserId : userId;
13664    }
13665
13666    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13667            int allowMode, String name, String callerPackage) {
13668        final int callingUserId = UserHandle.getUserId(callingUid);
13669        if (callingUserId == userId) {
13670            return userId;
13671        }
13672
13673        // Note that we may be accessing mCurrentUserId outside of a lock...
13674        // shouldn't be a big deal, if this is being called outside
13675        // of a locked context there is intrinsically a race with
13676        // the value the caller will receive and someone else changing it.
13677        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13678        // we will switch to the calling user if access to the current user fails.
13679        int targetUserId = unsafeConvertIncomingUser(userId);
13680
13681        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13682            final boolean allow;
13683            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13684                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13685                // If the caller has this permission, they always pass go.  And collect $200.
13686                allow = true;
13687            } else if (allowMode == ALLOW_FULL_ONLY) {
13688                // We require full access, sucks to be you.
13689                allow = false;
13690            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13691                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13692                // If the caller does not have either permission, they are always doomed.
13693                allow = false;
13694            } else if (allowMode == ALLOW_NON_FULL) {
13695                // We are blanket allowing non-full access, you lucky caller!
13696                allow = true;
13697            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13698                // We may or may not allow this depending on whether the two users are
13699                // in the same profile.
13700                synchronized (mUserProfileGroupIdsSelfLocked) {
13701                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13702                            UserInfo.NO_PROFILE_GROUP_ID);
13703                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13704                            UserInfo.NO_PROFILE_GROUP_ID);
13705                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13706                            && callingProfile == targetProfile;
13707                }
13708            } else {
13709                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13710            }
13711            if (!allow) {
13712                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13713                    // In this case, they would like to just execute as their
13714                    // owner user instead of failing.
13715                    targetUserId = callingUserId;
13716                } else {
13717                    StringBuilder builder = new StringBuilder(128);
13718                    builder.append("Permission Denial: ");
13719                    builder.append(name);
13720                    if (callerPackage != null) {
13721                        builder.append(" from ");
13722                        builder.append(callerPackage);
13723                    }
13724                    builder.append(" asks to run as user ");
13725                    builder.append(userId);
13726                    builder.append(" but is calling from user ");
13727                    builder.append(UserHandle.getUserId(callingUid));
13728                    builder.append("; this requires ");
13729                    builder.append(INTERACT_ACROSS_USERS_FULL);
13730                    if (allowMode != ALLOW_FULL_ONLY) {
13731                        builder.append(" or ");
13732                        builder.append(INTERACT_ACROSS_USERS);
13733                    }
13734                    String msg = builder.toString();
13735                    Slog.w(TAG, msg);
13736                    throw new SecurityException(msg);
13737                }
13738            }
13739        }
13740        if (!allowAll && targetUserId < 0) {
13741            throw new IllegalArgumentException(
13742                    "Call does not support special user #" + targetUserId);
13743        }
13744        return targetUserId;
13745    }
13746
13747    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13748            String className, int flags) {
13749        boolean result = false;
13750        // For apps that don't have pre-defined UIDs, check for permission
13751        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13752            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13753                if (ActivityManager.checkUidPermission(
13754                        INTERACT_ACROSS_USERS,
13755                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13756                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13757                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13758                            + " requests FLAG_SINGLE_USER, but app does not hold "
13759                            + INTERACT_ACROSS_USERS;
13760                    Slog.w(TAG, msg);
13761                    throw new SecurityException(msg);
13762                }
13763                // Permission passed
13764                result = true;
13765            }
13766        } else if ("system".equals(componentProcessName)) {
13767            result = true;
13768        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
13769                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13770            // Phone app is allowed to export singleuser providers.
13771            result = true;
13772        } else {
13773            // App with pre-defined UID, check if it's a persistent app
13774            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13775        }
13776        if (DEBUG_MU) {
13777            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13778                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13779        }
13780        return result;
13781    }
13782
13783    /**
13784     * Checks to see if the caller is in the same app as the singleton
13785     * component, or the component is in a special app. It allows special apps
13786     * to export singleton components but prevents exporting singleton
13787     * components for regular apps.
13788     */
13789    boolean isValidSingletonCall(int callingUid, int componentUid) {
13790        int componentAppId = UserHandle.getAppId(componentUid);
13791        return UserHandle.isSameApp(callingUid, componentUid)
13792                || componentAppId == Process.SYSTEM_UID
13793                || componentAppId == Process.PHONE_UID
13794                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13795                        == PackageManager.PERMISSION_GRANTED;
13796    }
13797
13798    public int bindService(IApplicationThread caller, IBinder token,
13799            Intent service, String resolvedType,
13800            IServiceConnection connection, int flags, int userId) {
13801        enforceNotIsolatedCaller("bindService");
13802        // Refuse possible leaked file descriptors
13803        if (service != null && service.hasFileDescriptors() == true) {
13804            throw new IllegalArgumentException("File descriptors passed in Intent");
13805        }
13806
13807        synchronized(this) {
13808            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13809                    connection, flags, userId);
13810        }
13811    }
13812
13813    public boolean unbindService(IServiceConnection connection) {
13814        synchronized (this) {
13815            return mServices.unbindServiceLocked(connection);
13816        }
13817    }
13818
13819    public void publishService(IBinder token, Intent intent, IBinder service) {
13820        // Refuse possible leaked file descriptors
13821        if (intent != null && intent.hasFileDescriptors() == true) {
13822            throw new IllegalArgumentException("File descriptors passed in Intent");
13823        }
13824
13825        synchronized(this) {
13826            if (!(token instanceof ServiceRecord)) {
13827                throw new IllegalArgumentException("Invalid service token");
13828            }
13829            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13830        }
13831    }
13832
13833    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13834        // Refuse possible leaked file descriptors
13835        if (intent != null && intent.hasFileDescriptors() == true) {
13836            throw new IllegalArgumentException("File descriptors passed in Intent");
13837        }
13838
13839        synchronized(this) {
13840            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13841        }
13842    }
13843
13844    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13845        synchronized(this) {
13846            if (!(token instanceof ServiceRecord)) {
13847                throw new IllegalArgumentException("Invalid service token");
13848            }
13849            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13850        }
13851    }
13852
13853    // =========================================================
13854    // BACKUP AND RESTORE
13855    // =========================================================
13856
13857    // Cause the target app to be launched if necessary and its backup agent
13858    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13859    // activity manager to announce its creation.
13860    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13861        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13862        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13863
13864        synchronized(this) {
13865            // !!! TODO: currently no check here that we're already bound
13866            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13867            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13868            synchronized (stats) {
13869                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13870            }
13871
13872            // Backup agent is now in use, its package can't be stopped.
13873            try {
13874                AppGlobals.getPackageManager().setPackageStoppedState(
13875                        app.packageName, false, UserHandle.getUserId(app.uid));
13876            } catch (RemoteException e) {
13877            } catch (IllegalArgumentException e) {
13878                Slog.w(TAG, "Failed trying to unstop package "
13879                        + app.packageName + ": " + e);
13880            }
13881
13882            BackupRecord r = new BackupRecord(ss, app, backupMode);
13883            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13884                    ? new ComponentName(app.packageName, app.backupAgentName)
13885                    : new ComponentName("android", "FullBackupAgent");
13886            // startProcessLocked() returns existing proc's record if it's already running
13887            ProcessRecord proc = startProcessLocked(app.processName, app,
13888                    false, 0, "backup", hostingName, false, false, false);
13889            if (proc == null) {
13890                Slog.e(TAG, "Unable to start backup agent process " + r);
13891                return false;
13892            }
13893
13894            r.app = proc;
13895            mBackupTarget = r;
13896            mBackupAppName = app.packageName;
13897
13898            // Try not to kill the process during backup
13899            updateOomAdjLocked(proc);
13900
13901            // If the process is already attached, schedule the creation of the backup agent now.
13902            // If it is not yet live, this will be done when it attaches to the framework.
13903            if (proc.thread != null) {
13904                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13905                try {
13906                    proc.thread.scheduleCreateBackupAgent(app,
13907                            compatibilityInfoForPackageLocked(app), backupMode);
13908                } catch (RemoteException e) {
13909                    // Will time out on the backup manager side
13910                }
13911            } else {
13912                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13913            }
13914            // Invariants: at this point, the target app process exists and the application
13915            // is either already running or in the process of coming up.  mBackupTarget and
13916            // mBackupAppName describe the app, so that when it binds back to the AM we
13917            // know that it's scheduled for a backup-agent operation.
13918        }
13919
13920        return true;
13921    }
13922
13923    @Override
13924    public void clearPendingBackup() {
13925        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13926        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13927
13928        synchronized (this) {
13929            mBackupTarget = null;
13930            mBackupAppName = null;
13931        }
13932    }
13933
13934    // A backup agent has just come up
13935    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13936        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13937                + " = " + agent);
13938
13939        synchronized(this) {
13940            if (!agentPackageName.equals(mBackupAppName)) {
13941                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13942                return;
13943            }
13944        }
13945
13946        long oldIdent = Binder.clearCallingIdentity();
13947        try {
13948            IBackupManager bm = IBackupManager.Stub.asInterface(
13949                    ServiceManager.getService(Context.BACKUP_SERVICE));
13950            bm.agentConnected(agentPackageName, agent);
13951        } catch (RemoteException e) {
13952            // can't happen; the backup manager service is local
13953        } catch (Exception e) {
13954            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13955            e.printStackTrace();
13956        } finally {
13957            Binder.restoreCallingIdentity(oldIdent);
13958        }
13959    }
13960
13961    // done with this agent
13962    public void unbindBackupAgent(ApplicationInfo appInfo) {
13963        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13964        if (appInfo == null) {
13965            Slog.w(TAG, "unbind backup agent for null app");
13966            return;
13967        }
13968
13969        synchronized(this) {
13970            try {
13971                if (mBackupAppName == null) {
13972                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13973                    return;
13974                }
13975
13976                if (!mBackupAppName.equals(appInfo.packageName)) {
13977                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13978                    return;
13979                }
13980
13981                // Not backing this app up any more; reset its OOM adjustment
13982                final ProcessRecord proc = mBackupTarget.app;
13983                updateOomAdjLocked(proc);
13984
13985                // If the app crashed during backup, 'thread' will be null here
13986                if (proc.thread != null) {
13987                    try {
13988                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13989                                compatibilityInfoForPackageLocked(appInfo));
13990                    } catch (Exception e) {
13991                        Slog.e(TAG, "Exception when unbinding backup agent:");
13992                        e.printStackTrace();
13993                    }
13994                }
13995            } finally {
13996                mBackupTarget = null;
13997                mBackupAppName = null;
13998            }
13999        }
14000    }
14001    // =========================================================
14002    // BROADCASTS
14003    // =========================================================
14004
14005    private final List getStickiesLocked(String action, IntentFilter filter,
14006            List cur, int userId) {
14007        final ContentResolver resolver = mContext.getContentResolver();
14008        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14009        if (stickies == null) {
14010            return cur;
14011        }
14012        final ArrayList<Intent> list = stickies.get(action);
14013        if (list == null) {
14014            return cur;
14015        }
14016        int N = list.size();
14017        for (int i=0; i<N; i++) {
14018            Intent intent = list.get(i);
14019            if (filter.match(resolver, intent, true, TAG) >= 0) {
14020                if (cur == null) {
14021                    cur = new ArrayList<Intent>();
14022                }
14023                cur.add(intent);
14024            }
14025        }
14026        return cur;
14027    }
14028
14029    boolean isPendingBroadcastProcessLocked(int pid) {
14030        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14031                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14032    }
14033
14034    void skipPendingBroadcastLocked(int pid) {
14035            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14036            for (BroadcastQueue queue : mBroadcastQueues) {
14037                queue.skipPendingBroadcastLocked(pid);
14038            }
14039    }
14040
14041    // The app just attached; send any pending broadcasts that it should receive
14042    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14043        boolean didSomething = false;
14044        for (BroadcastQueue queue : mBroadcastQueues) {
14045            didSomething |= queue.sendPendingBroadcastsLocked(app);
14046        }
14047        return didSomething;
14048    }
14049
14050    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14051            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14052        enforceNotIsolatedCaller("registerReceiver");
14053        int callingUid;
14054        int callingPid;
14055        synchronized(this) {
14056            ProcessRecord callerApp = null;
14057            if (caller != null) {
14058                callerApp = getRecordForAppLocked(caller);
14059                if (callerApp == null) {
14060                    throw new SecurityException(
14061                            "Unable to find app for caller " + caller
14062                            + " (pid=" + Binder.getCallingPid()
14063                            + ") when registering receiver " + receiver);
14064                }
14065                if (callerApp.info.uid != Process.SYSTEM_UID &&
14066                        !callerApp.pkgList.containsKey(callerPackage) &&
14067                        !"android".equals(callerPackage)) {
14068                    throw new SecurityException("Given caller package " + callerPackage
14069                            + " is not running in process " + callerApp);
14070                }
14071                callingUid = callerApp.info.uid;
14072                callingPid = callerApp.pid;
14073            } else {
14074                callerPackage = null;
14075                callingUid = Binder.getCallingUid();
14076                callingPid = Binder.getCallingPid();
14077            }
14078
14079            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14080                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14081
14082            List allSticky = null;
14083
14084            // Look for any matching sticky broadcasts...
14085            Iterator actions = filter.actionsIterator();
14086            if (actions != null) {
14087                while (actions.hasNext()) {
14088                    String action = (String)actions.next();
14089                    allSticky = getStickiesLocked(action, filter, allSticky,
14090                            UserHandle.USER_ALL);
14091                    allSticky = getStickiesLocked(action, filter, allSticky,
14092                            UserHandle.getUserId(callingUid));
14093                }
14094            } else {
14095                allSticky = getStickiesLocked(null, filter, allSticky,
14096                        UserHandle.USER_ALL);
14097                allSticky = getStickiesLocked(null, filter, allSticky,
14098                        UserHandle.getUserId(callingUid));
14099            }
14100
14101            // The first sticky in the list is returned directly back to
14102            // the client.
14103            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14104
14105            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14106                    + ": " + sticky);
14107
14108            if (receiver == null) {
14109                return sticky;
14110            }
14111
14112            ReceiverList rl
14113                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14114            if (rl == null) {
14115                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14116                        userId, receiver);
14117                if (rl.app != null) {
14118                    rl.app.receivers.add(rl);
14119                } else {
14120                    try {
14121                        receiver.asBinder().linkToDeath(rl, 0);
14122                    } catch (RemoteException e) {
14123                        return sticky;
14124                    }
14125                    rl.linkedToDeath = true;
14126                }
14127                mRegisteredReceivers.put(receiver.asBinder(), rl);
14128            } else if (rl.uid != callingUid) {
14129                throw new IllegalArgumentException(
14130                        "Receiver requested to register for uid " + callingUid
14131                        + " was previously registered for uid " + rl.uid);
14132            } else if (rl.pid != callingPid) {
14133                throw new IllegalArgumentException(
14134                        "Receiver requested to register for pid " + callingPid
14135                        + " was previously registered for pid " + rl.pid);
14136            } else if (rl.userId != userId) {
14137                throw new IllegalArgumentException(
14138                        "Receiver requested to register for user " + userId
14139                        + " was previously registered for user " + rl.userId);
14140            }
14141            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14142                    permission, callingUid, userId);
14143            rl.add(bf);
14144            if (!bf.debugCheck()) {
14145                Slog.w(TAG, "==> For Dynamic broadast");
14146            }
14147            mReceiverResolver.addFilter(bf);
14148
14149            // Enqueue broadcasts for all existing stickies that match
14150            // this filter.
14151            if (allSticky != null) {
14152                ArrayList receivers = new ArrayList();
14153                receivers.add(bf);
14154
14155                int N = allSticky.size();
14156                for (int i=0; i<N; i++) {
14157                    Intent intent = (Intent)allSticky.get(i);
14158                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14159                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14160                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14161                            null, null, false, true, true, -1);
14162                    queue.enqueueParallelBroadcastLocked(r);
14163                    queue.scheduleBroadcastsLocked();
14164                }
14165            }
14166
14167            return sticky;
14168        }
14169    }
14170
14171    public void unregisterReceiver(IIntentReceiver receiver) {
14172        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14173
14174        final long origId = Binder.clearCallingIdentity();
14175        try {
14176            boolean doTrim = false;
14177
14178            synchronized(this) {
14179                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14180                if (rl != null) {
14181                    if (rl.curBroadcast != null) {
14182                        BroadcastRecord r = rl.curBroadcast;
14183                        final boolean doNext = finishReceiverLocked(
14184                                receiver.asBinder(), r.resultCode, r.resultData,
14185                                r.resultExtras, r.resultAbort);
14186                        if (doNext) {
14187                            doTrim = true;
14188                            r.queue.processNextBroadcast(false);
14189                        }
14190                    }
14191
14192                    if (rl.app != null) {
14193                        rl.app.receivers.remove(rl);
14194                    }
14195                    removeReceiverLocked(rl);
14196                    if (rl.linkedToDeath) {
14197                        rl.linkedToDeath = false;
14198                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14199                    }
14200                }
14201            }
14202
14203            // If we actually concluded any broadcasts, we might now be able
14204            // to trim the recipients' apps from our working set
14205            if (doTrim) {
14206                trimApplications();
14207                return;
14208            }
14209
14210        } finally {
14211            Binder.restoreCallingIdentity(origId);
14212        }
14213    }
14214
14215    void removeReceiverLocked(ReceiverList rl) {
14216        mRegisteredReceivers.remove(rl.receiver.asBinder());
14217        int N = rl.size();
14218        for (int i=0; i<N; i++) {
14219            mReceiverResolver.removeFilter(rl.get(i));
14220        }
14221    }
14222
14223    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14224        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14225            ProcessRecord r = mLruProcesses.get(i);
14226            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14227                try {
14228                    r.thread.dispatchPackageBroadcast(cmd, packages);
14229                } catch (RemoteException ex) {
14230                }
14231            }
14232        }
14233    }
14234
14235    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14236            int[] users) {
14237        List<ResolveInfo> receivers = null;
14238        try {
14239            HashSet<ComponentName> singleUserReceivers = null;
14240            boolean scannedFirstReceivers = false;
14241            for (int user : users) {
14242                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14243                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14244                if (user != 0 && newReceivers != null) {
14245                    // If this is not the primary user, we need to check for
14246                    // any receivers that should be filtered out.
14247                    for (int i=0; i<newReceivers.size(); i++) {
14248                        ResolveInfo ri = newReceivers.get(i);
14249                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14250                            newReceivers.remove(i);
14251                            i--;
14252                        }
14253                    }
14254                }
14255                if (newReceivers != null && newReceivers.size() == 0) {
14256                    newReceivers = null;
14257                }
14258                if (receivers == null) {
14259                    receivers = newReceivers;
14260                } else if (newReceivers != null) {
14261                    // We need to concatenate the additional receivers
14262                    // found with what we have do far.  This would be easy,
14263                    // but we also need to de-dup any receivers that are
14264                    // singleUser.
14265                    if (!scannedFirstReceivers) {
14266                        // Collect any single user receivers we had already retrieved.
14267                        scannedFirstReceivers = true;
14268                        for (int i=0; i<receivers.size(); i++) {
14269                            ResolveInfo ri = receivers.get(i);
14270                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14271                                ComponentName cn = new ComponentName(
14272                                        ri.activityInfo.packageName, ri.activityInfo.name);
14273                                if (singleUserReceivers == null) {
14274                                    singleUserReceivers = new HashSet<ComponentName>();
14275                                }
14276                                singleUserReceivers.add(cn);
14277                            }
14278                        }
14279                    }
14280                    // Add the new results to the existing results, tracking
14281                    // and de-dupping single user receivers.
14282                    for (int i=0; i<newReceivers.size(); i++) {
14283                        ResolveInfo ri = newReceivers.get(i);
14284                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14285                            ComponentName cn = new ComponentName(
14286                                    ri.activityInfo.packageName, ri.activityInfo.name);
14287                            if (singleUserReceivers == null) {
14288                                singleUserReceivers = new HashSet<ComponentName>();
14289                            }
14290                            if (!singleUserReceivers.contains(cn)) {
14291                                singleUserReceivers.add(cn);
14292                                receivers.add(ri);
14293                            }
14294                        } else {
14295                            receivers.add(ri);
14296                        }
14297                    }
14298                }
14299            }
14300        } catch (RemoteException ex) {
14301            // pm is in same process, this will never happen.
14302        }
14303        return receivers;
14304    }
14305
14306    private final int broadcastIntentLocked(ProcessRecord callerApp,
14307            String callerPackage, Intent intent, String resolvedType,
14308            IIntentReceiver resultTo, int resultCode, String resultData,
14309            Bundle map, String requiredPermission, int appOp,
14310            boolean ordered, boolean sticky, int callingPid, int callingUid,
14311            int userId) {
14312        intent = new Intent(intent);
14313
14314        // By default broadcasts do not go to stopped apps.
14315        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14316
14317        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14318            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14319            + " ordered=" + ordered + " userid=" + userId);
14320        if ((resultTo != null) && !ordered) {
14321            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14322        }
14323
14324        userId = handleIncomingUser(callingPid, callingUid, userId,
14325                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14326
14327        // Make sure that the user who is receiving this broadcast is started.
14328        // If not, we will just skip it.
14329
14330
14331        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14332            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14333                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14334                Slog.w(TAG, "Skipping broadcast of " + intent
14335                        + ": user " + userId + " is stopped");
14336                return ActivityManager.BROADCAST_SUCCESS;
14337            }
14338        }
14339
14340        /*
14341         * Prevent non-system code (defined here to be non-persistent
14342         * processes) from sending protected broadcasts.
14343         */
14344        int callingAppId = UserHandle.getAppId(callingUid);
14345        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14346            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14347            || callingAppId == Process.NFC_UID || callingUid == 0) {
14348            // Always okay.
14349        } else if (callerApp == null || !callerApp.persistent) {
14350            try {
14351                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14352                        intent.getAction())) {
14353                    String msg = "Permission Denial: not allowed to send broadcast "
14354                            + intent.getAction() + " from pid="
14355                            + callingPid + ", uid=" + callingUid;
14356                    Slog.w(TAG, msg);
14357                    throw new SecurityException(msg);
14358                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14359                    // Special case for compatibility: we don't want apps to send this,
14360                    // but historically it has not been protected and apps may be using it
14361                    // to poke their own app widget.  So, instead of making it protected,
14362                    // just limit it to the caller.
14363                    if (callerApp == null) {
14364                        String msg = "Permission Denial: not allowed to send broadcast "
14365                                + intent.getAction() + " from unknown caller.";
14366                        Slog.w(TAG, msg);
14367                        throw new SecurityException(msg);
14368                    } else if (intent.getComponent() != null) {
14369                        // They are good enough to send to an explicit component...  verify
14370                        // it is being sent to the calling app.
14371                        if (!intent.getComponent().getPackageName().equals(
14372                                callerApp.info.packageName)) {
14373                            String msg = "Permission Denial: not allowed to send broadcast "
14374                                    + intent.getAction() + " to "
14375                                    + intent.getComponent().getPackageName() + " from "
14376                                    + callerApp.info.packageName;
14377                            Slog.w(TAG, msg);
14378                            throw new SecurityException(msg);
14379                        }
14380                    } else {
14381                        // Limit broadcast to their own package.
14382                        intent.setPackage(callerApp.info.packageName);
14383                    }
14384                }
14385            } catch (RemoteException e) {
14386                Slog.w(TAG, "Remote exception", e);
14387                return ActivityManager.BROADCAST_SUCCESS;
14388            }
14389        }
14390
14391        // Handle special intents: if this broadcast is from the package
14392        // manager about a package being removed, we need to remove all of
14393        // its activities from the history stack.
14394        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14395                intent.getAction());
14396        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14397                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14398                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14399                || uidRemoved) {
14400            if (checkComponentPermission(
14401                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14402                    callingPid, callingUid, -1, true)
14403                    == PackageManager.PERMISSION_GRANTED) {
14404                if (uidRemoved) {
14405                    final Bundle intentExtras = intent.getExtras();
14406                    final int uid = intentExtras != null
14407                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14408                    if (uid >= 0) {
14409                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14410                        synchronized (bs) {
14411                            bs.removeUidStatsLocked(uid);
14412                        }
14413                        mAppOpsService.uidRemoved(uid);
14414                    }
14415                } else {
14416                    // If resources are unavailable just force stop all
14417                    // those packages and flush the attribute cache as well.
14418                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14419                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14420                        if (list != null && (list.length > 0)) {
14421                            for (String pkg : list) {
14422                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14423                                        "storage unmount");
14424                            }
14425                            sendPackageBroadcastLocked(
14426                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14427                        }
14428                    } else {
14429                        Uri data = intent.getData();
14430                        String ssp;
14431                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14432                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14433                                    intent.getAction());
14434                            boolean fullUninstall = removed &&
14435                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14436                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14437                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14438                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14439                                        false, fullUninstall, userId,
14440                                        removed ? "pkg removed" : "pkg changed");
14441                            }
14442                            if (removed) {
14443                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14444                                        new String[] {ssp}, userId);
14445                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14446                                    mAppOpsService.packageRemoved(
14447                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14448
14449                                    // Remove all permissions granted from/to this package
14450                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14451                                }
14452                            }
14453                        }
14454                    }
14455                }
14456            } else {
14457                String msg = "Permission Denial: " + intent.getAction()
14458                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14459                        + ", uid=" + callingUid + ")"
14460                        + " requires "
14461                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14462                Slog.w(TAG, msg);
14463                throw new SecurityException(msg);
14464            }
14465
14466        // Special case for adding a package: by default turn on compatibility
14467        // mode.
14468        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14469            Uri data = intent.getData();
14470            String ssp;
14471            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14472                mCompatModePackages.handlePackageAddedLocked(ssp,
14473                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14474            }
14475        }
14476
14477        /*
14478         * If this is the time zone changed action, queue up a message that will reset the timezone
14479         * of all currently running processes. This message will get queued up before the broadcast
14480         * happens.
14481         */
14482        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14483            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14484        }
14485
14486        /*
14487         * If the user set the time, let all running processes know.
14488         */
14489        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14490            final int is24Hour = intent.getBooleanExtra(
14491                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14492            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14493        }
14494
14495        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14496            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14497        }
14498
14499        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14500            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14501            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14502        }
14503
14504        // Add to the sticky list if requested.
14505        if (sticky) {
14506            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14507                    callingPid, callingUid)
14508                    != PackageManager.PERMISSION_GRANTED) {
14509                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14510                        + callingPid + ", uid=" + callingUid
14511                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14512                Slog.w(TAG, msg);
14513                throw new SecurityException(msg);
14514            }
14515            if (requiredPermission != null) {
14516                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14517                        + " and enforce permission " + requiredPermission);
14518                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14519            }
14520            if (intent.getComponent() != null) {
14521                throw new SecurityException(
14522                        "Sticky broadcasts can't target a specific component");
14523            }
14524            // We use userId directly here, since the "all" target is maintained
14525            // as a separate set of sticky broadcasts.
14526            if (userId != UserHandle.USER_ALL) {
14527                // But first, if this is not a broadcast to all users, then
14528                // make sure it doesn't conflict with an existing broadcast to
14529                // all users.
14530                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14531                        UserHandle.USER_ALL);
14532                if (stickies != null) {
14533                    ArrayList<Intent> list = stickies.get(intent.getAction());
14534                    if (list != null) {
14535                        int N = list.size();
14536                        int i;
14537                        for (i=0; i<N; i++) {
14538                            if (intent.filterEquals(list.get(i))) {
14539                                throw new IllegalArgumentException(
14540                                        "Sticky broadcast " + intent + " for user "
14541                                        + userId + " conflicts with existing global broadcast");
14542                            }
14543                        }
14544                    }
14545                }
14546            }
14547            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14548            if (stickies == null) {
14549                stickies = new ArrayMap<String, ArrayList<Intent>>();
14550                mStickyBroadcasts.put(userId, stickies);
14551            }
14552            ArrayList<Intent> list = stickies.get(intent.getAction());
14553            if (list == null) {
14554                list = new ArrayList<Intent>();
14555                stickies.put(intent.getAction(), list);
14556            }
14557            int N = list.size();
14558            int i;
14559            for (i=0; i<N; i++) {
14560                if (intent.filterEquals(list.get(i))) {
14561                    // This sticky already exists, replace it.
14562                    list.set(i, new Intent(intent));
14563                    break;
14564                }
14565            }
14566            if (i >= N) {
14567                list.add(new Intent(intent));
14568            }
14569        }
14570
14571        int[] users;
14572        if (userId == UserHandle.USER_ALL) {
14573            // Caller wants broadcast to go to all started users.
14574            users = mStartedUserArray;
14575        } else {
14576            // Caller wants broadcast to go to one specific user.
14577            users = new int[] {userId};
14578        }
14579
14580        // Figure out who all will receive this broadcast.
14581        List receivers = null;
14582        List<BroadcastFilter> registeredReceivers = null;
14583        // Need to resolve the intent to interested receivers...
14584        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14585                 == 0) {
14586            receivers = collectReceiverComponents(intent, resolvedType, users);
14587        }
14588        if (intent.getComponent() == null) {
14589            registeredReceivers = mReceiverResolver.queryIntent(intent,
14590                    resolvedType, false, userId);
14591        }
14592
14593        final boolean replacePending =
14594                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14595
14596        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14597                + " replacePending=" + replacePending);
14598
14599        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14600        if (!ordered && NR > 0) {
14601            // If we are not serializing this broadcast, then send the
14602            // registered receivers separately so they don't wait for the
14603            // components to be launched.
14604            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14605            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14606                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14607                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14608                    ordered, sticky, false, userId);
14609            if (DEBUG_BROADCAST) Slog.v(
14610                    TAG, "Enqueueing parallel broadcast " + r);
14611            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14612            if (!replaced) {
14613                queue.enqueueParallelBroadcastLocked(r);
14614                queue.scheduleBroadcastsLocked();
14615            }
14616            registeredReceivers = null;
14617            NR = 0;
14618        }
14619
14620        // Merge into one list.
14621        int ir = 0;
14622        if (receivers != null) {
14623            // A special case for PACKAGE_ADDED: do not allow the package
14624            // being added to see this broadcast.  This prevents them from
14625            // using this as a back door to get run as soon as they are
14626            // installed.  Maybe in the future we want to have a special install
14627            // broadcast or such for apps, but we'd like to deliberately make
14628            // this decision.
14629            String skipPackages[] = null;
14630            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14631                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14632                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14633                Uri data = intent.getData();
14634                if (data != null) {
14635                    String pkgName = data.getSchemeSpecificPart();
14636                    if (pkgName != null) {
14637                        skipPackages = new String[] { pkgName };
14638                    }
14639                }
14640            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14641                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14642            }
14643            if (skipPackages != null && (skipPackages.length > 0)) {
14644                for (String skipPackage : skipPackages) {
14645                    if (skipPackage != null) {
14646                        int NT = receivers.size();
14647                        for (int it=0; it<NT; it++) {
14648                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14649                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14650                                receivers.remove(it);
14651                                it--;
14652                                NT--;
14653                            }
14654                        }
14655                    }
14656                }
14657            }
14658
14659            int NT = receivers != null ? receivers.size() : 0;
14660            int it = 0;
14661            ResolveInfo curt = null;
14662            BroadcastFilter curr = null;
14663            while (it < NT && ir < NR) {
14664                if (curt == null) {
14665                    curt = (ResolveInfo)receivers.get(it);
14666                }
14667                if (curr == null) {
14668                    curr = registeredReceivers.get(ir);
14669                }
14670                if (curr.getPriority() >= curt.priority) {
14671                    // Insert this broadcast record into the final list.
14672                    receivers.add(it, curr);
14673                    ir++;
14674                    curr = null;
14675                    it++;
14676                    NT++;
14677                } else {
14678                    // Skip to the next ResolveInfo in the final list.
14679                    it++;
14680                    curt = null;
14681                }
14682            }
14683        }
14684        while (ir < NR) {
14685            if (receivers == null) {
14686                receivers = new ArrayList();
14687            }
14688            receivers.add(registeredReceivers.get(ir));
14689            ir++;
14690        }
14691
14692        if ((receivers != null && receivers.size() > 0)
14693                || resultTo != null) {
14694            BroadcastQueue queue = broadcastQueueForIntent(intent);
14695            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14696                    callerPackage, callingPid, callingUid, resolvedType,
14697                    requiredPermission, appOp, receivers, resultTo, resultCode,
14698                    resultData, map, ordered, sticky, false, userId);
14699            if (DEBUG_BROADCAST) Slog.v(
14700                    TAG, "Enqueueing ordered broadcast " + r
14701                    + ": prev had " + queue.mOrderedBroadcasts.size());
14702            if (DEBUG_BROADCAST) {
14703                int seq = r.intent.getIntExtra("seq", -1);
14704                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14705            }
14706            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14707            if (!replaced) {
14708                queue.enqueueOrderedBroadcastLocked(r);
14709                queue.scheduleBroadcastsLocked();
14710            }
14711        }
14712
14713        return ActivityManager.BROADCAST_SUCCESS;
14714    }
14715
14716    final Intent verifyBroadcastLocked(Intent intent) {
14717        // Refuse possible leaked file descriptors
14718        if (intent != null && intent.hasFileDescriptors() == true) {
14719            throw new IllegalArgumentException("File descriptors passed in Intent");
14720        }
14721
14722        int flags = intent.getFlags();
14723
14724        if (!mProcessesReady) {
14725            // if the caller really truly claims to know what they're doing, go
14726            // ahead and allow the broadcast without launching any receivers
14727            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14728                intent = new Intent(intent);
14729                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14730            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14731                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14732                        + " before boot completion");
14733                throw new IllegalStateException("Cannot broadcast before boot completed");
14734            }
14735        }
14736
14737        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14738            throw new IllegalArgumentException(
14739                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14740        }
14741
14742        return intent;
14743    }
14744
14745    public final int broadcastIntent(IApplicationThread caller,
14746            Intent intent, String resolvedType, IIntentReceiver resultTo,
14747            int resultCode, String resultData, Bundle map,
14748            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14749        enforceNotIsolatedCaller("broadcastIntent");
14750        synchronized(this) {
14751            intent = verifyBroadcastLocked(intent);
14752
14753            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14754            final int callingPid = Binder.getCallingPid();
14755            final int callingUid = Binder.getCallingUid();
14756            final long origId = Binder.clearCallingIdentity();
14757            int res = broadcastIntentLocked(callerApp,
14758                    callerApp != null ? callerApp.info.packageName : null,
14759                    intent, resolvedType, resultTo,
14760                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14761                    callingPid, callingUid, userId);
14762            Binder.restoreCallingIdentity(origId);
14763            return res;
14764        }
14765    }
14766
14767    int broadcastIntentInPackage(String packageName, int uid,
14768            Intent intent, String resolvedType, IIntentReceiver resultTo,
14769            int resultCode, String resultData, Bundle map,
14770            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14771        synchronized(this) {
14772            intent = verifyBroadcastLocked(intent);
14773
14774            final long origId = Binder.clearCallingIdentity();
14775            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14776                    resultTo, resultCode, resultData, map, requiredPermission,
14777                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14778            Binder.restoreCallingIdentity(origId);
14779            return res;
14780        }
14781    }
14782
14783    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14784        // Refuse possible leaked file descriptors
14785        if (intent != null && intent.hasFileDescriptors() == true) {
14786            throw new IllegalArgumentException("File descriptors passed in Intent");
14787        }
14788
14789        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14790                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14791
14792        synchronized(this) {
14793            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14794                    != PackageManager.PERMISSION_GRANTED) {
14795                String msg = "Permission Denial: unbroadcastIntent() from pid="
14796                        + Binder.getCallingPid()
14797                        + ", uid=" + Binder.getCallingUid()
14798                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14799                Slog.w(TAG, msg);
14800                throw new SecurityException(msg);
14801            }
14802            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14803            if (stickies != null) {
14804                ArrayList<Intent> list = stickies.get(intent.getAction());
14805                if (list != null) {
14806                    int N = list.size();
14807                    int i;
14808                    for (i=0; i<N; i++) {
14809                        if (intent.filterEquals(list.get(i))) {
14810                            list.remove(i);
14811                            break;
14812                        }
14813                    }
14814                    if (list.size() <= 0) {
14815                        stickies.remove(intent.getAction());
14816                    }
14817                }
14818                if (stickies.size() <= 0) {
14819                    mStickyBroadcasts.remove(userId);
14820                }
14821            }
14822        }
14823    }
14824
14825    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14826            String resultData, Bundle resultExtras, boolean resultAbort) {
14827        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14828        if (r == null) {
14829            Slog.w(TAG, "finishReceiver called but not found on queue");
14830            return false;
14831        }
14832
14833        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14834    }
14835
14836    void backgroundServicesFinishedLocked(int userId) {
14837        for (BroadcastQueue queue : mBroadcastQueues) {
14838            queue.backgroundServicesFinishedLocked(userId);
14839        }
14840    }
14841
14842    public void finishReceiver(IBinder who, int resultCode, String resultData,
14843            Bundle resultExtras, boolean resultAbort) {
14844        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14845
14846        // Refuse possible leaked file descriptors
14847        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14848            throw new IllegalArgumentException("File descriptors passed in Bundle");
14849        }
14850
14851        final long origId = Binder.clearCallingIdentity();
14852        try {
14853            boolean doNext = false;
14854            BroadcastRecord r;
14855
14856            synchronized(this) {
14857                r = broadcastRecordForReceiverLocked(who);
14858                if (r != null) {
14859                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14860                        resultData, resultExtras, resultAbort, true);
14861                }
14862            }
14863
14864            if (doNext) {
14865                r.queue.processNextBroadcast(false);
14866            }
14867            trimApplications();
14868        } finally {
14869            Binder.restoreCallingIdentity(origId);
14870        }
14871    }
14872
14873    // =========================================================
14874    // INSTRUMENTATION
14875    // =========================================================
14876
14877    public boolean startInstrumentation(ComponentName className,
14878            String profileFile, int flags, Bundle arguments,
14879            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14880            int userId, String abiOverride) {
14881        enforceNotIsolatedCaller("startInstrumentation");
14882        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14883                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14884        // Refuse possible leaked file descriptors
14885        if (arguments != null && arguments.hasFileDescriptors()) {
14886            throw new IllegalArgumentException("File descriptors passed in Bundle");
14887        }
14888
14889        synchronized(this) {
14890            InstrumentationInfo ii = null;
14891            ApplicationInfo ai = null;
14892            try {
14893                ii = mContext.getPackageManager().getInstrumentationInfo(
14894                    className, STOCK_PM_FLAGS);
14895                ai = AppGlobals.getPackageManager().getApplicationInfo(
14896                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14897            } catch (PackageManager.NameNotFoundException e) {
14898            } catch (RemoteException e) {
14899            }
14900            if (ii == null) {
14901                reportStartInstrumentationFailure(watcher, className,
14902                        "Unable to find instrumentation info for: " + className);
14903                return false;
14904            }
14905            if (ai == null) {
14906                reportStartInstrumentationFailure(watcher, className,
14907                        "Unable to find instrumentation target package: " + ii.targetPackage);
14908                return false;
14909            }
14910
14911            int match = mContext.getPackageManager().checkSignatures(
14912                    ii.targetPackage, ii.packageName);
14913            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14914                String msg = "Permission Denial: starting instrumentation "
14915                        + className + " from pid="
14916                        + Binder.getCallingPid()
14917                        + ", uid=" + Binder.getCallingPid()
14918                        + " not allowed because package " + ii.packageName
14919                        + " does not have a signature matching the target "
14920                        + ii.targetPackage;
14921                reportStartInstrumentationFailure(watcher, className, msg);
14922                throw new SecurityException(msg);
14923            }
14924
14925            final long origId = Binder.clearCallingIdentity();
14926            // Instrumentation can kill and relaunch even persistent processes
14927            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14928                    "start instr");
14929            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14930            app.instrumentationClass = className;
14931            app.instrumentationInfo = ai;
14932            app.instrumentationProfileFile = profileFile;
14933            app.instrumentationArguments = arguments;
14934            app.instrumentationWatcher = watcher;
14935            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14936            app.instrumentationResultClass = className;
14937            Binder.restoreCallingIdentity(origId);
14938        }
14939
14940        return true;
14941    }
14942
14943    /**
14944     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14945     * error to the logs, but if somebody is watching, send the report there too.  This enables
14946     * the "am" command to report errors with more information.
14947     *
14948     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14949     * @param cn The component name of the instrumentation.
14950     * @param report The error report.
14951     */
14952    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14953            ComponentName cn, String report) {
14954        Slog.w(TAG, report);
14955        try {
14956            if (watcher != null) {
14957                Bundle results = new Bundle();
14958                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14959                results.putString("Error", report);
14960                watcher.instrumentationStatus(cn, -1, results);
14961            }
14962        } catch (RemoteException e) {
14963            Slog.w(TAG, e);
14964        }
14965    }
14966
14967    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14968        if (app.instrumentationWatcher != null) {
14969            try {
14970                // NOTE:  IInstrumentationWatcher *must* be oneway here
14971                app.instrumentationWatcher.instrumentationFinished(
14972                    app.instrumentationClass,
14973                    resultCode,
14974                    results);
14975            } catch (RemoteException e) {
14976            }
14977        }
14978        if (app.instrumentationUiAutomationConnection != null) {
14979            try {
14980                app.instrumentationUiAutomationConnection.shutdown();
14981            } catch (RemoteException re) {
14982                /* ignore */
14983            }
14984            // Only a UiAutomation can set this flag and now that
14985            // it is finished we make sure it is reset to its default.
14986            mUserIsMonkey = false;
14987        }
14988        app.instrumentationWatcher = null;
14989        app.instrumentationUiAutomationConnection = null;
14990        app.instrumentationClass = null;
14991        app.instrumentationInfo = null;
14992        app.instrumentationProfileFile = null;
14993        app.instrumentationArguments = null;
14994
14995        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14996                "finished inst");
14997    }
14998
14999    public void finishInstrumentation(IApplicationThread target,
15000            int resultCode, Bundle results) {
15001        int userId = UserHandle.getCallingUserId();
15002        // Refuse possible leaked file descriptors
15003        if (results != null && results.hasFileDescriptors()) {
15004            throw new IllegalArgumentException("File descriptors passed in Intent");
15005        }
15006
15007        synchronized(this) {
15008            ProcessRecord app = getRecordForAppLocked(target);
15009            if (app == null) {
15010                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15011                return;
15012            }
15013            final long origId = Binder.clearCallingIdentity();
15014            finishInstrumentationLocked(app, resultCode, results);
15015            Binder.restoreCallingIdentity(origId);
15016        }
15017    }
15018
15019    // =========================================================
15020    // CONFIGURATION
15021    // =========================================================
15022
15023    public ConfigurationInfo getDeviceConfigurationInfo() {
15024        ConfigurationInfo config = new ConfigurationInfo();
15025        synchronized (this) {
15026            config.reqTouchScreen = mConfiguration.touchscreen;
15027            config.reqKeyboardType = mConfiguration.keyboard;
15028            config.reqNavigation = mConfiguration.navigation;
15029            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15030                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15031                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15032            }
15033            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15034                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15035                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15036            }
15037            config.reqGlEsVersion = GL_ES_VERSION;
15038        }
15039        return config;
15040    }
15041
15042    ActivityStack getFocusedStack() {
15043        return mStackSupervisor.getFocusedStack();
15044    }
15045
15046    public Configuration getConfiguration() {
15047        Configuration ci;
15048        synchronized(this) {
15049            ci = new Configuration(mConfiguration);
15050        }
15051        return ci;
15052    }
15053
15054    public void updatePersistentConfiguration(Configuration values) {
15055        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15056                "updateConfiguration()");
15057        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15058                "updateConfiguration()");
15059        if (values == null) {
15060            throw new NullPointerException("Configuration must not be null");
15061        }
15062
15063        synchronized(this) {
15064            final long origId = Binder.clearCallingIdentity();
15065            updateConfigurationLocked(values, null, true, false);
15066            Binder.restoreCallingIdentity(origId);
15067        }
15068    }
15069
15070    public void updateConfiguration(Configuration values) {
15071        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15072                "updateConfiguration()");
15073
15074        synchronized(this) {
15075            if (values == null && mWindowManager != null) {
15076                // sentinel: fetch the current configuration from the window manager
15077                values = mWindowManager.computeNewConfiguration();
15078            }
15079
15080            if (mWindowManager != null) {
15081                mProcessList.applyDisplaySize(mWindowManager);
15082            }
15083
15084            final long origId = Binder.clearCallingIdentity();
15085            if (values != null) {
15086                Settings.System.clearConfiguration(values);
15087            }
15088            updateConfigurationLocked(values, null, false, false);
15089            Binder.restoreCallingIdentity(origId);
15090        }
15091    }
15092
15093    /**
15094     * Do either or both things: (1) change the current configuration, and (2)
15095     * make sure the given activity is running with the (now) current
15096     * configuration.  Returns true if the activity has been left running, or
15097     * false if <var>starting</var> is being destroyed to match the new
15098     * configuration.
15099     * @param persistent TODO
15100     */
15101    boolean updateConfigurationLocked(Configuration values,
15102            ActivityRecord starting, boolean persistent, boolean initLocale) {
15103        int changes = 0;
15104
15105        if (values != null) {
15106            Configuration newConfig = new Configuration(mConfiguration);
15107            changes = newConfig.updateFrom(values);
15108            if (changes != 0) {
15109                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15110                    Slog.i(TAG, "Updating configuration to: " + values);
15111                }
15112
15113                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15114
15115                if (values.locale != null && !initLocale) {
15116                    saveLocaleLocked(values.locale,
15117                                     !values.locale.equals(mConfiguration.locale),
15118                                     values.userSetLocale);
15119                }
15120
15121                mConfigurationSeq++;
15122                if (mConfigurationSeq <= 0) {
15123                    mConfigurationSeq = 1;
15124                }
15125                newConfig.seq = mConfigurationSeq;
15126                mConfiguration = newConfig;
15127                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15128                //mUsageStatsService.noteStartConfig(newConfig);
15129
15130                final Configuration configCopy = new Configuration(mConfiguration);
15131
15132                // TODO: If our config changes, should we auto dismiss any currently
15133                // showing dialogs?
15134                mShowDialogs = shouldShowDialogs(newConfig);
15135
15136                AttributeCache ac = AttributeCache.instance();
15137                if (ac != null) {
15138                    ac.updateConfiguration(configCopy);
15139                }
15140
15141                // Make sure all resources in our process are updated
15142                // right now, so that anyone who is going to retrieve
15143                // resource values after we return will be sure to get
15144                // the new ones.  This is especially important during
15145                // boot, where the first config change needs to guarantee
15146                // all resources have that config before following boot
15147                // code is executed.
15148                mSystemThread.applyConfigurationToResources(configCopy);
15149
15150                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15151                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15152                    msg.obj = new Configuration(configCopy);
15153                    mHandler.sendMessage(msg);
15154                }
15155
15156                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15157                    ProcessRecord app = mLruProcesses.get(i);
15158                    try {
15159                        if (app.thread != null) {
15160                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15161                                    + app.processName + " new config " + mConfiguration);
15162                            app.thread.scheduleConfigurationChanged(configCopy);
15163                        }
15164                    } catch (Exception e) {
15165                    }
15166                }
15167                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15168                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15169                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15170                        | Intent.FLAG_RECEIVER_FOREGROUND);
15171                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15172                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15173                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15174                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15175                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15176                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15177                    broadcastIntentLocked(null, null, intent,
15178                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15179                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15180                }
15181            }
15182        }
15183
15184        boolean kept = true;
15185        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15186        // mainStack is null during startup.
15187        if (mainStack != null) {
15188            if (changes != 0 && starting == null) {
15189                // If the configuration changed, and the caller is not already
15190                // in the process of starting an activity, then find the top
15191                // activity to check if its configuration needs to change.
15192                starting = mainStack.topRunningActivityLocked(null);
15193            }
15194
15195            if (starting != null) {
15196                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15197                // And we need to make sure at this point that all other activities
15198                // are made visible with the correct configuration.
15199                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15200            }
15201        }
15202
15203        if (values != null && mWindowManager != null) {
15204            mWindowManager.setNewConfiguration(mConfiguration);
15205        }
15206
15207        return kept;
15208    }
15209
15210    /**
15211     * Decide based on the configuration whether we should shouw the ANR,
15212     * crash, etc dialogs.  The idea is that if there is no affordnace to
15213     * press the on-screen buttons, we shouldn't show the dialog.
15214     *
15215     * A thought: SystemUI might also want to get told about this, the Power
15216     * dialog / global actions also might want different behaviors.
15217     */
15218    private static final boolean shouldShowDialogs(Configuration config) {
15219        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15220                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15221    }
15222
15223    /**
15224     * Save the locale.  You must be inside a synchronized (this) block.
15225     */
15226    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15227        if(isDiff) {
15228            SystemProperties.set("user.language", l.getLanguage());
15229            SystemProperties.set("user.region", l.getCountry());
15230        }
15231
15232        if(isPersist) {
15233            SystemProperties.set("persist.sys.language", l.getLanguage());
15234            SystemProperties.set("persist.sys.country", l.getCountry());
15235            SystemProperties.set("persist.sys.localevar", l.getVariant());
15236        }
15237    }
15238
15239    @Override
15240    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15241        ActivityRecord srec = ActivityRecord.forToken(token);
15242        return srec != null && srec.task.affinity != null &&
15243                srec.task.affinity.equals(destAffinity);
15244    }
15245
15246    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15247            Intent resultData) {
15248
15249        synchronized (this) {
15250            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15251            if (stack != null) {
15252                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15253            }
15254            return false;
15255        }
15256    }
15257
15258    public int getLaunchedFromUid(IBinder activityToken) {
15259        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15260        if (srec == null) {
15261            return -1;
15262        }
15263        return srec.launchedFromUid;
15264    }
15265
15266    public String getLaunchedFromPackage(IBinder activityToken) {
15267        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15268        if (srec == null) {
15269            return null;
15270        }
15271        return srec.launchedFromPackage;
15272    }
15273
15274    // =========================================================
15275    // LIFETIME MANAGEMENT
15276    // =========================================================
15277
15278    // Returns which broadcast queue the app is the current [or imminent] receiver
15279    // on, or 'null' if the app is not an active broadcast recipient.
15280    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15281        BroadcastRecord r = app.curReceiver;
15282        if (r != null) {
15283            return r.queue;
15284        }
15285
15286        // It's not the current receiver, but it might be starting up to become one
15287        synchronized (this) {
15288            for (BroadcastQueue queue : mBroadcastQueues) {
15289                r = queue.mPendingBroadcast;
15290                if (r != null && r.curApp == app) {
15291                    // found it; report which queue it's in
15292                    return queue;
15293                }
15294            }
15295        }
15296
15297        return null;
15298    }
15299
15300    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15301            boolean doingAll, long now) {
15302        if (mAdjSeq == app.adjSeq) {
15303            // This adjustment has already been computed.
15304            return app.curRawAdj;
15305        }
15306
15307        if (app.thread == null) {
15308            app.adjSeq = mAdjSeq;
15309            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15310            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15311            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15312        }
15313
15314        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15315        app.adjSource = null;
15316        app.adjTarget = null;
15317        app.empty = false;
15318        app.cached = false;
15319
15320        final int activitiesSize = app.activities.size();
15321
15322        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15323            // The max adjustment doesn't allow this app to be anything
15324            // below foreground, so it is not worth doing work for it.
15325            app.adjType = "fixed";
15326            app.adjSeq = mAdjSeq;
15327            app.curRawAdj = app.maxAdj;
15328            app.foregroundActivities = false;
15329            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15330            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15331            // System processes can do UI, and when they do we want to have
15332            // them trim their memory after the user leaves the UI.  To
15333            // facilitate this, here we need to determine whether or not it
15334            // is currently showing UI.
15335            app.systemNoUi = true;
15336            if (app == TOP_APP) {
15337                app.systemNoUi = false;
15338            } else if (activitiesSize > 0) {
15339                for (int j = 0; j < activitiesSize; j++) {
15340                    final ActivityRecord r = app.activities.get(j);
15341                    if (r.visible) {
15342                        app.systemNoUi = false;
15343                    }
15344                }
15345            }
15346            if (!app.systemNoUi) {
15347                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15348            }
15349            return (app.curAdj=app.maxAdj);
15350        }
15351
15352        app.systemNoUi = false;
15353
15354        // Determine the importance of the process, starting with most
15355        // important to least, and assign an appropriate OOM adjustment.
15356        int adj;
15357        int schedGroup;
15358        int procState;
15359        boolean foregroundActivities = false;
15360        BroadcastQueue queue;
15361        if (app == TOP_APP) {
15362            // The last app on the list is the foreground app.
15363            adj = ProcessList.FOREGROUND_APP_ADJ;
15364            schedGroup = Process.THREAD_GROUP_DEFAULT;
15365            app.adjType = "top-activity";
15366            foregroundActivities = true;
15367            procState = ActivityManager.PROCESS_STATE_TOP;
15368        } else if (app.instrumentationClass != null) {
15369            // Don't want to kill running instrumentation.
15370            adj = ProcessList.FOREGROUND_APP_ADJ;
15371            schedGroup = Process.THREAD_GROUP_DEFAULT;
15372            app.adjType = "instrumentation";
15373            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15374        } else if ((queue = isReceivingBroadcast(app)) != null) {
15375            // An app that is currently receiving a broadcast also
15376            // counts as being in the foreground for OOM killer purposes.
15377            // It's placed in a sched group based on the nature of the
15378            // broadcast as reflected by which queue it's active in.
15379            adj = ProcessList.FOREGROUND_APP_ADJ;
15380            schedGroup = (queue == mFgBroadcastQueue)
15381                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15382            app.adjType = "broadcast";
15383            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15384        } else if (app.executingServices.size() > 0) {
15385            // An app that is currently executing a service callback also
15386            // counts as being in the foreground.
15387            adj = ProcessList.FOREGROUND_APP_ADJ;
15388            schedGroup = app.execServicesFg ?
15389                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15390            app.adjType = "exec-service";
15391            procState = ActivityManager.PROCESS_STATE_SERVICE;
15392            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15393        } else {
15394            // As far as we know the process is empty.  We may change our mind later.
15395            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15396            // At this point we don't actually know the adjustment.  Use the cached adj
15397            // value that the caller wants us to.
15398            adj = cachedAdj;
15399            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15400            app.cached = true;
15401            app.empty = true;
15402            app.adjType = "cch-empty";
15403        }
15404
15405        // Examine all activities if not already foreground.
15406        if (!foregroundActivities && activitiesSize > 0) {
15407            for (int j = 0; j < activitiesSize; j++) {
15408                final ActivityRecord r = app.activities.get(j);
15409                if (r.app != app) {
15410                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15411                            + app + "?!?");
15412                    continue;
15413                }
15414                if (r.visible) {
15415                    // App has a visible activity; only upgrade adjustment.
15416                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15417                        adj = ProcessList.VISIBLE_APP_ADJ;
15418                        app.adjType = "visible";
15419                    }
15420                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15421                        procState = ActivityManager.PROCESS_STATE_TOP;
15422                    }
15423                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15424                    app.cached = false;
15425                    app.empty = false;
15426                    foregroundActivities = true;
15427                    break;
15428                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15429                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15430                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15431                        app.adjType = "pausing";
15432                    }
15433                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15434                        procState = ActivityManager.PROCESS_STATE_TOP;
15435                    }
15436                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15437                    app.cached = false;
15438                    app.empty = false;
15439                    foregroundActivities = true;
15440                } else if (r.state == ActivityState.STOPPING) {
15441                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15442                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15443                        app.adjType = "stopping";
15444                    }
15445                    // For the process state, we will at this point consider the
15446                    // process to be cached.  It will be cached either as an activity
15447                    // or empty depending on whether the activity is finishing.  We do
15448                    // this so that we can treat the process as cached for purposes of
15449                    // memory trimming (determing current memory level, trim command to
15450                    // send to process) since there can be an arbitrary number of stopping
15451                    // processes and they should soon all go into the cached state.
15452                    if (!r.finishing) {
15453                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15454                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15455                        }
15456                    }
15457                    app.cached = false;
15458                    app.empty = false;
15459                    foregroundActivities = true;
15460                } else {
15461                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15462                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15463                        app.adjType = "cch-act";
15464                    }
15465                }
15466            }
15467        }
15468
15469        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15470            if (app.foregroundServices) {
15471                // The user is aware of this app, so make it visible.
15472                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15473                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15474                app.cached = false;
15475                app.adjType = "fg-service";
15476                schedGroup = Process.THREAD_GROUP_DEFAULT;
15477            } else if (app.forcingToForeground != null) {
15478                // The user is aware of this app, so make it visible.
15479                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15480                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15481                app.cached = false;
15482                app.adjType = "force-fg";
15483                app.adjSource = app.forcingToForeground;
15484                schedGroup = Process.THREAD_GROUP_DEFAULT;
15485            }
15486        }
15487
15488        if (app == mHeavyWeightProcess) {
15489            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15490                // We don't want to kill the current heavy-weight process.
15491                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15492                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15493                app.cached = false;
15494                app.adjType = "heavy";
15495            }
15496            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15497                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15498            }
15499        }
15500
15501        if (app == mHomeProcess) {
15502            if (adj > ProcessList.HOME_APP_ADJ) {
15503                // This process is hosting what we currently consider to be the
15504                // home app, so we don't want to let it go into the background.
15505                adj = ProcessList.HOME_APP_ADJ;
15506                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15507                app.cached = false;
15508                app.adjType = "home";
15509            }
15510            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15511                procState = ActivityManager.PROCESS_STATE_HOME;
15512            }
15513        }
15514
15515        if (app == mPreviousProcess && app.activities.size() > 0) {
15516            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15517                // This was the previous process that showed UI to the user.
15518                // We want to try to keep it around more aggressively, to give
15519                // a good experience around switching between two apps.
15520                adj = ProcessList.PREVIOUS_APP_ADJ;
15521                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15522                app.cached = false;
15523                app.adjType = "previous";
15524            }
15525            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15526                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15527            }
15528        }
15529
15530        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15531                + " reason=" + app.adjType);
15532
15533        // By default, we use the computed adjustment.  It may be changed if
15534        // there are applications dependent on our services or providers, but
15535        // this gives us a baseline and makes sure we don't get into an
15536        // infinite recursion.
15537        app.adjSeq = mAdjSeq;
15538        app.curRawAdj = adj;
15539        app.hasStartedServices = false;
15540
15541        if (mBackupTarget != null && app == mBackupTarget.app) {
15542            // If possible we want to avoid killing apps while they're being backed up
15543            if (adj > ProcessList.BACKUP_APP_ADJ) {
15544                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15545                adj = ProcessList.BACKUP_APP_ADJ;
15546                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15547                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15548                }
15549                app.adjType = "backup";
15550                app.cached = false;
15551            }
15552            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15553                procState = ActivityManager.PROCESS_STATE_BACKUP;
15554            }
15555        }
15556
15557        boolean mayBeTop = false;
15558
15559        for (int is = app.services.size()-1;
15560                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15561                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15562                        || procState > ActivityManager.PROCESS_STATE_TOP);
15563                is--) {
15564            ServiceRecord s = app.services.valueAt(is);
15565            if (s.startRequested) {
15566                app.hasStartedServices = true;
15567                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15568                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15569                }
15570                if (app.hasShownUi && app != mHomeProcess) {
15571                    // If this process has shown some UI, let it immediately
15572                    // go to the LRU list because it may be pretty heavy with
15573                    // UI stuff.  We'll tag it with a label just to help
15574                    // debug and understand what is going on.
15575                    if (adj > ProcessList.SERVICE_ADJ) {
15576                        app.adjType = "cch-started-ui-services";
15577                    }
15578                } else {
15579                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15580                        // This service has seen some activity within
15581                        // recent memory, so we will keep its process ahead
15582                        // of the background processes.
15583                        if (adj > ProcessList.SERVICE_ADJ) {
15584                            adj = ProcessList.SERVICE_ADJ;
15585                            app.adjType = "started-services";
15586                            app.cached = false;
15587                        }
15588                    }
15589                    // If we have let the service slide into the background
15590                    // state, still have some text describing what it is doing
15591                    // even though the service no longer has an impact.
15592                    if (adj > ProcessList.SERVICE_ADJ) {
15593                        app.adjType = "cch-started-services";
15594                    }
15595                }
15596            }
15597            for (int conni = s.connections.size()-1;
15598                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15599                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15600                            || procState > ActivityManager.PROCESS_STATE_TOP);
15601                    conni--) {
15602                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15603                for (int i = 0;
15604                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15605                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15606                                || procState > ActivityManager.PROCESS_STATE_TOP);
15607                        i++) {
15608                    // XXX should compute this based on the max of
15609                    // all connected clients.
15610                    ConnectionRecord cr = clist.get(i);
15611                    if (cr.binding.client == app) {
15612                        // Binding to ourself is not interesting.
15613                        continue;
15614                    }
15615                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15616                        ProcessRecord client = cr.binding.client;
15617                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15618                                TOP_APP, doingAll, now);
15619                        int clientProcState = client.curProcState;
15620                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15621                            // If the other app is cached for any reason, for purposes here
15622                            // we are going to consider it empty.  The specific cached state
15623                            // doesn't propagate except under certain conditions.
15624                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15625                        }
15626                        String adjType = null;
15627                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15628                            // Not doing bind OOM management, so treat
15629                            // this guy more like a started service.
15630                            if (app.hasShownUi && app != mHomeProcess) {
15631                                // If this process has shown some UI, let it immediately
15632                                // go to the LRU list because it may be pretty heavy with
15633                                // UI stuff.  We'll tag it with a label just to help
15634                                // debug and understand what is going on.
15635                                if (adj > clientAdj) {
15636                                    adjType = "cch-bound-ui-services";
15637                                }
15638                                app.cached = false;
15639                                clientAdj = adj;
15640                                clientProcState = procState;
15641                            } else {
15642                                if (now >= (s.lastActivity
15643                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15644                                    // This service has not seen activity within
15645                                    // recent memory, so allow it to drop to the
15646                                    // LRU list if there is no other reason to keep
15647                                    // it around.  We'll also tag it with a label just
15648                                    // to help debug and undertand what is going on.
15649                                    if (adj > clientAdj) {
15650                                        adjType = "cch-bound-services";
15651                                    }
15652                                    clientAdj = adj;
15653                                }
15654                            }
15655                        }
15656                        if (adj > clientAdj) {
15657                            // If this process has recently shown UI, and
15658                            // the process that is binding to it is less
15659                            // important than being visible, then we don't
15660                            // care about the binding as much as we care
15661                            // about letting this process get into the LRU
15662                            // list to be killed and restarted if needed for
15663                            // memory.
15664                            if (app.hasShownUi && app != mHomeProcess
15665                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15666                                adjType = "cch-bound-ui-services";
15667                            } else {
15668                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15669                                        |Context.BIND_IMPORTANT)) != 0) {
15670                                    adj = clientAdj;
15671                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15672                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15673                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15674                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15675                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15676                                    adj = clientAdj;
15677                                } else {
15678                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15679                                        adj = ProcessList.VISIBLE_APP_ADJ;
15680                                    }
15681                                }
15682                                if (!client.cached) {
15683                                    app.cached = false;
15684                                }
15685                                adjType = "service";
15686                            }
15687                        }
15688                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15689                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15690                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15691                            }
15692                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15693                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15694                                    // Special handling of clients who are in the top state.
15695                                    // We *may* want to consider this process to be in the
15696                                    // top state as well, but only if there is not another
15697                                    // reason for it to be running.  Being on the top is a
15698                                    // special state, meaning you are specifically running
15699                                    // for the current top app.  If the process is already
15700                                    // running in the background for some other reason, it
15701                                    // is more important to continue considering it to be
15702                                    // in the background state.
15703                                    mayBeTop = true;
15704                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15705                                } else {
15706                                    // Special handling for above-top states (persistent
15707                                    // processes).  These should not bring the current process
15708                                    // into the top state, since they are not on top.  Instead
15709                                    // give them the best state after that.
15710                                    clientProcState =
15711                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15712                                }
15713                            }
15714                        } else {
15715                            if (clientProcState <
15716                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15717                                clientProcState =
15718                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15719                            }
15720                        }
15721                        if (procState > clientProcState) {
15722                            procState = clientProcState;
15723                        }
15724                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15725                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15726                            app.pendingUiClean = true;
15727                        }
15728                        if (adjType != null) {
15729                            app.adjType = adjType;
15730                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15731                                    .REASON_SERVICE_IN_USE;
15732                            app.adjSource = cr.binding.client;
15733                            app.adjSourceProcState = clientProcState;
15734                            app.adjTarget = s.name;
15735                        }
15736                    }
15737                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15738                        app.treatLikeActivity = true;
15739                    }
15740                    final ActivityRecord a = cr.activity;
15741                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15742                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15743                                (a.visible || a.state == ActivityState.RESUMED
15744                                 || a.state == ActivityState.PAUSING)) {
15745                            adj = ProcessList.FOREGROUND_APP_ADJ;
15746                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15747                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15748                            }
15749                            app.cached = false;
15750                            app.adjType = "service";
15751                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15752                                    .REASON_SERVICE_IN_USE;
15753                            app.adjSource = a;
15754                            app.adjSourceProcState = procState;
15755                            app.adjTarget = s.name;
15756                        }
15757                    }
15758                }
15759            }
15760        }
15761
15762        for (int provi = app.pubProviders.size()-1;
15763                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15764                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15765                        || procState > ActivityManager.PROCESS_STATE_TOP);
15766                provi--) {
15767            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15768            for (int i = cpr.connections.size()-1;
15769                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15770                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15771                            || procState > ActivityManager.PROCESS_STATE_TOP);
15772                    i--) {
15773                ContentProviderConnection conn = cpr.connections.get(i);
15774                ProcessRecord client = conn.client;
15775                if (client == app) {
15776                    // Being our own client is not interesting.
15777                    continue;
15778                }
15779                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15780                int clientProcState = client.curProcState;
15781                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15782                    // If the other app is cached for any reason, for purposes here
15783                    // we are going to consider it empty.
15784                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15785                }
15786                if (adj > clientAdj) {
15787                    if (app.hasShownUi && app != mHomeProcess
15788                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15789                        app.adjType = "cch-ui-provider";
15790                    } else {
15791                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15792                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15793                        app.adjType = "provider";
15794                    }
15795                    app.cached &= client.cached;
15796                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15797                            .REASON_PROVIDER_IN_USE;
15798                    app.adjSource = client;
15799                    app.adjSourceProcState = clientProcState;
15800                    app.adjTarget = cpr.name;
15801                }
15802                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15803                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15804                        // Special handling of clients who are in the top state.
15805                        // We *may* want to consider this process to be in the
15806                        // top state as well, but only if there is not another
15807                        // reason for it to be running.  Being on the top is a
15808                        // special state, meaning you are specifically running
15809                        // for the current top app.  If the process is already
15810                        // running in the background for some other reason, it
15811                        // is more important to continue considering it to be
15812                        // in the background state.
15813                        mayBeTop = true;
15814                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15815                    } else {
15816                        // Special handling for above-top states (persistent
15817                        // processes).  These should not bring the current process
15818                        // into the top state, since they are not on top.  Instead
15819                        // give them the best state after that.
15820                        clientProcState =
15821                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15822                    }
15823                }
15824                if (procState > clientProcState) {
15825                    procState = clientProcState;
15826                }
15827                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15828                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15829                }
15830            }
15831            // If the provider has external (non-framework) process
15832            // dependencies, ensure that its adjustment is at least
15833            // FOREGROUND_APP_ADJ.
15834            if (cpr.hasExternalProcessHandles()) {
15835                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15836                    adj = ProcessList.FOREGROUND_APP_ADJ;
15837                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15838                    app.cached = false;
15839                    app.adjType = "provider";
15840                    app.adjTarget = cpr.name;
15841                }
15842                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15843                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15844                }
15845            }
15846        }
15847
15848        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15849            // A client of one of our services or providers is in the top state.  We
15850            // *may* want to be in the top state, but not if we are already running in
15851            // the background for some other reason.  For the decision here, we are going
15852            // to pick out a few specific states that we want to remain in when a client
15853            // is top (states that tend to be longer-term) and otherwise allow it to go
15854            // to the top state.
15855            switch (procState) {
15856                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15857                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15858                case ActivityManager.PROCESS_STATE_SERVICE:
15859                    // These all are longer-term states, so pull them up to the top
15860                    // of the background states, but not all the way to the top state.
15861                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15862                    break;
15863                default:
15864                    // Otherwise, top is a better choice, so take it.
15865                    procState = ActivityManager.PROCESS_STATE_TOP;
15866                    break;
15867            }
15868        }
15869
15870        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15871            if (app.hasClientActivities) {
15872                // This is a cached process, but with client activities.  Mark it so.
15873                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15874                app.adjType = "cch-client-act";
15875            } else if (app.treatLikeActivity) {
15876                // This is a cached process, but somebody wants us to treat it like it has
15877                // an activity, okay!
15878                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15879                app.adjType = "cch-as-act";
15880            }
15881        }
15882
15883        if (adj == ProcessList.SERVICE_ADJ) {
15884            if (doingAll) {
15885                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15886                mNewNumServiceProcs++;
15887                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15888                if (!app.serviceb) {
15889                    // This service isn't far enough down on the LRU list to
15890                    // normally be a B service, but if we are low on RAM and it
15891                    // is large we want to force it down since we would prefer to
15892                    // keep launcher over it.
15893                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15894                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15895                        app.serviceHighRam = true;
15896                        app.serviceb = true;
15897                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15898                    } else {
15899                        mNewNumAServiceProcs++;
15900                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15901                    }
15902                } else {
15903                    app.serviceHighRam = false;
15904                }
15905            }
15906            if (app.serviceb) {
15907                adj = ProcessList.SERVICE_B_ADJ;
15908            }
15909        }
15910
15911        app.curRawAdj = adj;
15912
15913        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15914        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15915        if (adj > app.maxAdj) {
15916            adj = app.maxAdj;
15917            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15918                schedGroup = Process.THREAD_GROUP_DEFAULT;
15919            }
15920        }
15921
15922        // Do final modification to adj.  Everything we do between here and applying
15923        // the final setAdj must be done in this function, because we will also use
15924        // it when computing the final cached adj later.  Note that we don't need to
15925        // worry about this for max adj above, since max adj will always be used to
15926        // keep it out of the cached vaues.
15927        app.curAdj = app.modifyRawOomAdj(adj);
15928        app.curSchedGroup = schedGroup;
15929        app.curProcState = procState;
15930        app.foregroundActivities = foregroundActivities;
15931
15932        return app.curRawAdj;
15933    }
15934
15935    /**
15936     * Schedule PSS collection of a process.
15937     */
15938    void requestPssLocked(ProcessRecord proc, int procState) {
15939        if (mPendingPssProcesses.contains(proc)) {
15940            return;
15941        }
15942        if (mPendingPssProcesses.size() == 0) {
15943            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15944        }
15945        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15946        proc.pssProcState = procState;
15947        mPendingPssProcesses.add(proc);
15948    }
15949
15950    /**
15951     * Schedule PSS collection of all processes.
15952     */
15953    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15954        if (!always) {
15955            if (now < (mLastFullPssTime +
15956                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15957                return;
15958            }
15959        }
15960        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15961        mLastFullPssTime = now;
15962        mFullPssPending = true;
15963        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15964        mPendingPssProcesses.clear();
15965        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15966            ProcessRecord app = mLruProcesses.get(i);
15967            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15968                app.pssProcState = app.setProcState;
15969                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15970                        isSleeping(), now);
15971                mPendingPssProcesses.add(app);
15972            }
15973        }
15974        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15975    }
15976
15977    /**
15978     * Ask a given process to GC right now.
15979     */
15980    final void performAppGcLocked(ProcessRecord app) {
15981        try {
15982            app.lastRequestedGc = SystemClock.uptimeMillis();
15983            if (app.thread != null) {
15984                if (app.reportLowMemory) {
15985                    app.reportLowMemory = false;
15986                    app.thread.scheduleLowMemory();
15987                } else {
15988                    app.thread.processInBackground();
15989                }
15990            }
15991        } catch (Exception e) {
15992            // whatever.
15993        }
15994    }
15995
15996    /**
15997     * Returns true if things are idle enough to perform GCs.
15998     */
15999    private final boolean canGcNowLocked() {
16000        boolean processingBroadcasts = false;
16001        for (BroadcastQueue q : mBroadcastQueues) {
16002            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16003                processingBroadcasts = true;
16004            }
16005        }
16006        return !processingBroadcasts
16007                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16008    }
16009
16010    /**
16011     * Perform GCs on all processes that are waiting for it, but only
16012     * if things are idle.
16013     */
16014    final void performAppGcsLocked() {
16015        final int N = mProcessesToGc.size();
16016        if (N <= 0) {
16017            return;
16018        }
16019        if (canGcNowLocked()) {
16020            while (mProcessesToGc.size() > 0) {
16021                ProcessRecord proc = mProcessesToGc.remove(0);
16022                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16023                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16024                            <= SystemClock.uptimeMillis()) {
16025                        // To avoid spamming the system, we will GC processes one
16026                        // at a time, waiting a few seconds between each.
16027                        performAppGcLocked(proc);
16028                        scheduleAppGcsLocked();
16029                        return;
16030                    } else {
16031                        // It hasn't been long enough since we last GCed this
16032                        // process...  put it in the list to wait for its time.
16033                        addProcessToGcListLocked(proc);
16034                        break;
16035                    }
16036                }
16037            }
16038
16039            scheduleAppGcsLocked();
16040        }
16041    }
16042
16043    /**
16044     * If all looks good, perform GCs on all processes waiting for them.
16045     */
16046    final void performAppGcsIfAppropriateLocked() {
16047        if (canGcNowLocked()) {
16048            performAppGcsLocked();
16049            return;
16050        }
16051        // Still not idle, wait some more.
16052        scheduleAppGcsLocked();
16053    }
16054
16055    /**
16056     * Schedule the execution of all pending app GCs.
16057     */
16058    final void scheduleAppGcsLocked() {
16059        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16060
16061        if (mProcessesToGc.size() > 0) {
16062            // Schedule a GC for the time to the next process.
16063            ProcessRecord proc = mProcessesToGc.get(0);
16064            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16065
16066            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16067            long now = SystemClock.uptimeMillis();
16068            if (when < (now+GC_TIMEOUT)) {
16069                when = now + GC_TIMEOUT;
16070            }
16071            mHandler.sendMessageAtTime(msg, when);
16072        }
16073    }
16074
16075    /**
16076     * Add a process to the array of processes waiting to be GCed.  Keeps the
16077     * list in sorted order by the last GC time.  The process can't already be
16078     * on the list.
16079     */
16080    final void addProcessToGcListLocked(ProcessRecord proc) {
16081        boolean added = false;
16082        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16083            if (mProcessesToGc.get(i).lastRequestedGc <
16084                    proc.lastRequestedGc) {
16085                added = true;
16086                mProcessesToGc.add(i+1, proc);
16087                break;
16088            }
16089        }
16090        if (!added) {
16091            mProcessesToGc.add(0, proc);
16092        }
16093    }
16094
16095    /**
16096     * Set up to ask a process to GC itself.  This will either do it
16097     * immediately, or put it on the list of processes to gc the next
16098     * time things are idle.
16099     */
16100    final void scheduleAppGcLocked(ProcessRecord app) {
16101        long now = SystemClock.uptimeMillis();
16102        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16103            return;
16104        }
16105        if (!mProcessesToGc.contains(app)) {
16106            addProcessToGcListLocked(app);
16107            scheduleAppGcsLocked();
16108        }
16109    }
16110
16111    final void checkExcessivePowerUsageLocked(boolean doKills) {
16112        updateCpuStatsNow();
16113
16114        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16115        boolean doWakeKills = doKills;
16116        boolean doCpuKills = doKills;
16117        if (mLastPowerCheckRealtime == 0) {
16118            doWakeKills = false;
16119        }
16120        if (mLastPowerCheckUptime == 0) {
16121            doCpuKills = false;
16122        }
16123        if (stats.isScreenOn()) {
16124            doWakeKills = false;
16125        }
16126        final long curRealtime = SystemClock.elapsedRealtime();
16127        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16128        final long curUptime = SystemClock.uptimeMillis();
16129        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16130        mLastPowerCheckRealtime = curRealtime;
16131        mLastPowerCheckUptime = curUptime;
16132        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16133            doWakeKills = false;
16134        }
16135        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16136            doCpuKills = false;
16137        }
16138        int i = mLruProcesses.size();
16139        while (i > 0) {
16140            i--;
16141            ProcessRecord app = mLruProcesses.get(i);
16142            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16143                long wtime;
16144                synchronized (stats) {
16145                    wtime = stats.getProcessWakeTime(app.info.uid,
16146                            app.pid, curRealtime);
16147                }
16148                long wtimeUsed = wtime - app.lastWakeTime;
16149                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16150                if (DEBUG_POWER) {
16151                    StringBuilder sb = new StringBuilder(128);
16152                    sb.append("Wake for ");
16153                    app.toShortString(sb);
16154                    sb.append(": over ");
16155                    TimeUtils.formatDuration(realtimeSince, sb);
16156                    sb.append(" used ");
16157                    TimeUtils.formatDuration(wtimeUsed, sb);
16158                    sb.append(" (");
16159                    sb.append((wtimeUsed*100)/realtimeSince);
16160                    sb.append("%)");
16161                    Slog.i(TAG, sb.toString());
16162                    sb.setLength(0);
16163                    sb.append("CPU for ");
16164                    app.toShortString(sb);
16165                    sb.append(": over ");
16166                    TimeUtils.formatDuration(uptimeSince, sb);
16167                    sb.append(" used ");
16168                    TimeUtils.formatDuration(cputimeUsed, sb);
16169                    sb.append(" (");
16170                    sb.append((cputimeUsed*100)/uptimeSince);
16171                    sb.append("%)");
16172                    Slog.i(TAG, sb.toString());
16173                }
16174                // If a process has held a wake lock for more
16175                // than 50% of the time during this period,
16176                // that sounds bad.  Kill!
16177                if (doWakeKills && realtimeSince > 0
16178                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16179                    synchronized (stats) {
16180                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16181                                realtimeSince, wtimeUsed);
16182                    }
16183                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16184                            + " during " + realtimeSince);
16185                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16186                } else if (doCpuKills && uptimeSince > 0
16187                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16188                    synchronized (stats) {
16189                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16190                                uptimeSince, cputimeUsed);
16191                    }
16192                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16193                            + " during " + uptimeSince);
16194                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16195                } else {
16196                    app.lastWakeTime = wtime;
16197                    app.lastCpuTime = app.curCpuTime;
16198                }
16199            }
16200        }
16201    }
16202
16203    private final boolean applyOomAdjLocked(ProcessRecord app,
16204            ProcessRecord TOP_APP, boolean doingAll, long now) {
16205        boolean success = true;
16206
16207        if (app.curRawAdj != app.setRawAdj) {
16208            app.setRawAdj = app.curRawAdj;
16209        }
16210
16211        int changes = 0;
16212
16213        if (app.curAdj != app.setAdj) {
16214            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16215            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16216                TAG, "Set " + app.pid + " " + app.processName +
16217                " adj " + app.curAdj + ": " + app.adjType);
16218            app.setAdj = app.curAdj;
16219        }
16220
16221        if (app.setSchedGroup != app.curSchedGroup) {
16222            app.setSchedGroup = app.curSchedGroup;
16223            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16224                    "Setting process group of " + app.processName
16225                    + " to " + app.curSchedGroup);
16226            if (app.waitingToKill != null &&
16227                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16228                killUnneededProcessLocked(app, app.waitingToKill);
16229                success = false;
16230            } else {
16231                if (true) {
16232                    long oldId = Binder.clearCallingIdentity();
16233                    try {
16234                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16235                    } catch (Exception e) {
16236                        Slog.w(TAG, "Failed setting process group of " + app.pid
16237                                + " to " + app.curSchedGroup);
16238                        e.printStackTrace();
16239                    } finally {
16240                        Binder.restoreCallingIdentity(oldId);
16241                    }
16242                } else {
16243                    if (app.thread != null) {
16244                        try {
16245                            app.thread.setSchedulingGroup(app.curSchedGroup);
16246                        } catch (RemoteException e) {
16247                        }
16248                    }
16249                }
16250                Process.setSwappiness(app.pid,
16251                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16252            }
16253        }
16254        if (app.repForegroundActivities != app.foregroundActivities) {
16255            app.repForegroundActivities = app.foregroundActivities;
16256            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16257        }
16258        if (app.repProcState != app.curProcState) {
16259            app.repProcState = app.curProcState;
16260            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16261            if (app.thread != null) {
16262                try {
16263                    if (false) {
16264                        //RuntimeException h = new RuntimeException("here");
16265                        Slog.i(TAG, "Sending new process state " + app.repProcState
16266                                + " to " + app /*, h*/);
16267                    }
16268                    app.thread.setProcessState(app.repProcState);
16269                } catch (RemoteException e) {
16270                }
16271            }
16272        }
16273        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16274                app.setProcState)) {
16275            app.lastStateTime = now;
16276            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16277                    isSleeping(), now);
16278            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16279                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16280                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16281                    + (app.nextPssTime-now) + ": " + app);
16282        } else {
16283            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16284                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16285                requestPssLocked(app, app.setProcState);
16286                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16287                        isSleeping(), now);
16288            } else if (false && DEBUG_PSS) {
16289                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16290            }
16291        }
16292        if (app.setProcState != app.curProcState) {
16293            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16294                    "Proc state change of " + app.processName
16295                    + " to " + app.curProcState);
16296            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16297            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16298            if (setImportant && !curImportant) {
16299                // This app is no longer something we consider important enough to allow to
16300                // use arbitrary amounts of battery power.  Note
16301                // its current wake lock time to later know to kill it if
16302                // it is not behaving well.
16303                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16304                synchronized (stats) {
16305                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16306                            app.pid, SystemClock.elapsedRealtime());
16307                }
16308                app.lastCpuTime = app.curCpuTime;
16309
16310            }
16311            app.setProcState = app.curProcState;
16312            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16313                app.notCachedSinceIdle = false;
16314            }
16315            if (!doingAll) {
16316                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16317            } else {
16318                app.procStateChanged = true;
16319            }
16320        }
16321
16322        if (changes != 0) {
16323            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16324            int i = mPendingProcessChanges.size()-1;
16325            ProcessChangeItem item = null;
16326            while (i >= 0) {
16327                item = mPendingProcessChanges.get(i);
16328                if (item.pid == app.pid) {
16329                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16330                    break;
16331                }
16332                i--;
16333            }
16334            if (i < 0) {
16335                // No existing item in pending changes; need a new one.
16336                final int NA = mAvailProcessChanges.size();
16337                if (NA > 0) {
16338                    item = mAvailProcessChanges.remove(NA-1);
16339                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16340                } else {
16341                    item = new ProcessChangeItem();
16342                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16343                }
16344                item.changes = 0;
16345                item.pid = app.pid;
16346                item.uid = app.info.uid;
16347                if (mPendingProcessChanges.size() == 0) {
16348                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16349                            "*** Enqueueing dispatch processes changed!");
16350                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16351                }
16352                mPendingProcessChanges.add(item);
16353            }
16354            item.changes |= changes;
16355            item.processState = app.repProcState;
16356            item.foregroundActivities = app.repForegroundActivities;
16357            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16358                    + Integer.toHexString(System.identityHashCode(item))
16359                    + " " + app.toShortString() + ": changes=" + item.changes
16360                    + " procState=" + item.processState
16361                    + " foreground=" + item.foregroundActivities
16362                    + " type=" + app.adjType + " source=" + app.adjSource
16363                    + " target=" + app.adjTarget);
16364        }
16365
16366        return success;
16367    }
16368
16369    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16370        if (proc.thread != null) {
16371            if (proc.baseProcessTracker != null) {
16372                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16373            }
16374            if (proc.repProcState >= 0) {
16375                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16376                        proc.repProcState);
16377            }
16378        }
16379    }
16380
16381    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16382            ProcessRecord TOP_APP, boolean doingAll, long now) {
16383        if (app.thread == null) {
16384            return false;
16385        }
16386
16387        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16388
16389        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16390    }
16391
16392    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16393            boolean oomAdj) {
16394        if (isForeground != proc.foregroundServices) {
16395            proc.foregroundServices = isForeground;
16396            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16397                    proc.info.uid);
16398            if (isForeground) {
16399                if (curProcs == null) {
16400                    curProcs = new ArrayList<ProcessRecord>();
16401                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16402                }
16403                if (!curProcs.contains(proc)) {
16404                    curProcs.add(proc);
16405                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16406                            proc.info.packageName, proc.info.uid);
16407                }
16408            } else {
16409                if (curProcs != null) {
16410                    if (curProcs.remove(proc)) {
16411                        mBatteryStatsService.noteEvent(
16412                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16413                                proc.info.packageName, proc.info.uid);
16414                        if (curProcs.size() <= 0) {
16415                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16416                        }
16417                    }
16418                }
16419            }
16420            if (oomAdj) {
16421                updateOomAdjLocked();
16422            }
16423        }
16424    }
16425
16426    private final ActivityRecord resumedAppLocked() {
16427        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16428        String pkg;
16429        int uid;
16430        if (act != null) {
16431            pkg = act.packageName;
16432            uid = act.info.applicationInfo.uid;
16433        } else {
16434            pkg = null;
16435            uid = -1;
16436        }
16437        // Has the UID or resumed package name changed?
16438        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16439                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16440            if (mCurResumedPackage != null) {
16441                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16442                        mCurResumedPackage, mCurResumedUid);
16443            }
16444            mCurResumedPackage = pkg;
16445            mCurResumedUid = uid;
16446            if (mCurResumedPackage != null) {
16447                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16448                        mCurResumedPackage, mCurResumedUid);
16449            }
16450        }
16451        return act;
16452    }
16453
16454    final boolean updateOomAdjLocked(ProcessRecord app) {
16455        final ActivityRecord TOP_ACT = resumedAppLocked();
16456        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16457        final boolean wasCached = app.cached;
16458
16459        mAdjSeq++;
16460
16461        // This is the desired cached adjusment we want to tell it to use.
16462        // If our app is currently cached, we know it, and that is it.  Otherwise,
16463        // we don't know it yet, and it needs to now be cached we will then
16464        // need to do a complete oom adj.
16465        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16466                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16467        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16468                SystemClock.uptimeMillis());
16469        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16470            // Changed to/from cached state, so apps after it in the LRU
16471            // list may also be changed.
16472            updateOomAdjLocked();
16473        }
16474        return success;
16475    }
16476
16477    final void updateOomAdjLocked() {
16478        final ActivityRecord TOP_ACT = resumedAppLocked();
16479        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16480        final long now = SystemClock.uptimeMillis();
16481        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16482        final int N = mLruProcesses.size();
16483
16484        if (false) {
16485            RuntimeException e = new RuntimeException();
16486            e.fillInStackTrace();
16487            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16488        }
16489
16490        mAdjSeq++;
16491        mNewNumServiceProcs = 0;
16492        mNewNumAServiceProcs = 0;
16493
16494        final int emptyProcessLimit;
16495        final int cachedProcessLimit;
16496        if (mProcessLimit <= 0) {
16497            emptyProcessLimit = cachedProcessLimit = 0;
16498        } else if (mProcessLimit == 1) {
16499            emptyProcessLimit = 1;
16500            cachedProcessLimit = 0;
16501        } else {
16502            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16503            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16504        }
16505
16506        // Let's determine how many processes we have running vs.
16507        // how many slots we have for background processes; we may want
16508        // to put multiple processes in a slot of there are enough of
16509        // them.
16510        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16511                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16512        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16513        if (numEmptyProcs > cachedProcessLimit) {
16514            // If there are more empty processes than our limit on cached
16515            // processes, then use the cached process limit for the factor.
16516            // This ensures that the really old empty processes get pushed
16517            // down to the bottom, so if we are running low on memory we will
16518            // have a better chance at keeping around more cached processes
16519            // instead of a gazillion empty processes.
16520            numEmptyProcs = cachedProcessLimit;
16521        }
16522        int emptyFactor = numEmptyProcs/numSlots;
16523        if (emptyFactor < 1) emptyFactor = 1;
16524        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16525        if (cachedFactor < 1) cachedFactor = 1;
16526        int stepCached = 0;
16527        int stepEmpty = 0;
16528        int numCached = 0;
16529        int numEmpty = 0;
16530        int numTrimming = 0;
16531
16532        mNumNonCachedProcs = 0;
16533        mNumCachedHiddenProcs = 0;
16534
16535        // First update the OOM adjustment for each of the
16536        // application processes based on their current state.
16537        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16538        int nextCachedAdj = curCachedAdj+1;
16539        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16540        int nextEmptyAdj = curEmptyAdj+2;
16541        for (int i=N-1; i>=0; i--) {
16542            ProcessRecord app = mLruProcesses.get(i);
16543            if (!app.killedByAm && app.thread != null) {
16544                app.procStateChanged = false;
16545                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16546
16547                // If we haven't yet assigned the final cached adj
16548                // to the process, do that now.
16549                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16550                    switch (app.curProcState) {
16551                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16552                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16553                            // This process is a cached process holding activities...
16554                            // assign it the next cached value for that type, and then
16555                            // step that cached level.
16556                            app.curRawAdj = curCachedAdj;
16557                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16558                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16559                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16560                                    + ")");
16561                            if (curCachedAdj != nextCachedAdj) {
16562                                stepCached++;
16563                                if (stepCached >= cachedFactor) {
16564                                    stepCached = 0;
16565                                    curCachedAdj = nextCachedAdj;
16566                                    nextCachedAdj += 2;
16567                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16568                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16569                                    }
16570                                }
16571                            }
16572                            break;
16573                        default:
16574                            // For everything else, assign next empty cached process
16575                            // level and bump that up.  Note that this means that
16576                            // long-running services that have dropped down to the
16577                            // cached level will be treated as empty (since their process
16578                            // state is still as a service), which is what we want.
16579                            app.curRawAdj = curEmptyAdj;
16580                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16581                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16582                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16583                                    + ")");
16584                            if (curEmptyAdj != nextEmptyAdj) {
16585                                stepEmpty++;
16586                                if (stepEmpty >= emptyFactor) {
16587                                    stepEmpty = 0;
16588                                    curEmptyAdj = nextEmptyAdj;
16589                                    nextEmptyAdj += 2;
16590                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16591                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16592                                    }
16593                                }
16594                            }
16595                            break;
16596                    }
16597                }
16598
16599                applyOomAdjLocked(app, TOP_APP, true, now);
16600
16601                // Count the number of process types.
16602                switch (app.curProcState) {
16603                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16604                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16605                        mNumCachedHiddenProcs++;
16606                        numCached++;
16607                        if (numCached > cachedProcessLimit) {
16608                            killUnneededProcessLocked(app, "cached #" + numCached);
16609                        }
16610                        break;
16611                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16612                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16613                                && app.lastActivityTime < oldTime) {
16614                            killUnneededProcessLocked(app, "empty for "
16615                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16616                                    / 1000) + "s");
16617                        } else {
16618                            numEmpty++;
16619                            if (numEmpty > emptyProcessLimit) {
16620                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16621                            }
16622                        }
16623                        break;
16624                    default:
16625                        mNumNonCachedProcs++;
16626                        break;
16627                }
16628
16629                if (app.isolated && app.services.size() <= 0) {
16630                    // If this is an isolated process, and there are no
16631                    // services running in it, then the process is no longer
16632                    // needed.  We agressively kill these because we can by
16633                    // definition not re-use the same process again, and it is
16634                    // good to avoid having whatever code was running in them
16635                    // left sitting around after no longer needed.
16636                    killUnneededProcessLocked(app, "isolated not needed");
16637                }
16638
16639                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16640                        && !app.killedByAm) {
16641                    numTrimming++;
16642                }
16643            }
16644        }
16645
16646        mNumServiceProcs = mNewNumServiceProcs;
16647
16648        // Now determine the memory trimming level of background processes.
16649        // Unfortunately we need to start at the back of the list to do this
16650        // properly.  We only do this if the number of background apps we
16651        // are managing to keep around is less than half the maximum we desire;
16652        // if we are keeping a good number around, we'll let them use whatever
16653        // memory they want.
16654        final int numCachedAndEmpty = numCached + numEmpty;
16655        int memFactor;
16656        if (numCached <= ProcessList.TRIM_CACHED_APPS
16657                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16658            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16659                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16660            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16661                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16662            } else {
16663                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16664            }
16665        } else {
16666            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16667        }
16668        // We always allow the memory level to go up (better).  We only allow it to go
16669        // down if we are in a state where that is allowed, *and* the total number of processes
16670        // has gone down since last time.
16671        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16672                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16673                + " last=" + mLastNumProcesses);
16674        if (memFactor > mLastMemoryLevel) {
16675            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16676                memFactor = mLastMemoryLevel;
16677                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16678            }
16679        }
16680        mLastMemoryLevel = memFactor;
16681        mLastNumProcesses = mLruProcesses.size();
16682        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16683        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16684        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16685            if (mLowRamStartTime == 0) {
16686                mLowRamStartTime = now;
16687            }
16688            int step = 0;
16689            int fgTrimLevel;
16690            switch (memFactor) {
16691                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16692                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16693                    break;
16694                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16695                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16696                    break;
16697                default:
16698                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16699                    break;
16700            }
16701            int factor = numTrimming/3;
16702            int minFactor = 2;
16703            if (mHomeProcess != null) minFactor++;
16704            if (mPreviousProcess != null) minFactor++;
16705            if (factor < minFactor) factor = minFactor;
16706            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16707            for (int i=N-1; i>=0; i--) {
16708                ProcessRecord app = mLruProcesses.get(i);
16709                if (allChanged || app.procStateChanged) {
16710                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16711                    app.procStateChanged = false;
16712                }
16713                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16714                        && !app.killedByAm) {
16715                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16716                        try {
16717                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16718                                    "Trimming memory of " + app.processName
16719                                    + " to " + curLevel);
16720                            app.thread.scheduleTrimMemory(curLevel);
16721                        } catch (RemoteException e) {
16722                        }
16723                        if (false) {
16724                            // For now we won't do this; our memory trimming seems
16725                            // to be good enough at this point that destroying
16726                            // activities causes more harm than good.
16727                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16728                                    && app != mHomeProcess && app != mPreviousProcess) {
16729                                // Need to do this on its own message because the stack may not
16730                                // be in a consistent state at this point.
16731                                // For these apps we will also finish their activities
16732                                // to help them free memory.
16733                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16734                            }
16735                        }
16736                    }
16737                    app.trimMemoryLevel = curLevel;
16738                    step++;
16739                    if (step >= factor) {
16740                        step = 0;
16741                        switch (curLevel) {
16742                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16743                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16744                                break;
16745                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16746                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16747                                break;
16748                        }
16749                    }
16750                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16751                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16752                            && app.thread != null) {
16753                        try {
16754                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16755                                    "Trimming memory of heavy-weight " + app.processName
16756                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16757                            app.thread.scheduleTrimMemory(
16758                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16759                        } catch (RemoteException e) {
16760                        }
16761                    }
16762                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16763                } else {
16764                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16765                            || app.systemNoUi) && app.pendingUiClean) {
16766                        // If this application is now in the background and it
16767                        // had done UI, then give it the special trim level to
16768                        // have it free UI resources.
16769                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16770                        if (app.trimMemoryLevel < level && app.thread != null) {
16771                            try {
16772                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16773                                        "Trimming memory of bg-ui " + app.processName
16774                                        + " to " + level);
16775                                app.thread.scheduleTrimMemory(level);
16776                            } catch (RemoteException e) {
16777                            }
16778                        }
16779                        app.pendingUiClean = false;
16780                    }
16781                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16782                        try {
16783                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16784                                    "Trimming memory of fg " + app.processName
16785                                    + " to " + fgTrimLevel);
16786                            app.thread.scheduleTrimMemory(fgTrimLevel);
16787                        } catch (RemoteException e) {
16788                        }
16789                    }
16790                    app.trimMemoryLevel = fgTrimLevel;
16791                }
16792            }
16793        } else {
16794            if (mLowRamStartTime != 0) {
16795                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16796                mLowRamStartTime = 0;
16797            }
16798            for (int i=N-1; i>=0; i--) {
16799                ProcessRecord app = mLruProcesses.get(i);
16800                if (allChanged || app.procStateChanged) {
16801                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16802                    app.procStateChanged = false;
16803                }
16804                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16805                        || app.systemNoUi) && app.pendingUiClean) {
16806                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16807                            && app.thread != null) {
16808                        try {
16809                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16810                                    "Trimming memory of ui hidden " + app.processName
16811                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16812                            app.thread.scheduleTrimMemory(
16813                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16814                        } catch (RemoteException e) {
16815                        }
16816                    }
16817                    app.pendingUiClean = false;
16818                }
16819                app.trimMemoryLevel = 0;
16820            }
16821        }
16822
16823        if (mAlwaysFinishActivities) {
16824            // Need to do this on its own message because the stack may not
16825            // be in a consistent state at this point.
16826            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16827        }
16828
16829        if (allChanged) {
16830            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16831        }
16832
16833        if (mProcessStats.shouldWriteNowLocked(now)) {
16834            mHandler.post(new Runnable() {
16835                @Override public void run() {
16836                    synchronized (ActivityManagerService.this) {
16837                        mProcessStats.writeStateAsyncLocked();
16838                    }
16839                }
16840            });
16841        }
16842
16843        if (DEBUG_OOM_ADJ) {
16844            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16845        }
16846    }
16847
16848    final void trimApplications() {
16849        synchronized (this) {
16850            int i;
16851
16852            // First remove any unused application processes whose package
16853            // has been removed.
16854            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16855                final ProcessRecord app = mRemovedProcesses.get(i);
16856                if (app.activities.size() == 0
16857                        && app.curReceiver == null && app.services.size() == 0) {
16858                    Slog.i(
16859                        TAG, "Exiting empty application process "
16860                        + app.processName + " ("
16861                        + (app.thread != null ? app.thread.asBinder() : null)
16862                        + ")\n");
16863                    if (app.pid > 0 && app.pid != MY_PID) {
16864                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16865                                app.processName, app.setAdj, "empty");
16866                        app.killedByAm = true;
16867                        Process.killProcessQuiet(app.pid);
16868                        Process.killProcessGroup(app.info.uid, app.pid);
16869                    } else {
16870                        try {
16871                            app.thread.scheduleExit();
16872                        } catch (Exception e) {
16873                            // Ignore exceptions.
16874                        }
16875                    }
16876                    cleanUpApplicationRecordLocked(app, false, true, -1);
16877                    mRemovedProcesses.remove(i);
16878
16879                    if (app.persistent) {
16880                        addAppLocked(app.info, false, null /* ABI override */);
16881                    }
16882                }
16883            }
16884
16885            // Now update the oom adj for all processes.
16886            updateOomAdjLocked();
16887        }
16888    }
16889
16890    /** This method sends the specified signal to each of the persistent apps */
16891    public void signalPersistentProcesses(int sig) throws RemoteException {
16892        if (sig != Process.SIGNAL_USR1) {
16893            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16894        }
16895
16896        synchronized (this) {
16897            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16898                    != PackageManager.PERMISSION_GRANTED) {
16899                throw new SecurityException("Requires permission "
16900                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16901            }
16902
16903            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16904                ProcessRecord r = mLruProcesses.get(i);
16905                if (r.thread != null && r.persistent) {
16906                    Process.sendSignal(r.pid, sig);
16907                }
16908            }
16909        }
16910    }
16911
16912    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16913        if (proc == null || proc == mProfileProc) {
16914            proc = mProfileProc;
16915            path = mProfileFile;
16916            profileType = mProfileType;
16917            clearProfilerLocked();
16918        }
16919        if (proc == null) {
16920            return;
16921        }
16922        try {
16923            proc.thread.profilerControl(false, path, null, profileType);
16924        } catch (RemoteException e) {
16925            throw new IllegalStateException("Process disappeared");
16926        }
16927    }
16928
16929    private void clearProfilerLocked() {
16930        if (mProfileFd != null) {
16931            try {
16932                mProfileFd.close();
16933            } catch (IOException e) {
16934            }
16935        }
16936        mProfileApp = null;
16937        mProfileProc = null;
16938        mProfileFile = null;
16939        mProfileType = 0;
16940        mAutoStopProfiler = false;
16941    }
16942
16943    public boolean profileControl(String process, int userId, boolean start,
16944            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16945
16946        try {
16947            synchronized (this) {
16948                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16949                // its own permission.
16950                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16951                        != PackageManager.PERMISSION_GRANTED) {
16952                    throw new SecurityException("Requires permission "
16953                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16954                }
16955
16956                if (start && fd == null) {
16957                    throw new IllegalArgumentException("null fd");
16958                }
16959
16960                ProcessRecord proc = null;
16961                if (process != null) {
16962                    proc = findProcessLocked(process, userId, "profileControl");
16963                }
16964
16965                if (start && (proc == null || proc.thread == null)) {
16966                    throw new IllegalArgumentException("Unknown process: " + process);
16967                }
16968
16969                if (start) {
16970                    stopProfilerLocked(null, null, 0);
16971                    setProfileApp(proc.info, proc.processName, path, fd, false);
16972                    mProfileProc = proc;
16973                    mProfileType = profileType;
16974                    try {
16975                        fd = fd.dup();
16976                    } catch (IOException e) {
16977                        fd = null;
16978                    }
16979                    proc.thread.profilerControl(start, path, fd, profileType);
16980                    fd = null;
16981                    mProfileFd = null;
16982                } else {
16983                    stopProfilerLocked(proc, path, profileType);
16984                    if (fd != null) {
16985                        try {
16986                            fd.close();
16987                        } catch (IOException e) {
16988                        }
16989                    }
16990                }
16991
16992                return true;
16993            }
16994        } catch (RemoteException e) {
16995            throw new IllegalStateException("Process disappeared");
16996        } finally {
16997            if (fd != null) {
16998                try {
16999                    fd.close();
17000                } catch (IOException e) {
17001                }
17002            }
17003        }
17004    }
17005
17006    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17007        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17008                userId, true, ALLOW_FULL_ONLY, callName, null);
17009        ProcessRecord proc = null;
17010        try {
17011            int pid = Integer.parseInt(process);
17012            synchronized (mPidsSelfLocked) {
17013                proc = mPidsSelfLocked.get(pid);
17014            }
17015        } catch (NumberFormatException e) {
17016        }
17017
17018        if (proc == null) {
17019            ArrayMap<String, SparseArray<ProcessRecord>> all
17020                    = mProcessNames.getMap();
17021            SparseArray<ProcessRecord> procs = all.get(process);
17022            if (procs != null && procs.size() > 0) {
17023                proc = procs.valueAt(0);
17024                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17025                    for (int i=1; i<procs.size(); i++) {
17026                        ProcessRecord thisProc = procs.valueAt(i);
17027                        if (thisProc.userId == userId) {
17028                            proc = thisProc;
17029                            break;
17030                        }
17031                    }
17032                }
17033            }
17034        }
17035
17036        return proc;
17037    }
17038
17039    public boolean dumpHeap(String process, int userId, boolean managed,
17040            String path, ParcelFileDescriptor fd) throws RemoteException {
17041
17042        try {
17043            synchronized (this) {
17044                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17045                // its own permission (same as profileControl).
17046                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17047                        != PackageManager.PERMISSION_GRANTED) {
17048                    throw new SecurityException("Requires permission "
17049                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17050                }
17051
17052                if (fd == null) {
17053                    throw new IllegalArgumentException("null fd");
17054                }
17055
17056                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17057                if (proc == null || proc.thread == null) {
17058                    throw new IllegalArgumentException("Unknown process: " + process);
17059                }
17060
17061                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17062                if (!isDebuggable) {
17063                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17064                        throw new SecurityException("Process not debuggable: " + proc);
17065                    }
17066                }
17067
17068                proc.thread.dumpHeap(managed, path, fd);
17069                fd = null;
17070                return true;
17071            }
17072        } catch (RemoteException e) {
17073            throw new IllegalStateException("Process disappeared");
17074        } finally {
17075            if (fd != null) {
17076                try {
17077                    fd.close();
17078                } catch (IOException e) {
17079                }
17080            }
17081        }
17082    }
17083
17084    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17085    public void monitor() {
17086        synchronized (this) { }
17087    }
17088
17089    void onCoreSettingsChange(Bundle settings) {
17090        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17091            ProcessRecord processRecord = mLruProcesses.get(i);
17092            try {
17093                if (processRecord.thread != null) {
17094                    processRecord.thread.setCoreSettings(settings);
17095                }
17096            } catch (RemoteException re) {
17097                /* ignore */
17098            }
17099        }
17100    }
17101
17102    // Multi-user methods
17103
17104    /**
17105     * Start user, if its not already running, but don't bring it to foreground.
17106     */
17107    @Override
17108    public boolean startUserInBackground(final int userId) {
17109        return startUser(userId, /* foreground */ false);
17110    }
17111
17112    /**
17113     * Refreshes the list of users related to the current user when either a
17114     * user switch happens or when a new related user is started in the
17115     * background.
17116     */
17117    private void updateCurrentProfileIdsLocked() {
17118        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17119                mCurrentUserId, false /* enabledOnly */);
17120        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17121        for (int i = 0; i < currentProfileIds.length; i++) {
17122            currentProfileIds[i] = profiles.get(i).id;
17123        }
17124        mCurrentProfileIds = currentProfileIds;
17125
17126        synchronized (mUserProfileGroupIdsSelfLocked) {
17127            mUserProfileGroupIdsSelfLocked.clear();
17128            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17129            for (int i = 0; i < users.size(); i++) {
17130                UserInfo user = users.get(i);
17131                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17132                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17133                }
17134            }
17135        }
17136    }
17137
17138    private Set getProfileIdsLocked(int userId) {
17139        Set userIds = new HashSet<Integer>();
17140        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17141                userId, false /* enabledOnly */);
17142        for (UserInfo user : profiles) {
17143            userIds.add(Integer.valueOf(user.id));
17144        }
17145        return userIds;
17146    }
17147
17148    @Override
17149    public boolean switchUser(final int userId) {
17150        return startUser(userId, /* foregound */ true);
17151    }
17152
17153    private boolean startUser(final int userId, boolean foreground) {
17154        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17155                != PackageManager.PERMISSION_GRANTED) {
17156            String msg = "Permission Denial: switchUser() from pid="
17157                    + Binder.getCallingPid()
17158                    + ", uid=" + Binder.getCallingUid()
17159                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17160            Slog.w(TAG, msg);
17161            throw new SecurityException(msg);
17162        }
17163
17164        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17165
17166        final long ident = Binder.clearCallingIdentity();
17167        try {
17168            synchronized (this) {
17169                final int oldUserId = mCurrentUserId;
17170                if (oldUserId == userId) {
17171                    return true;
17172                }
17173
17174                mStackSupervisor.setLockTaskModeLocked(null, false);
17175
17176                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17177                if (userInfo == null) {
17178                    Slog.w(TAG, "No user info for user #" + userId);
17179                    return false;
17180                }
17181
17182                if (foreground) {
17183                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17184                            R.anim.screen_user_enter);
17185                }
17186
17187                boolean needStart = false;
17188
17189                // If the user we are switching to is not currently started, then
17190                // we need to start it now.
17191                if (mStartedUsers.get(userId) == null) {
17192                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17193                    updateStartedUserArrayLocked();
17194                    needStart = true;
17195                }
17196
17197                final Integer userIdInt = Integer.valueOf(userId);
17198                mUserLru.remove(userIdInt);
17199                mUserLru.add(userIdInt);
17200
17201                if (foreground) {
17202                    mCurrentUserId = userId;
17203                    updateCurrentProfileIdsLocked();
17204                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17205                    // Once the internal notion of the active user has switched, we lock the device
17206                    // with the option to show the user switcher on the keyguard.
17207                    mWindowManager.lockNow(null);
17208                } else {
17209                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17210                    updateCurrentProfileIdsLocked();
17211                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17212                    mUserLru.remove(currentUserIdInt);
17213                    mUserLru.add(currentUserIdInt);
17214                }
17215
17216                final UserStartedState uss = mStartedUsers.get(userId);
17217
17218                // Make sure user is in the started state.  If it is currently
17219                // stopping, we need to knock that off.
17220                if (uss.mState == UserStartedState.STATE_STOPPING) {
17221                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17222                    // so we can just fairly silently bring the user back from
17223                    // the almost-dead.
17224                    uss.mState = UserStartedState.STATE_RUNNING;
17225                    updateStartedUserArrayLocked();
17226                    needStart = true;
17227                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17228                    // This means ACTION_SHUTDOWN has been sent, so we will
17229                    // need to treat this as a new boot of the user.
17230                    uss.mState = UserStartedState.STATE_BOOTING;
17231                    updateStartedUserArrayLocked();
17232                    needStart = true;
17233                }
17234
17235                if (uss.mState == UserStartedState.STATE_BOOTING) {
17236                    // Booting up a new user, need to tell system services about it.
17237                    // Note that this is on the same handler as scheduling of broadcasts,
17238                    // which is important because it needs to go first.
17239                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
17240                }
17241
17242                if (foreground) {
17243                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17244                            oldUserId));
17245                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17246                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17247                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17248                            oldUserId, userId, uss));
17249                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17250                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17251                }
17252
17253                if (needStart) {
17254                    // Send USER_STARTED broadcast
17255                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17256                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17257                            | Intent.FLAG_RECEIVER_FOREGROUND);
17258                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17259                    broadcastIntentLocked(null, null, intent,
17260                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17261                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17262                }
17263
17264                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17265                    if (userId != UserHandle.USER_OWNER) {
17266                        // Send PRE_BOOT_COMPLETED broadcasts for this new user
17267                        final ArrayList<ComponentName> doneReceivers
17268                                = new ArrayList<ComponentName>();
17269                        deliverPreBootCompleted(null, doneReceivers, userId);
17270
17271                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17272                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17273                        broadcastIntentLocked(null, null, intent, null,
17274                                new IIntentReceiver.Stub() {
17275                                    public void performReceive(Intent intent, int resultCode,
17276                                            String data, Bundle extras, boolean ordered,
17277                                            boolean sticky, int sendingUser) {
17278                                        userInitialized(uss, userId);
17279                                    }
17280                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17281                                true, false, MY_PID, Process.SYSTEM_UID,
17282                                userId);
17283                        uss.initializing = true;
17284                    } else {
17285                        getUserManagerLocked().makeInitialized(userInfo.id);
17286                    }
17287                }
17288
17289                if (foreground) {
17290                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17291                    if (homeInFront) {
17292                        startHomeActivityLocked(userId);
17293                    } else {
17294                        mStackSupervisor.resumeTopActivitiesLocked();
17295                    }
17296                    EventLogTags.writeAmSwitchUser(userId);
17297                    getUserManagerLocked().userForeground(userId);
17298                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17299                } else {
17300                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17301                }
17302
17303                if (needStart) {
17304                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17305                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17306                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17307                    broadcastIntentLocked(null, null, intent,
17308                            null, new IIntentReceiver.Stub() {
17309                                @Override
17310                                public void performReceive(Intent intent, int resultCode, String data,
17311                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17312                                        throws RemoteException {
17313                                }
17314                            }, 0, null, null,
17315                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17316                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17317                }
17318            }
17319        } finally {
17320            Binder.restoreCallingIdentity(ident);
17321        }
17322
17323        return true;
17324    }
17325
17326    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17327        long ident = Binder.clearCallingIdentity();
17328        try {
17329            Intent intent;
17330            if (oldUserId >= 0) {
17331                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17332                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17333                int count = profiles.size();
17334                for (int i = 0; i < count; i++) {
17335                    int profileUserId = profiles.get(i).id;
17336                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17337                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17338                            | Intent.FLAG_RECEIVER_FOREGROUND);
17339                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17340                    broadcastIntentLocked(null, null, intent,
17341                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17342                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17343                }
17344            }
17345            if (newUserId >= 0) {
17346                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17347                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17348                int count = profiles.size();
17349                for (int i = 0; i < count; i++) {
17350                    int profileUserId = profiles.get(i).id;
17351                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17352                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17353                            | Intent.FLAG_RECEIVER_FOREGROUND);
17354                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17355                    broadcastIntentLocked(null, null, intent,
17356                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17357                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17358                }
17359                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17360                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17361                        | Intent.FLAG_RECEIVER_FOREGROUND);
17362                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17363                broadcastIntentLocked(null, null, intent,
17364                        null, null, 0, null, null,
17365                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17366                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17367            }
17368        } finally {
17369            Binder.restoreCallingIdentity(ident);
17370        }
17371    }
17372
17373    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17374            final int newUserId) {
17375        final int N = mUserSwitchObservers.beginBroadcast();
17376        if (N > 0) {
17377            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17378                int mCount = 0;
17379                @Override
17380                public void sendResult(Bundle data) throws RemoteException {
17381                    synchronized (ActivityManagerService.this) {
17382                        if (mCurUserSwitchCallback == this) {
17383                            mCount++;
17384                            if (mCount == N) {
17385                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17386                            }
17387                        }
17388                    }
17389                }
17390            };
17391            synchronized (this) {
17392                uss.switching = true;
17393                mCurUserSwitchCallback = callback;
17394            }
17395            for (int i=0; i<N; i++) {
17396                try {
17397                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17398                            newUserId, callback);
17399                } catch (RemoteException e) {
17400                }
17401            }
17402        } else {
17403            synchronized (this) {
17404                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17405            }
17406        }
17407        mUserSwitchObservers.finishBroadcast();
17408    }
17409
17410    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17411        synchronized (this) {
17412            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17413            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17414        }
17415    }
17416
17417    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17418        mCurUserSwitchCallback = null;
17419        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17420        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17421                oldUserId, newUserId, uss));
17422    }
17423
17424    void userInitialized(UserStartedState uss, int newUserId) {
17425        completeSwitchAndInitalize(uss, newUserId, true, false);
17426    }
17427
17428    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17429        completeSwitchAndInitalize(uss, newUserId, false, true);
17430    }
17431
17432    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17433            boolean clearInitializing, boolean clearSwitching) {
17434        boolean unfrozen = false;
17435        synchronized (this) {
17436            if (clearInitializing) {
17437                uss.initializing = false;
17438                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17439            }
17440            if (clearSwitching) {
17441                uss.switching = false;
17442            }
17443            if (!uss.switching && !uss.initializing) {
17444                mWindowManager.stopFreezingScreen();
17445                unfrozen = true;
17446            }
17447        }
17448        if (unfrozen) {
17449            final int N = mUserSwitchObservers.beginBroadcast();
17450            for (int i=0; i<N; i++) {
17451                try {
17452                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17453                } catch (RemoteException e) {
17454                }
17455            }
17456            mUserSwitchObservers.finishBroadcast();
17457        }
17458    }
17459
17460    void scheduleStartProfilesLocked() {
17461        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17462            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17463                    DateUtils.SECOND_IN_MILLIS);
17464        }
17465    }
17466
17467    void startProfilesLocked() {
17468        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17469        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17470                mCurrentUserId, false /* enabledOnly */);
17471        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17472        for (UserInfo user : profiles) {
17473            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17474                    && user.id != mCurrentUserId) {
17475                toStart.add(user);
17476            }
17477        }
17478        final int n = toStart.size();
17479        int i = 0;
17480        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17481            startUserInBackground(toStart.get(i).id);
17482        }
17483        if (i < n) {
17484            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17485        }
17486    }
17487
17488    void finishUserBoot(UserStartedState uss) {
17489        synchronized (this) {
17490            if (uss.mState == UserStartedState.STATE_BOOTING
17491                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17492                uss.mState = UserStartedState.STATE_RUNNING;
17493                final int userId = uss.mHandle.getIdentifier();
17494                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17495                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17496                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17497                broadcastIntentLocked(null, null, intent,
17498                        null, null, 0, null, null,
17499                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17500                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17501            }
17502        }
17503    }
17504
17505    void finishUserSwitch(UserStartedState uss) {
17506        synchronized (this) {
17507            finishUserBoot(uss);
17508
17509            startProfilesLocked();
17510
17511            int num = mUserLru.size();
17512            int i = 0;
17513            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17514                Integer oldUserId = mUserLru.get(i);
17515                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17516                if (oldUss == null) {
17517                    // Shouldn't happen, but be sane if it does.
17518                    mUserLru.remove(i);
17519                    num--;
17520                    continue;
17521                }
17522                if (oldUss.mState == UserStartedState.STATE_STOPPING
17523                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17524                    // This user is already stopping, doesn't count.
17525                    num--;
17526                    i++;
17527                    continue;
17528                }
17529                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17530                    // Owner and current can't be stopped, but count as running.
17531                    i++;
17532                    continue;
17533                }
17534                // This is a user to be stopped.
17535                stopUserLocked(oldUserId, null);
17536                num--;
17537                i++;
17538            }
17539        }
17540    }
17541
17542    @Override
17543    public int stopUser(final int userId, final IStopUserCallback callback) {
17544        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17545                != PackageManager.PERMISSION_GRANTED) {
17546            String msg = "Permission Denial: switchUser() from pid="
17547                    + Binder.getCallingPid()
17548                    + ", uid=" + Binder.getCallingUid()
17549                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17550            Slog.w(TAG, msg);
17551            throw new SecurityException(msg);
17552        }
17553        if (userId <= 0) {
17554            throw new IllegalArgumentException("Can't stop primary user " + userId);
17555        }
17556        synchronized (this) {
17557            return stopUserLocked(userId, callback);
17558        }
17559    }
17560
17561    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17562        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17563        if (mCurrentUserId == userId) {
17564            return ActivityManager.USER_OP_IS_CURRENT;
17565        }
17566
17567        final UserStartedState uss = mStartedUsers.get(userId);
17568        if (uss == null) {
17569            // User is not started, nothing to do...  but we do need to
17570            // callback if requested.
17571            if (callback != null) {
17572                mHandler.post(new Runnable() {
17573                    @Override
17574                    public void run() {
17575                        try {
17576                            callback.userStopped(userId);
17577                        } catch (RemoteException e) {
17578                        }
17579                    }
17580                });
17581            }
17582            return ActivityManager.USER_OP_SUCCESS;
17583        }
17584
17585        if (callback != null) {
17586            uss.mStopCallbacks.add(callback);
17587        }
17588
17589        if (uss.mState != UserStartedState.STATE_STOPPING
17590                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17591            uss.mState = UserStartedState.STATE_STOPPING;
17592            updateStartedUserArrayLocked();
17593
17594            long ident = Binder.clearCallingIdentity();
17595            try {
17596                // We are going to broadcast ACTION_USER_STOPPING and then
17597                // once that is done send a final ACTION_SHUTDOWN and then
17598                // stop the user.
17599                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17600                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17601                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17602                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17603                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17604                // This is the result receiver for the final shutdown broadcast.
17605                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17606                    @Override
17607                    public void performReceive(Intent intent, int resultCode, String data,
17608                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17609                        finishUserStop(uss);
17610                    }
17611                };
17612                // This is the result receiver for the initial stopping broadcast.
17613                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17614                    @Override
17615                    public void performReceive(Intent intent, int resultCode, String data,
17616                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17617                        // On to the next.
17618                        synchronized (ActivityManagerService.this) {
17619                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17620                                // Whoops, we are being started back up.  Abort, abort!
17621                                return;
17622                            }
17623                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17624                        }
17625                        mBatteryStatsService.noteEvent(
17626                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17627                                Integer.toString(userId), userId);
17628                        mSystemServiceManager.stopUser(userId);
17629                        broadcastIntentLocked(null, null, shutdownIntent,
17630                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17631                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17632                    }
17633                };
17634                // Kick things off.
17635                broadcastIntentLocked(null, null, stoppingIntent,
17636                        null, stoppingReceiver, 0, null, null,
17637                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17638                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17639            } finally {
17640                Binder.restoreCallingIdentity(ident);
17641            }
17642        }
17643
17644        return ActivityManager.USER_OP_SUCCESS;
17645    }
17646
17647    void finishUserStop(UserStartedState uss) {
17648        final int userId = uss.mHandle.getIdentifier();
17649        boolean stopped;
17650        ArrayList<IStopUserCallback> callbacks;
17651        synchronized (this) {
17652            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17653            if (mStartedUsers.get(userId) != uss) {
17654                stopped = false;
17655            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17656                stopped = false;
17657            } else {
17658                stopped = true;
17659                // User can no longer run.
17660                mStartedUsers.remove(userId);
17661                mUserLru.remove(Integer.valueOf(userId));
17662                updateStartedUserArrayLocked();
17663
17664                // Clean up all state and processes associated with the user.
17665                // Kill all the processes for the user.
17666                forceStopUserLocked(userId, "finish user");
17667            }
17668        }
17669
17670        // Explicitly remove the old information in mRecentTasks.
17671        removeRecentTasksForUser(userId);
17672
17673        for (int i=0; i<callbacks.size(); i++) {
17674            try {
17675                if (stopped) callbacks.get(i).userStopped(userId);
17676                else callbacks.get(i).userStopAborted(userId);
17677            } catch (RemoteException e) {
17678            }
17679        }
17680
17681        if (stopped) {
17682            mSystemServiceManager.cleanupUser(userId);
17683            synchronized (this) {
17684                mStackSupervisor.removeUserLocked(userId);
17685            }
17686        }
17687    }
17688
17689    @Override
17690    public UserInfo getCurrentUser() {
17691        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17692                != PackageManager.PERMISSION_GRANTED) && (
17693                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17694                != PackageManager.PERMISSION_GRANTED)) {
17695            String msg = "Permission Denial: getCurrentUser() from pid="
17696                    + Binder.getCallingPid()
17697                    + ", uid=" + Binder.getCallingUid()
17698                    + " requires " + INTERACT_ACROSS_USERS;
17699            Slog.w(TAG, msg);
17700            throw new SecurityException(msg);
17701        }
17702        synchronized (this) {
17703            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17704        }
17705    }
17706
17707    int getCurrentUserIdLocked() {
17708        return mCurrentUserId;
17709    }
17710
17711    @Override
17712    public boolean isUserRunning(int userId, boolean orStopped) {
17713        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17714                != PackageManager.PERMISSION_GRANTED) {
17715            String msg = "Permission Denial: isUserRunning() from pid="
17716                    + Binder.getCallingPid()
17717                    + ", uid=" + Binder.getCallingUid()
17718                    + " requires " + INTERACT_ACROSS_USERS;
17719            Slog.w(TAG, msg);
17720            throw new SecurityException(msg);
17721        }
17722        synchronized (this) {
17723            return isUserRunningLocked(userId, orStopped);
17724        }
17725    }
17726
17727    boolean isUserRunningLocked(int userId, boolean orStopped) {
17728        UserStartedState state = mStartedUsers.get(userId);
17729        if (state == null) {
17730            return false;
17731        }
17732        if (orStopped) {
17733            return true;
17734        }
17735        return state.mState != UserStartedState.STATE_STOPPING
17736                && state.mState != UserStartedState.STATE_SHUTDOWN;
17737    }
17738
17739    @Override
17740    public int[] getRunningUserIds() {
17741        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17742                != PackageManager.PERMISSION_GRANTED) {
17743            String msg = "Permission Denial: isUserRunning() from pid="
17744                    + Binder.getCallingPid()
17745                    + ", uid=" + Binder.getCallingUid()
17746                    + " requires " + INTERACT_ACROSS_USERS;
17747            Slog.w(TAG, msg);
17748            throw new SecurityException(msg);
17749        }
17750        synchronized (this) {
17751            return mStartedUserArray;
17752        }
17753    }
17754
17755    private void updateStartedUserArrayLocked() {
17756        int num = 0;
17757        for (int i=0; i<mStartedUsers.size();  i++) {
17758            UserStartedState uss = mStartedUsers.valueAt(i);
17759            // This list does not include stopping users.
17760            if (uss.mState != UserStartedState.STATE_STOPPING
17761                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17762                num++;
17763            }
17764        }
17765        mStartedUserArray = new int[num];
17766        num = 0;
17767        for (int i=0; i<mStartedUsers.size();  i++) {
17768            UserStartedState uss = mStartedUsers.valueAt(i);
17769            if (uss.mState != UserStartedState.STATE_STOPPING
17770                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17771                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17772                num++;
17773            }
17774        }
17775    }
17776
17777    @Override
17778    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17779        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17780                != PackageManager.PERMISSION_GRANTED) {
17781            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17782                    + Binder.getCallingPid()
17783                    + ", uid=" + Binder.getCallingUid()
17784                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17785            Slog.w(TAG, msg);
17786            throw new SecurityException(msg);
17787        }
17788
17789        mUserSwitchObservers.register(observer);
17790    }
17791
17792    @Override
17793    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17794        mUserSwitchObservers.unregister(observer);
17795    }
17796
17797    private boolean userExists(int userId) {
17798        if (userId == 0) {
17799            return true;
17800        }
17801        UserManagerService ums = getUserManagerLocked();
17802        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17803    }
17804
17805    int[] getUsersLocked() {
17806        UserManagerService ums = getUserManagerLocked();
17807        return ums != null ? ums.getUserIds() : new int[] { 0 };
17808    }
17809
17810    UserManagerService getUserManagerLocked() {
17811        if (mUserManager == null) {
17812            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17813            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17814        }
17815        return mUserManager;
17816    }
17817
17818    private int applyUserId(int uid, int userId) {
17819        return UserHandle.getUid(userId, uid);
17820    }
17821
17822    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17823        if (info == null) return null;
17824        ApplicationInfo newInfo = new ApplicationInfo(info);
17825        newInfo.uid = applyUserId(info.uid, userId);
17826        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17827                + info.packageName;
17828        return newInfo;
17829    }
17830
17831    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17832        if (aInfo == null
17833                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17834            return aInfo;
17835        }
17836
17837        ActivityInfo info = new ActivityInfo(aInfo);
17838        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17839        return info;
17840    }
17841
17842    private final class LocalService extends ActivityManagerInternal {
17843        @Override
17844        public void goingToSleep() {
17845            ActivityManagerService.this.goingToSleep();
17846        }
17847
17848        @Override
17849        public void wakingUp() {
17850            ActivityManagerService.this.wakingUp();
17851        }
17852    }
17853
17854    /**
17855     * An implementation of IAppTask, that allows an app to manage its own tasks via
17856     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17857     * only the process that calls getAppTasks() can call the AppTask methods.
17858     */
17859    class AppTaskImpl extends IAppTask.Stub {
17860        private int mTaskId;
17861        private int mCallingUid;
17862
17863        public AppTaskImpl(int taskId, int callingUid) {
17864            mTaskId = taskId;
17865            mCallingUid = callingUid;
17866        }
17867
17868        @Override
17869        public void finishAndRemoveTask() {
17870            // Ensure that we are called from the same process that created this AppTask
17871            if (mCallingUid != Binder.getCallingUid()) {
17872                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17873                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17874                return;
17875            }
17876
17877            synchronized (ActivityManagerService.this) {
17878                long origId = Binder.clearCallingIdentity();
17879                try {
17880                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17881                    if (tr != null) {
17882                        // Only kill the process if we are not a new document
17883                        int flags = tr.getBaseIntent().getFlags();
17884                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17885                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17886                        removeTaskByIdLocked(mTaskId,
17887                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17888                    }
17889                } finally {
17890                    Binder.restoreCallingIdentity(origId);
17891                }
17892            }
17893        }
17894
17895        @Override
17896        public ActivityManager.RecentTaskInfo getTaskInfo() {
17897            // Ensure that we are called from the same process that created this AppTask
17898            if (mCallingUid != Binder.getCallingUid()) {
17899                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17900                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17901                return null;
17902            }
17903
17904            synchronized (ActivityManagerService.this) {
17905                long origId = Binder.clearCallingIdentity();
17906                try {
17907                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17908                    if (tr != null) {
17909                        return createRecentTaskInfoFromTaskRecord(tr);
17910                    }
17911                } finally {
17912                    Binder.restoreCallingIdentity(origId);
17913                }
17914                return null;
17915            }
17916        }
17917    }
17918}
17919