ActivityManagerService.java revision 161536b5970ba5ab43233e7695ef69ba2bb804f4
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.IActivityContainer;
37import android.app.IActivityContainerCallback;
38import android.app.IAppTask;
39import android.app.admin.DevicePolicyManager;
40import android.app.usage.UsageStats;
41import android.app.usage.UsageStatsManagerInternal;
42import android.appwidget.AppWidgetManager;
43import android.graphics.Rect;
44import android.os.BatteryStats;
45import android.os.PersistableBundle;
46import android.service.voice.IVoiceInteractionSession;
47import android.util.ArrayMap;
48import android.util.ArraySet;
49import android.util.SparseIntArray;
50
51import com.android.internal.R;
52import com.android.internal.annotations.GuardedBy;
53import com.android.internal.app.IAppOpsService;
54import com.android.internal.app.IVoiceInteractor;
55import com.android.internal.app.ProcessMap;
56import com.android.internal.app.ProcessStats;
57import com.android.internal.content.PackageMonitor;
58import com.android.internal.os.BackgroundThread;
59import com.android.internal.os.BatteryStatsImpl;
60import com.android.internal.os.ProcessCpuTracker;
61import com.android.internal.os.TransferPipe;
62import com.android.internal.os.Zygote;
63import com.android.internal.util.FastPrintWriter;
64import com.android.internal.util.FastXmlSerializer;
65import com.android.internal.util.MemInfoReader;
66import com.android.internal.util.Preconditions;
67import com.android.server.AppOpsService;
68import com.android.server.AttributeCache;
69import com.android.server.IntentResolver;
70import com.android.server.LocalServices;
71import com.android.server.ServiceThread;
72import com.android.server.SystemService;
73import com.android.server.SystemServiceManager;
74import com.android.server.Watchdog;
75import com.android.server.am.ActivityStack.ActivityState;
76import com.android.server.firewall.IntentFirewall;
77import com.android.server.pm.UserManagerService;
78import com.android.server.wm.AppTransition;
79import com.android.server.wm.WindowManagerService;
80import com.google.android.collect.Lists;
81import com.google.android.collect.Maps;
82
83import libcore.io.IoUtils;
84
85import org.xmlpull.v1.XmlPullParser;
86import org.xmlpull.v1.XmlPullParserException;
87import org.xmlpull.v1.XmlSerializer;
88
89import android.app.Activity;
90import android.app.ActivityManager;
91import android.app.ActivityManager.RunningTaskInfo;
92import android.app.ActivityManager.StackInfo;
93import android.app.ActivityManagerInternal;
94import android.app.ActivityManagerNative;
95import android.app.ActivityOptions;
96import android.app.ActivityThread;
97import android.app.AlertDialog;
98import android.app.AppGlobals;
99import android.app.ApplicationErrorReport;
100import android.app.Dialog;
101import android.app.IActivityController;
102import android.app.IApplicationThread;
103import android.app.IInstrumentationWatcher;
104import android.app.INotificationManager;
105import android.app.IProcessObserver;
106import android.app.IServiceConnection;
107import android.app.IStopUserCallback;
108import android.app.IUiAutomationConnection;
109import android.app.IUserSwitchObserver;
110import android.app.Instrumentation;
111import android.app.Notification;
112import android.app.NotificationManager;
113import android.app.PendingIntent;
114import android.app.backup.IBackupManager;
115import android.content.ActivityNotFoundException;
116import android.content.BroadcastReceiver;
117import android.content.ClipData;
118import android.content.ComponentCallbacks2;
119import android.content.ComponentName;
120import android.content.ContentProvider;
121import android.content.ContentResolver;
122import android.content.Context;
123import android.content.DialogInterface;
124import android.content.IContentProvider;
125import android.content.IIntentReceiver;
126import android.content.IIntentSender;
127import android.content.Intent;
128import android.content.IntentFilter;
129import android.content.IntentSender;
130import android.content.pm.ActivityInfo;
131import android.content.pm.ApplicationInfo;
132import android.content.pm.ConfigurationInfo;
133import android.content.pm.IPackageDataObserver;
134import android.content.pm.IPackageManager;
135import android.content.pm.InstrumentationInfo;
136import android.content.pm.PackageInfo;
137import android.content.pm.PackageManager;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.UserInfo;
140import android.content.pm.PackageManager.NameNotFoundException;
141import android.content.pm.PathPermission;
142import android.content.pm.ProviderInfo;
143import android.content.pm.ResolveInfo;
144import android.content.pm.ServiceInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.net.Proxy;
148import android.net.ProxyInfo;
149import android.net.Uri;
150import android.os.Binder;
151import android.os.Build;
152import android.os.Bundle;
153import android.os.Debug;
154import android.os.DropBoxManager;
155import android.os.Environment;
156import android.os.FactoryTest;
157import android.os.FileObserver;
158import android.os.FileUtils;
159import android.os.Handler;
160import android.os.IBinder;
161import android.os.IPermissionController;
162import android.os.IRemoteCallback;
163import android.os.IUserManager;
164import android.os.Looper;
165import android.os.Message;
166import android.os.Parcel;
167import android.os.ParcelFileDescriptor;
168import android.os.Process;
169import android.os.RemoteCallbackList;
170import android.os.RemoteException;
171import android.os.SELinux;
172import android.os.ServiceManager;
173import android.os.StrictMode;
174import android.os.SystemClock;
175import android.os.SystemProperties;
176import android.os.UpdateLock;
177import android.os.UserHandle;
178import android.provider.Settings;
179import android.text.format.DateUtils;
180import android.text.format.Time;
181import android.util.AtomicFile;
182import android.util.EventLog;
183import android.util.Log;
184import android.util.Pair;
185import android.util.PrintWriterPrinter;
186import android.util.Slog;
187import android.util.SparseArray;
188import android.util.TimeUtils;
189import android.util.Xml;
190import android.view.Gravity;
191import android.view.LayoutInflater;
192import android.view.View;
193import android.view.WindowManager;
194
195import java.io.BufferedInputStream;
196import java.io.BufferedOutputStream;
197import java.io.DataInputStream;
198import java.io.DataOutputStream;
199import java.io.File;
200import java.io.FileDescriptor;
201import java.io.FileInputStream;
202import java.io.FileNotFoundException;
203import java.io.FileOutputStream;
204import java.io.IOException;
205import java.io.InputStreamReader;
206import java.io.PrintWriter;
207import java.io.StringWriter;
208import java.lang.ref.WeakReference;
209import java.util.ArrayList;
210import java.util.Arrays;
211import java.util.Collections;
212import java.util.Comparator;
213import java.util.HashMap;
214import java.util.HashSet;
215import java.util.Iterator;
216import java.util.List;
217import java.util.Locale;
218import java.util.Map;
219import java.util.Set;
220import java.util.concurrent.atomic.AtomicBoolean;
221import java.util.concurrent.atomic.AtomicLong;
222
223public final class ActivityManagerService extends ActivityManagerNative
224        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
225
226    private static final String USER_DATA_DIR = "/data/user/";
227    // File that stores last updated system version and called preboot receivers
228    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
229
230    static final String TAG = "ActivityManager";
231    static final String TAG_MU = "ActivityManagerServiceMU";
232    static final boolean DEBUG = false;
233    static final boolean localLOGV = DEBUG;
234    static final boolean DEBUG_BACKUP = localLOGV || false;
235    static final boolean DEBUG_BROADCAST = localLOGV || false;
236    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
237    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
238    static final boolean DEBUG_CLEANUP = localLOGV || false;
239    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
240    static final boolean DEBUG_FOCUS = false;
241    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
242    static final boolean DEBUG_MU = localLOGV || false;
243    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
244    static final boolean DEBUG_LRU = localLOGV || false;
245    static final boolean DEBUG_PAUSE = localLOGV || false;
246    static final boolean DEBUG_POWER = localLOGV || false;
247    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
248    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
249    static final boolean DEBUG_PROCESSES = localLOGV || false;
250    static final boolean DEBUG_PROVIDER = localLOGV || false;
251    static final boolean DEBUG_RESULTS = localLOGV || false;
252    static final boolean DEBUG_SERVICE = localLOGV || false;
253    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
254    static final boolean DEBUG_STACK = localLOGV || false;
255    static final boolean DEBUG_SWITCH = localLOGV || false;
256    static final boolean DEBUG_TASKS = localLOGV || false;
257    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
258    static final boolean DEBUG_TRANSITION = localLOGV || false;
259    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
260    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
261    static final boolean DEBUG_VISBILITY = localLOGV || false;
262    static final boolean DEBUG_PSS = localLOGV || false;
263    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
264    static final boolean VALIDATE_TOKENS = false;
265    static final boolean SHOW_ACTIVITY_START_TIME = true;
266
267    // Control over CPU and battery monitoring.
268    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
269    static final boolean MONITOR_CPU_USAGE = true;
270    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
271    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
272    static final boolean MONITOR_THREAD_CPU_USAGE = false;
273
274    // The flags that are set for all calls we make to the package manager.
275    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
276
277    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
278
279    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
280
281    // Maximum number of recent tasks that we can remember.
282    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
283
284    // Maximum number recent bitmaps to keep in memory.
285    static final int MAX_RECENT_BITMAPS = 5;
286
287    // Amount of time after a call to stopAppSwitches() during which we will
288    // prevent further untrusted switches from happening.
289    static final long APP_SWITCH_DELAY_TIME = 5*1000;
290
291    // How long we wait for a launched process to attach to the activity manager
292    // before we decide it's never going to come up for real.
293    static final int PROC_START_TIMEOUT = 10*1000;
294
295    // How long we wait for a launched process to attach to the activity manager
296    // before we decide it's never going to come up for real, when the process was
297    // started with a wrapper for instrumentation (such as Valgrind) because it
298    // could take much longer than usual.
299    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
300
301    // How long to wait after going idle before forcing apps to GC.
302    static final int GC_TIMEOUT = 5*1000;
303
304    // The minimum amount of time between successive GC requests for a process.
305    static final int GC_MIN_INTERVAL = 60*1000;
306
307    // The minimum amount of time between successive PSS requests for a process.
308    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
309
310    // The minimum amount of time between successive PSS requests for a process
311    // when the request is due to the memory state being lowered.
312    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
313
314    // The rate at which we check for apps using excessive power -- 15 mins.
315    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
316
317    // The minimum sample duration we will allow before deciding we have
318    // enough data on wake locks to start killing things.
319    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
320
321    // The minimum sample duration we will allow before deciding we have
322    // enough data on CPU usage to start killing things.
323    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
324
325    // How long we allow a receiver to run before giving up on it.
326    static final int BROADCAST_FG_TIMEOUT = 10*1000;
327    static final int BROADCAST_BG_TIMEOUT = 60*1000;
328
329    // How long we wait until we timeout on key dispatching.
330    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
331
332    // How long we wait until we timeout on key dispatching during instrumentation.
333    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
334
335    // Amount of time we wait for observers to handle a user switch before
336    // giving up on them and unfreezing the screen.
337    static final int USER_SWITCH_TIMEOUT = 2*1000;
338
339    // Maximum number of users we allow to be running at a time.
340    static final int MAX_RUNNING_USERS = 3;
341
342    // How long to wait in getAssistContextExtras for the activity and foreground services
343    // to respond with the result.
344    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
345
346    // Maximum number of persisted Uri grants a package is allowed
347    static final int MAX_PERSISTED_URI_GRANTS = 128;
348
349    static final int MY_PID = Process.myPid();
350
351    static final String[] EMPTY_STRING_ARRAY = new String[0];
352
353    // How many bytes to write into the dropbox log before truncating
354    static final int DROPBOX_MAX_SIZE = 256 * 1024;
355
356    // Access modes for handleIncomingUser.
357    static final int ALLOW_NON_FULL = 0;
358    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
359    static final int ALLOW_FULL_ONLY = 2;
360
361    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
362
363    /** All system services */
364    SystemServiceManager mSystemServiceManager;
365
366    /** Run all ActivityStacks through this */
367    ActivityStackSupervisor mStackSupervisor;
368
369    public IntentFirewall mIntentFirewall;
370
371    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
372    // default actuion automatically.  Important for devices without direct input
373    // devices.
374    private boolean mShowDialogs = true;
375
376    BroadcastQueue mFgBroadcastQueue;
377    BroadcastQueue mBgBroadcastQueue;
378    // Convenient for easy iteration over the queues. Foreground is first
379    // so that dispatch of foreground broadcasts gets precedence.
380    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
381
382    BroadcastQueue broadcastQueueForIntent(Intent intent) {
383        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
384        if (DEBUG_BACKGROUND_BROADCAST) {
385            Slog.i(TAG, "Broadcast intent " + intent + " on "
386                    + (isFg ? "foreground" : "background")
387                    + " queue");
388        }
389        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
390    }
391
392    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
393        for (BroadcastQueue queue : mBroadcastQueues) {
394            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
395            if (r != null) {
396                return r;
397            }
398        }
399        return null;
400    }
401
402    /**
403     * Activity we have told the window manager to have key focus.
404     */
405    ActivityRecord mFocusedActivity = null;
406
407    /**
408     * List of intents that were used to start the most recent tasks.
409     */
410    ArrayList<TaskRecord> mRecentTasks;
411    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
412
413    public class PendingAssistExtras extends Binder implements Runnable {
414        public final ActivityRecord activity;
415        public boolean haveResult = false;
416        public Bundle result = null;
417        public PendingAssistExtras(ActivityRecord _activity) {
418            activity = _activity;
419        }
420        @Override
421        public void run() {
422            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
423            synchronized (this) {
424                haveResult = true;
425                notifyAll();
426            }
427        }
428    }
429
430    final ArrayList<PendingAssistExtras> mPendingAssistExtras
431            = new ArrayList<PendingAssistExtras>();
432
433    /**
434     * Process management.
435     */
436    final ProcessList mProcessList = new ProcessList();
437
438    /**
439     * All of the applications we currently have running organized by name.
440     * The keys are strings of the application package name (as
441     * returned by the package manager), and the keys are ApplicationRecord
442     * objects.
443     */
444    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
445
446    /**
447     * Tracking long-term execution of processes to look for abuse and other
448     * bad app behavior.
449     */
450    final ProcessStatsService mProcessStats;
451
452    /**
453     * The currently running isolated processes.
454     */
455    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
456
457    /**
458     * Counter for assigning isolated process uids, to avoid frequently reusing the
459     * same ones.
460     */
461    int mNextIsolatedProcessUid = 0;
462
463    /**
464     * The currently running heavy-weight process, if any.
465     */
466    ProcessRecord mHeavyWeightProcess = null;
467
468    /**
469     * The last time that various processes have crashed.
470     */
471    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
472
473    /**
474     * Information about a process that is currently marked as bad.
475     */
476    static final class BadProcessInfo {
477        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
478            this.time = time;
479            this.shortMsg = shortMsg;
480            this.longMsg = longMsg;
481            this.stack = stack;
482        }
483
484        final long time;
485        final String shortMsg;
486        final String longMsg;
487        final String stack;
488    }
489
490    /**
491     * Set of applications that we consider to be bad, and will reject
492     * incoming broadcasts from (which the user has no control over).
493     * Processes are added to this set when they have crashed twice within
494     * a minimum amount of time; they are removed from it when they are
495     * later restarted (hopefully due to some user action).  The value is the
496     * time it was added to the list.
497     */
498    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
499
500    /**
501     * All of the processes we currently have running organized by pid.
502     * The keys are the pid running the application.
503     *
504     * <p>NOTE: This object is protected by its own lock, NOT the global
505     * activity manager lock!
506     */
507    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
508
509    /**
510     * All of the processes that have been forced to be foreground.  The key
511     * is the pid of the caller who requested it (we hold a death
512     * link on it).
513     */
514    abstract class ForegroundToken implements IBinder.DeathRecipient {
515        int pid;
516        IBinder token;
517    }
518    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
519
520    /**
521     * List of records for processes that someone had tried to start before the
522     * system was ready.  We don't start them at that point, but ensure they
523     * are started by the time booting is complete.
524     */
525    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
526
527    /**
528     * List of persistent applications that are in the process
529     * of being started.
530     */
531    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
532
533    /**
534     * Processes that are being forcibly torn down.
535     */
536    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
537
538    /**
539     * List of running applications, sorted by recent usage.
540     * The first entry in the list is the least recently used.
541     */
542    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
543
544    /**
545     * Where in mLruProcesses that the processes hosting activities start.
546     */
547    int mLruProcessActivityStart = 0;
548
549    /**
550     * Where in mLruProcesses that the processes hosting services start.
551     * This is after (lower index) than mLruProcessesActivityStart.
552     */
553    int mLruProcessServiceStart = 0;
554
555    /**
556     * List of processes that should gc as soon as things are idle.
557     */
558    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
559
560    /**
561     * Processes we want to collect PSS data from.
562     */
563    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
564
565    /**
566     * Last time we requested PSS data of all processes.
567     */
568    long mLastFullPssTime = SystemClock.uptimeMillis();
569
570    /**
571     * If set, the next time we collect PSS data we should do a full collection
572     * with data from native processes and the kernel.
573     */
574    boolean mFullPssPending = false;
575
576    /**
577     * This is the process holding what we currently consider to be
578     * the "home" activity.
579     */
580    ProcessRecord mHomeProcess;
581
582    /**
583     * This is the process holding the activity the user last visited that
584     * is in a different process from the one they are currently in.
585     */
586    ProcessRecord mPreviousProcess;
587
588    /**
589     * The time at which the previous process was last visible.
590     */
591    long mPreviousProcessVisibleTime;
592
593    /**
594     * Which uses have been started, so are allowed to run code.
595     */
596    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
597
598    /**
599     * LRU list of history of current users.  Most recently current is at the end.
600     */
601    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
602
603    /**
604     * Constant array of the users that are currently started.
605     */
606    int[] mStartedUserArray = new int[] { 0 };
607
608    /**
609     * Registered observers of the user switching mechanics.
610     */
611    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
612            = new RemoteCallbackList<IUserSwitchObserver>();
613
614    /**
615     * Currently active user switch.
616     */
617    Object mCurUserSwitchCallback;
618
619    /**
620     * Packages that the user has asked to have run in screen size
621     * compatibility mode instead of filling the screen.
622     */
623    final CompatModePackages mCompatModePackages;
624
625    /**
626     * Set of IntentSenderRecord objects that are currently active.
627     */
628    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
629            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
630
631    /**
632     * Fingerprints (hashCode()) of stack traces that we've
633     * already logged DropBox entries for.  Guarded by itself.  If
634     * something (rogue user app) forces this over
635     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
636     */
637    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
638    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
639
640    /**
641     * Strict Mode background batched logging state.
642     *
643     * The string buffer is guarded by itself, and its lock is also
644     * used to determine if another batched write is already
645     * in-flight.
646     */
647    private final StringBuilder mStrictModeBuffer = new StringBuilder();
648
649    /**
650     * Keeps track of all IIntentReceivers that have been registered for
651     * broadcasts.  Hash keys are the receiver IBinder, hash value is
652     * a ReceiverList.
653     */
654    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
655            new HashMap<IBinder, ReceiverList>();
656
657    /**
658     * Resolver for broadcast intents to registered receivers.
659     * Holds BroadcastFilter (subclass of IntentFilter).
660     */
661    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
662            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
663        @Override
664        protected boolean allowFilterResult(
665                BroadcastFilter filter, List<BroadcastFilter> dest) {
666            IBinder target = filter.receiverList.receiver.asBinder();
667            for (int i=dest.size()-1; i>=0; i--) {
668                if (dest.get(i).receiverList.receiver.asBinder() == target) {
669                    return false;
670                }
671            }
672            return true;
673        }
674
675        @Override
676        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
677            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
678                    || userId == filter.owningUserId) {
679                return super.newResult(filter, match, userId);
680            }
681            return null;
682        }
683
684        @Override
685        protected BroadcastFilter[] newArray(int size) {
686            return new BroadcastFilter[size];
687        }
688
689        @Override
690        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
691            return packageName.equals(filter.packageName);
692        }
693    };
694
695    /**
696     * State of all active sticky broadcasts per user.  Keys are the action of the
697     * sticky Intent, values are an ArrayList of all broadcasted intents with
698     * that action (which should usually be one).  The SparseArray is keyed
699     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
700     * for stickies that are sent to all users.
701     */
702    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
703            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
704
705    final ActiveServices mServices;
706
707    /**
708     * Backup/restore process management
709     */
710    String mBackupAppName = null;
711    BackupRecord mBackupTarget = null;
712
713    final ProviderMap mProviderMap;
714
715    /**
716     * List of content providers who have clients waiting for them.  The
717     * application is currently being launched and the provider will be
718     * removed from this list once it is published.
719     */
720    final ArrayList<ContentProviderRecord> mLaunchingProviders
721            = new ArrayList<ContentProviderRecord>();
722
723    /**
724     * File storing persisted {@link #mGrantedUriPermissions}.
725     */
726    private final AtomicFile mGrantFile;
727
728    /** XML constants used in {@link #mGrantFile} */
729    private static final String TAG_URI_GRANTS = "uri-grants";
730    private static final String TAG_URI_GRANT = "uri-grant";
731    private static final String ATTR_USER_HANDLE = "userHandle";
732    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
733    private static final String ATTR_TARGET_USER_ID = "targetUserId";
734    private static final String ATTR_SOURCE_PKG = "sourcePkg";
735    private static final String ATTR_TARGET_PKG = "targetPkg";
736    private static final String ATTR_URI = "uri";
737    private static final String ATTR_MODE_FLAGS = "modeFlags";
738    private static final String ATTR_CREATED_TIME = "createdTime";
739    private static final String ATTR_PREFIX = "prefix";
740
741    /**
742     * Global set of specific {@link Uri} permissions that have been granted.
743     * This optimized lookup structure maps from {@link UriPermission#targetUid}
744     * to {@link UriPermission#uri} to {@link UriPermission}.
745     */
746    @GuardedBy("this")
747    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
748            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
749
750    public static class GrantUri {
751        public final int sourceUserId;
752        public final Uri uri;
753        public boolean prefix;
754
755        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
756            this.sourceUserId = sourceUserId;
757            this.uri = uri;
758            this.prefix = prefix;
759        }
760
761        @Override
762        public int hashCode() {
763            return toString().hashCode();
764        }
765
766        @Override
767        public boolean equals(Object o) {
768            if (o instanceof GrantUri) {
769                GrantUri other = (GrantUri) o;
770                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
771                        && prefix == other.prefix;
772            }
773            return false;
774        }
775
776        @Override
777        public String toString() {
778            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
779            if (prefix) result += " [prefix]";
780            return result;
781        }
782
783        public String toSafeString() {
784            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
785            if (prefix) result += " [prefix]";
786            return result;
787        }
788
789        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
790            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
791                    ContentProvider.getUriWithoutUserId(uri), false);
792        }
793    }
794
795    CoreSettingsObserver mCoreSettingsObserver;
796
797    /**
798     * Thread-local storage used to carry caller permissions over through
799     * indirect content-provider access.
800     */
801    private class Identity {
802        public int pid;
803        public int uid;
804
805        Identity(int _pid, int _uid) {
806            pid = _pid;
807            uid = _uid;
808        }
809    }
810
811    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
812
813    /**
814     * All information we have collected about the runtime performance of
815     * any user id that can impact battery performance.
816     */
817    final BatteryStatsService mBatteryStatsService;
818
819    /**
820     * Information about component usage
821     */
822    UsageStatsManagerInternal mUsageStatsService;
823
824    /**
825     * Information about and control over application operations
826     */
827    final AppOpsService mAppOpsService;
828
829    /**
830     * Save recent tasks information across reboots.
831     */
832    final TaskPersister mTaskPersister;
833
834    /**
835     * Current configuration information.  HistoryRecord objects are given
836     * a reference to this object to indicate which configuration they are
837     * currently running in, so this object must be kept immutable.
838     */
839    Configuration mConfiguration = new Configuration();
840
841    /**
842     * Current sequencing integer of the configuration, for skipping old
843     * configurations.
844     */
845    int mConfigurationSeq = 0;
846
847    /**
848     * Hardware-reported OpenGLES version.
849     */
850    final int GL_ES_VERSION;
851
852    /**
853     * List of initialization arguments to pass to all processes when binding applications to them.
854     * For example, references to the commonly used services.
855     */
856    HashMap<String, IBinder> mAppBindArgs;
857
858    /**
859     * Temporary to avoid allocations.  Protected by main lock.
860     */
861    final StringBuilder mStringBuilder = new StringBuilder(256);
862
863    /**
864     * Used to control how we initialize the service.
865     */
866    ComponentName mTopComponent;
867    String mTopAction = Intent.ACTION_MAIN;
868    String mTopData;
869    boolean mProcessesReady = false;
870    boolean mSystemReady = false;
871    boolean mBooting = false;
872    boolean mWaitingUpdate = false;
873    boolean mDidUpdate = false;
874    boolean mOnBattery = false;
875    boolean mLaunchWarningShown = false;
876
877    Context mContext;
878
879    int mFactoryTest;
880
881    boolean mCheckedForSetup;
882
883    /**
884     * The time at which we will allow normal application switches again,
885     * after a call to {@link #stopAppSwitches()}.
886     */
887    long mAppSwitchesAllowedTime;
888
889    /**
890     * This is set to true after the first switch after mAppSwitchesAllowedTime
891     * is set; any switches after that will clear the time.
892     */
893    boolean mDidAppSwitch;
894
895    /**
896     * Last time (in realtime) at which we checked for power usage.
897     */
898    long mLastPowerCheckRealtime;
899
900    /**
901     * Last time (in uptime) at which we checked for power usage.
902     */
903    long mLastPowerCheckUptime;
904
905    /**
906     * Set while we are wanting to sleep, to prevent any
907     * activities from being started/resumed.
908     */
909    private boolean mSleeping = false;
910
911    /**
912     * Set while we are running a voice interaction.  This overrides
913     * sleeping while it is active.
914     */
915    private boolean mRunningVoice = false;
916
917    /**
918     * State of external calls telling us if the device is asleep.
919     */
920    private boolean mWentToSleep = false;
921
922    /**
923     * State of external call telling us if the lock screen is shown.
924     */
925    private boolean mLockScreenShown = false;
926
927    /**
928     * Set if we are shutting down the system, similar to sleeping.
929     */
930    boolean mShuttingDown = false;
931
932    /**
933     * Current sequence id for oom_adj computation traversal.
934     */
935    int mAdjSeq = 0;
936
937    /**
938     * Current sequence id for process LRU updating.
939     */
940    int mLruSeq = 0;
941
942    /**
943     * Keep track of the non-cached/empty process we last found, to help
944     * determine how to distribute cached/empty processes next time.
945     */
946    int mNumNonCachedProcs = 0;
947
948    /**
949     * Keep track of the number of cached hidden procs, to balance oom adj
950     * distribution between those and empty procs.
951     */
952    int mNumCachedHiddenProcs = 0;
953
954    /**
955     * Keep track of the number of service processes we last found, to
956     * determine on the next iteration which should be B services.
957     */
958    int mNumServiceProcs = 0;
959    int mNewNumAServiceProcs = 0;
960    int mNewNumServiceProcs = 0;
961
962    /**
963     * Allow the current computed overall memory level of the system to go down?
964     * This is set to false when we are killing processes for reasons other than
965     * memory management, so that the now smaller process list will not be taken as
966     * an indication that memory is tighter.
967     */
968    boolean mAllowLowerMemLevel = false;
969
970    /**
971     * The last computed memory level, for holding when we are in a state that
972     * processes are going away for other reasons.
973     */
974    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
975
976    /**
977     * The last total number of process we have, to determine if changes actually look
978     * like a shrinking number of process due to lower RAM.
979     */
980    int mLastNumProcesses;
981
982    /**
983     * The uptime of the last time we performed idle maintenance.
984     */
985    long mLastIdleTime = SystemClock.uptimeMillis();
986
987    /**
988     * Total time spent with RAM that has been added in the past since the last idle time.
989     */
990    long mLowRamTimeSinceLastIdle = 0;
991
992    /**
993     * If RAM is currently low, when that horrible situation started.
994     */
995    long mLowRamStartTime = 0;
996
997    /**
998     * For reporting to battery stats the current top application.
999     */
1000    private String mCurResumedPackage = null;
1001    private int mCurResumedUid = -1;
1002
1003    /**
1004     * For reporting to battery stats the apps currently running foreground
1005     * service.  The ProcessMap is package/uid tuples; each of these contain
1006     * an array of the currently foreground processes.
1007     */
1008    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1009            = new ProcessMap<ArrayList<ProcessRecord>>();
1010
1011    /**
1012     * This is set if we had to do a delayed dexopt of an app before launching
1013     * it, to increase the ANR timeouts in that case.
1014     */
1015    boolean mDidDexOpt;
1016
1017    /**
1018     * Set if the systemServer made a call to enterSafeMode.
1019     */
1020    boolean mSafeMode;
1021
1022    String mDebugApp = null;
1023    boolean mWaitForDebugger = false;
1024    boolean mDebugTransient = false;
1025    String mOrigDebugApp = null;
1026    boolean mOrigWaitForDebugger = false;
1027    boolean mAlwaysFinishActivities = false;
1028    IActivityController mController = null;
1029    String mProfileApp = null;
1030    ProcessRecord mProfileProc = null;
1031    String mProfileFile;
1032    ParcelFileDescriptor mProfileFd;
1033    int mProfileType = 0;
1034    boolean mAutoStopProfiler = false;
1035    String mOpenGlTraceApp = null;
1036
1037    static class ProcessChangeItem {
1038        static final int CHANGE_ACTIVITIES = 1<<0;
1039        static final int CHANGE_PROCESS_STATE = 1<<1;
1040        int changes;
1041        int uid;
1042        int pid;
1043        int processState;
1044        boolean foregroundActivities;
1045    }
1046
1047    final RemoteCallbackList<IProcessObserver> mProcessObservers
1048            = new RemoteCallbackList<IProcessObserver>();
1049    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1050
1051    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1052            = new ArrayList<ProcessChangeItem>();
1053    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1054            = new ArrayList<ProcessChangeItem>();
1055
1056    /**
1057     * Runtime CPU use collection thread.  This object's lock is used to
1058     * protect all related state.
1059     */
1060    final Thread mProcessCpuThread;
1061
1062    /**
1063     * Used to collect process stats when showing not responding dialog.
1064     * Protected by mProcessCpuThread.
1065     */
1066    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1067            MONITOR_THREAD_CPU_USAGE);
1068    final AtomicLong mLastCpuTime = new AtomicLong(0);
1069    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1070
1071    long mLastWriteTime = 0;
1072
1073    /**
1074     * Used to retain an update lock when the foreground activity is in
1075     * immersive mode.
1076     */
1077    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1078
1079    /**
1080     * Set to true after the system has finished booting.
1081     */
1082    boolean mBooted = false;
1083
1084    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1085    int mProcessLimitOverride = -1;
1086
1087    WindowManagerService mWindowManager;
1088
1089    final ActivityThread mSystemThread;
1090
1091    int mCurrentUserId = 0;
1092    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1093
1094    /**
1095     * Mapping from each known user ID to the profile group ID it is associated with.
1096     */
1097    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1098
1099    private UserManagerService mUserManager;
1100
1101    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1102        final ProcessRecord mApp;
1103        final int mPid;
1104        final IApplicationThread mAppThread;
1105
1106        AppDeathRecipient(ProcessRecord app, int pid,
1107                IApplicationThread thread) {
1108            if (localLOGV) Slog.v(
1109                TAG, "New death recipient " + this
1110                + " for thread " + thread.asBinder());
1111            mApp = app;
1112            mPid = pid;
1113            mAppThread = thread;
1114        }
1115
1116        @Override
1117        public void binderDied() {
1118            if (localLOGV) Slog.v(
1119                TAG, "Death received in " + this
1120                + " for thread " + mAppThread.asBinder());
1121            synchronized(ActivityManagerService.this) {
1122                appDiedLocked(mApp, mPid, mAppThread);
1123            }
1124        }
1125    }
1126
1127    static final int SHOW_ERROR_MSG = 1;
1128    static final int SHOW_NOT_RESPONDING_MSG = 2;
1129    static final int SHOW_FACTORY_ERROR_MSG = 3;
1130    static final int UPDATE_CONFIGURATION_MSG = 4;
1131    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1132    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1133    static final int SERVICE_TIMEOUT_MSG = 12;
1134    static final int UPDATE_TIME_ZONE = 13;
1135    static final int SHOW_UID_ERROR_MSG = 14;
1136    static final int IM_FEELING_LUCKY_MSG = 15;
1137    static final int PROC_START_TIMEOUT_MSG = 20;
1138    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1139    static final int KILL_APPLICATION_MSG = 22;
1140    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1141    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1142    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1143    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1144    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1145    static final int CLEAR_DNS_CACHE_MSG = 28;
1146    static final int UPDATE_HTTP_PROXY_MSG = 29;
1147    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1148    static final int DISPATCH_PROCESSES_CHANGED = 31;
1149    static final int DISPATCH_PROCESS_DIED = 32;
1150    static final int REPORT_MEM_USAGE_MSG = 33;
1151    static final int REPORT_USER_SWITCH_MSG = 34;
1152    static final int CONTINUE_USER_SWITCH_MSG = 35;
1153    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1154    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1155    static final int PERSIST_URI_GRANTS_MSG = 38;
1156    static final int REQUEST_ALL_PSS_MSG = 39;
1157    static final int START_PROFILES_MSG = 40;
1158    static final int UPDATE_TIME = 41;
1159    static final int SYSTEM_USER_START_MSG = 42;
1160    static final int SYSTEM_USER_CURRENT_MSG = 43;
1161    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1162    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1163
1164    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1165    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1166    static final int FIRST_COMPAT_MODE_MSG = 300;
1167    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1168
1169    AlertDialog mUidAlert;
1170    CompatModeDialog mCompatModeDialog;
1171    long mLastMemUsageReportTime = 0;
1172
1173    private LockToAppRequestDialog mLockToAppRequest;
1174
1175    /**
1176     * Flag whether the current user is a "monkey", i.e. whether
1177     * the UI is driven by a UI automation tool.
1178     */
1179    private boolean mUserIsMonkey;
1180
1181    /** Flag whether the device has a recents UI */
1182    final boolean mHasRecents;
1183
1184    final ServiceThread mHandlerThread;
1185    final MainHandler mHandler;
1186
1187    final class MainHandler extends Handler {
1188        public MainHandler(Looper looper) {
1189            super(looper, null, true);
1190        }
1191
1192        @Override
1193        public void handleMessage(Message msg) {
1194            switch (msg.what) {
1195            case SHOW_ERROR_MSG: {
1196                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1197                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1198                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1199                synchronized (ActivityManagerService.this) {
1200                    ProcessRecord proc = (ProcessRecord)data.get("app");
1201                    AppErrorResult res = (AppErrorResult) data.get("result");
1202                    if (proc != null && proc.crashDialog != null) {
1203                        Slog.e(TAG, "App already has crash dialog: " + proc);
1204                        if (res != null) {
1205                            res.set(0);
1206                        }
1207                        return;
1208                    }
1209                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1210                            >= Process.FIRST_APPLICATION_UID
1211                            && proc.pid != MY_PID);
1212                    for (int userId : mCurrentProfileIds) {
1213                        isBackground &= (proc.userId != userId);
1214                    }
1215                    if (isBackground && !showBackground) {
1216                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1217                        if (res != null) {
1218                            res.set(0);
1219                        }
1220                        return;
1221                    }
1222                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1223                        Dialog d = new AppErrorDialog(mContext,
1224                                ActivityManagerService.this, res, proc);
1225                        d.show();
1226                        proc.crashDialog = d;
1227                    } else {
1228                        // The device is asleep, so just pretend that the user
1229                        // saw a crash dialog and hit "force quit".
1230                        if (res != null) {
1231                            res.set(0);
1232                        }
1233                    }
1234                }
1235
1236                ensureBootCompleted();
1237            } break;
1238            case SHOW_NOT_RESPONDING_MSG: {
1239                synchronized (ActivityManagerService.this) {
1240                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1241                    ProcessRecord proc = (ProcessRecord)data.get("app");
1242                    if (proc != null && proc.anrDialog != null) {
1243                        Slog.e(TAG, "App already has anr dialog: " + proc);
1244                        return;
1245                    }
1246
1247                    Intent intent = new Intent("android.intent.action.ANR");
1248                    if (!mProcessesReady) {
1249                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1250                                | Intent.FLAG_RECEIVER_FOREGROUND);
1251                    }
1252                    broadcastIntentLocked(null, null, intent,
1253                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1254                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1255
1256                    if (mShowDialogs) {
1257                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1258                                mContext, proc, (ActivityRecord)data.get("activity"),
1259                                msg.arg1 != 0);
1260                        d.show();
1261                        proc.anrDialog = d;
1262                    } else {
1263                        // Just kill the app if there is no dialog to be shown.
1264                        killAppAtUsersRequest(proc, null);
1265                    }
1266                }
1267
1268                ensureBootCompleted();
1269            } break;
1270            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1271                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1272                synchronized (ActivityManagerService.this) {
1273                    ProcessRecord proc = (ProcessRecord) data.get("app");
1274                    if (proc == null) {
1275                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1276                        break;
1277                    }
1278                    if (proc.crashDialog != null) {
1279                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1280                        return;
1281                    }
1282                    AppErrorResult res = (AppErrorResult) data.get("result");
1283                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1284                        Dialog d = new StrictModeViolationDialog(mContext,
1285                                ActivityManagerService.this, res, proc);
1286                        d.show();
1287                        proc.crashDialog = d;
1288                    } else {
1289                        // The device is asleep, so just pretend that the user
1290                        // saw a crash dialog and hit "force quit".
1291                        res.set(0);
1292                    }
1293                }
1294                ensureBootCompleted();
1295            } break;
1296            case SHOW_FACTORY_ERROR_MSG: {
1297                Dialog d = new FactoryErrorDialog(
1298                    mContext, msg.getData().getCharSequence("msg"));
1299                d.show();
1300                ensureBootCompleted();
1301            } break;
1302            case UPDATE_CONFIGURATION_MSG: {
1303                final ContentResolver resolver = mContext.getContentResolver();
1304                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1305            } break;
1306            case GC_BACKGROUND_PROCESSES_MSG: {
1307                synchronized (ActivityManagerService.this) {
1308                    performAppGcsIfAppropriateLocked();
1309                }
1310            } break;
1311            case WAIT_FOR_DEBUGGER_MSG: {
1312                synchronized (ActivityManagerService.this) {
1313                    ProcessRecord app = (ProcessRecord)msg.obj;
1314                    if (msg.arg1 != 0) {
1315                        if (!app.waitedForDebugger) {
1316                            Dialog d = new AppWaitingForDebuggerDialog(
1317                                    ActivityManagerService.this,
1318                                    mContext, app);
1319                            app.waitDialog = d;
1320                            app.waitedForDebugger = true;
1321                            d.show();
1322                        }
1323                    } else {
1324                        if (app.waitDialog != null) {
1325                            app.waitDialog.dismiss();
1326                            app.waitDialog = null;
1327                        }
1328                    }
1329                }
1330            } break;
1331            case SERVICE_TIMEOUT_MSG: {
1332                if (mDidDexOpt) {
1333                    mDidDexOpt = false;
1334                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1335                    nmsg.obj = msg.obj;
1336                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1337                    return;
1338                }
1339                mServices.serviceTimeout((ProcessRecord)msg.obj);
1340            } break;
1341            case UPDATE_TIME_ZONE: {
1342                synchronized (ActivityManagerService.this) {
1343                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1344                        ProcessRecord r = mLruProcesses.get(i);
1345                        if (r.thread != null) {
1346                            try {
1347                                r.thread.updateTimeZone();
1348                            } catch (RemoteException ex) {
1349                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1350                            }
1351                        }
1352                    }
1353                }
1354            } break;
1355            case CLEAR_DNS_CACHE_MSG: {
1356                synchronized (ActivityManagerService.this) {
1357                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1358                        ProcessRecord r = mLruProcesses.get(i);
1359                        if (r.thread != null) {
1360                            try {
1361                                r.thread.clearDnsCache();
1362                            } catch (RemoteException ex) {
1363                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1364                            }
1365                        }
1366                    }
1367                }
1368            } break;
1369            case UPDATE_HTTP_PROXY_MSG: {
1370                ProxyInfo proxy = (ProxyInfo)msg.obj;
1371                String host = "";
1372                String port = "";
1373                String exclList = "";
1374                Uri pacFileUrl = Uri.EMPTY;
1375                if (proxy != null) {
1376                    host = proxy.getHost();
1377                    port = Integer.toString(proxy.getPort());
1378                    exclList = proxy.getExclusionListAsString();
1379                    pacFileUrl = proxy.getPacFileUrl();
1380                }
1381                synchronized (ActivityManagerService.this) {
1382                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1383                        ProcessRecord r = mLruProcesses.get(i);
1384                        if (r.thread != null) {
1385                            try {
1386                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1387                            } catch (RemoteException ex) {
1388                                Slog.w(TAG, "Failed to update http proxy for: " +
1389                                        r.info.processName);
1390                            }
1391                        }
1392                    }
1393                }
1394            } break;
1395            case SHOW_UID_ERROR_MSG: {
1396                String title = "System UIDs Inconsistent";
1397                String text = "UIDs on the system are inconsistent, you need to wipe your"
1398                        + " data partition or your device will be unstable.";
1399                Log.e(TAG, title + ": " + text);
1400                if (mShowDialogs) {
1401                    // XXX This is a temporary dialog, no need to localize.
1402                    AlertDialog d = new BaseErrorDialog(mContext);
1403                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1404                    d.setCancelable(false);
1405                    d.setTitle(title);
1406                    d.setMessage(text);
1407                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1408                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1409                    mUidAlert = d;
1410                    d.show();
1411                }
1412            } break;
1413            case IM_FEELING_LUCKY_MSG: {
1414                if (mUidAlert != null) {
1415                    mUidAlert.dismiss();
1416                    mUidAlert = null;
1417                }
1418            } break;
1419            case PROC_START_TIMEOUT_MSG: {
1420                if (mDidDexOpt) {
1421                    mDidDexOpt = false;
1422                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1423                    nmsg.obj = msg.obj;
1424                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1425                    return;
1426                }
1427                ProcessRecord app = (ProcessRecord)msg.obj;
1428                synchronized (ActivityManagerService.this) {
1429                    processStartTimedOutLocked(app);
1430                }
1431            } break;
1432            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1433                synchronized (ActivityManagerService.this) {
1434                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1435                }
1436            } break;
1437            case KILL_APPLICATION_MSG: {
1438                synchronized (ActivityManagerService.this) {
1439                    int appid = msg.arg1;
1440                    boolean restart = (msg.arg2 == 1);
1441                    Bundle bundle = (Bundle)msg.obj;
1442                    String pkg = bundle.getString("pkg");
1443                    String reason = bundle.getString("reason");
1444                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1445                            false, UserHandle.USER_ALL, reason);
1446                }
1447            } break;
1448            case FINALIZE_PENDING_INTENT_MSG: {
1449                ((PendingIntentRecord)msg.obj).completeFinalize();
1450            } break;
1451            case POST_HEAVY_NOTIFICATION_MSG: {
1452                INotificationManager inm = NotificationManager.getService();
1453                if (inm == null) {
1454                    return;
1455                }
1456
1457                ActivityRecord root = (ActivityRecord)msg.obj;
1458                ProcessRecord process = root.app;
1459                if (process == null) {
1460                    return;
1461                }
1462
1463                try {
1464                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1465                    String text = mContext.getString(R.string.heavy_weight_notification,
1466                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1467                    Notification notification = new Notification();
1468                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1469                    notification.when = 0;
1470                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1471                    notification.tickerText = text;
1472                    notification.defaults = 0; // please be quiet
1473                    notification.sound = null;
1474                    notification.vibrate = null;
1475                    notification.setLatestEventInfo(context, text,
1476                            mContext.getText(R.string.heavy_weight_notification_detail),
1477                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1478                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1479                                    new UserHandle(root.userId)));
1480
1481                    try {
1482                        int[] outId = new int[1];
1483                        inm.enqueueNotificationWithTag("android", "android", null,
1484                                R.string.heavy_weight_notification,
1485                                notification, outId, root.userId);
1486                    } catch (RuntimeException e) {
1487                        Slog.w(ActivityManagerService.TAG,
1488                                "Error showing notification for heavy-weight app", e);
1489                    } catch (RemoteException e) {
1490                    }
1491                } catch (NameNotFoundException e) {
1492                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1493                }
1494            } break;
1495            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1496                INotificationManager inm = NotificationManager.getService();
1497                if (inm == null) {
1498                    return;
1499                }
1500                try {
1501                    inm.cancelNotificationWithTag("android", null,
1502                            R.string.heavy_weight_notification,  msg.arg1);
1503                } catch (RuntimeException e) {
1504                    Slog.w(ActivityManagerService.TAG,
1505                            "Error canceling notification for service", e);
1506                } catch (RemoteException e) {
1507                }
1508            } break;
1509            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1510                synchronized (ActivityManagerService.this) {
1511                    checkExcessivePowerUsageLocked(true);
1512                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1513                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1514                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1515                }
1516            } break;
1517            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1518                synchronized (ActivityManagerService.this) {
1519                    ActivityRecord ar = (ActivityRecord)msg.obj;
1520                    if (mCompatModeDialog != null) {
1521                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1522                                ar.info.applicationInfo.packageName)) {
1523                            return;
1524                        }
1525                        mCompatModeDialog.dismiss();
1526                        mCompatModeDialog = null;
1527                    }
1528                    if (ar != null && false) {
1529                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1530                                ar.packageName)) {
1531                            int mode = mCompatModePackages.computeCompatModeLocked(
1532                                    ar.info.applicationInfo);
1533                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1534                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1535                                mCompatModeDialog = new CompatModeDialog(
1536                                        ActivityManagerService.this, mContext,
1537                                        ar.info.applicationInfo);
1538                                mCompatModeDialog.show();
1539                            }
1540                        }
1541                    }
1542                }
1543                break;
1544            }
1545            case DISPATCH_PROCESSES_CHANGED: {
1546                dispatchProcessesChanged();
1547                break;
1548            }
1549            case DISPATCH_PROCESS_DIED: {
1550                final int pid = msg.arg1;
1551                final int uid = msg.arg2;
1552                dispatchProcessDied(pid, uid);
1553                break;
1554            }
1555            case REPORT_MEM_USAGE_MSG: {
1556                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1557                Thread thread = new Thread() {
1558                    @Override public void run() {
1559                        final SparseArray<ProcessMemInfo> infoMap
1560                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1561                        for (int i=0, N=memInfos.size(); i<N; i++) {
1562                            ProcessMemInfo mi = memInfos.get(i);
1563                            infoMap.put(mi.pid, mi);
1564                        }
1565                        updateCpuStatsNow();
1566                        synchronized (mProcessCpuThread) {
1567                            final int N = mProcessCpuTracker.countStats();
1568                            for (int i=0; i<N; i++) {
1569                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1570                                if (st.vsize > 0) {
1571                                    long pss = Debug.getPss(st.pid, null);
1572                                    if (pss > 0) {
1573                                        if (infoMap.indexOfKey(st.pid) < 0) {
1574                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1575                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1576                                            mi.pss = pss;
1577                                            memInfos.add(mi);
1578                                        }
1579                                    }
1580                                }
1581                            }
1582                        }
1583
1584                        long totalPss = 0;
1585                        for (int i=0, N=memInfos.size(); i<N; i++) {
1586                            ProcessMemInfo mi = memInfos.get(i);
1587                            if (mi.pss == 0) {
1588                                mi.pss = Debug.getPss(mi.pid, null);
1589                            }
1590                            totalPss += mi.pss;
1591                        }
1592                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1593                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1594                                if (lhs.oomAdj != rhs.oomAdj) {
1595                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1596                                }
1597                                if (lhs.pss != rhs.pss) {
1598                                    return lhs.pss < rhs.pss ? 1 : -1;
1599                                }
1600                                return 0;
1601                            }
1602                        });
1603
1604                        StringBuilder tag = new StringBuilder(128);
1605                        StringBuilder stack = new StringBuilder(128);
1606                        tag.append("Low on memory -- ");
1607                        appendMemBucket(tag, totalPss, "total", false);
1608                        appendMemBucket(stack, totalPss, "total", true);
1609
1610                        StringBuilder logBuilder = new StringBuilder(1024);
1611                        logBuilder.append("Low on memory:\n");
1612
1613                        boolean firstLine = true;
1614                        int lastOomAdj = Integer.MIN_VALUE;
1615                        for (int i=0, N=memInfos.size(); i<N; i++) {
1616                            ProcessMemInfo mi = memInfos.get(i);
1617
1618                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1619                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1620                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1621                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1622                                if (lastOomAdj != mi.oomAdj) {
1623                                    lastOomAdj = mi.oomAdj;
1624                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1625                                        tag.append(" / ");
1626                                    }
1627                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1628                                        if (firstLine) {
1629                                            stack.append(":");
1630                                            firstLine = false;
1631                                        }
1632                                        stack.append("\n\t at ");
1633                                    } else {
1634                                        stack.append("$");
1635                                    }
1636                                } else {
1637                                    tag.append(" ");
1638                                    stack.append("$");
1639                                }
1640                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1641                                    appendMemBucket(tag, mi.pss, mi.name, false);
1642                                }
1643                                appendMemBucket(stack, mi.pss, mi.name, true);
1644                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1645                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1646                                    stack.append("(");
1647                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1648                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1649                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1650                                            stack.append(":");
1651                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1652                                        }
1653                                    }
1654                                    stack.append(")");
1655                                }
1656                            }
1657
1658                            logBuilder.append("  ");
1659                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1660                            logBuilder.append(' ');
1661                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1662                            logBuilder.append(' ');
1663                            ProcessList.appendRamKb(logBuilder, mi.pss);
1664                            logBuilder.append(" kB: ");
1665                            logBuilder.append(mi.name);
1666                            logBuilder.append(" (");
1667                            logBuilder.append(mi.pid);
1668                            logBuilder.append(") ");
1669                            logBuilder.append(mi.adjType);
1670                            logBuilder.append('\n');
1671                            if (mi.adjReason != null) {
1672                                logBuilder.append("                      ");
1673                                logBuilder.append(mi.adjReason);
1674                                logBuilder.append('\n');
1675                            }
1676                        }
1677
1678                        logBuilder.append("           ");
1679                        ProcessList.appendRamKb(logBuilder, totalPss);
1680                        logBuilder.append(" kB: TOTAL\n");
1681
1682                        long[] infos = new long[Debug.MEMINFO_COUNT];
1683                        Debug.getMemInfo(infos);
1684                        logBuilder.append("  MemInfo: ");
1685                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1686                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1687                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1688                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1689                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1690                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1691                            logBuilder.append("  ZRAM: ");
1692                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1693                            logBuilder.append(" kB RAM, ");
1694                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1695                            logBuilder.append(" kB swap total, ");
1696                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1697                            logBuilder.append(" kB swap free\n");
1698                        }
1699                        Slog.i(TAG, logBuilder.toString());
1700
1701                        StringBuilder dropBuilder = new StringBuilder(1024);
1702                        /*
1703                        StringWriter oomSw = new StringWriter();
1704                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1705                        StringWriter catSw = new StringWriter();
1706                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1707                        String[] emptyArgs = new String[] { };
1708                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1709                        oomPw.flush();
1710                        String oomString = oomSw.toString();
1711                        */
1712                        dropBuilder.append(stack);
1713                        dropBuilder.append('\n');
1714                        dropBuilder.append('\n');
1715                        dropBuilder.append(logBuilder);
1716                        dropBuilder.append('\n');
1717                        /*
1718                        dropBuilder.append(oomString);
1719                        dropBuilder.append('\n');
1720                        */
1721                        StringWriter catSw = new StringWriter();
1722                        synchronized (ActivityManagerService.this) {
1723                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1724                            String[] emptyArgs = new String[] { };
1725                            catPw.println();
1726                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1727                            catPw.println();
1728                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1729                                    false, false, null);
1730                            catPw.println();
1731                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1732                            catPw.flush();
1733                        }
1734                        dropBuilder.append(catSw.toString());
1735                        addErrorToDropBox("lowmem", null, "system_server", null,
1736                                null, tag.toString(), dropBuilder.toString(), null, null);
1737                        //Slog.i(TAG, "Sent to dropbox:");
1738                        //Slog.i(TAG, dropBuilder.toString());
1739                        synchronized (ActivityManagerService.this) {
1740                            long now = SystemClock.uptimeMillis();
1741                            if (mLastMemUsageReportTime < now) {
1742                                mLastMemUsageReportTime = now;
1743                            }
1744                        }
1745                    }
1746                };
1747                thread.start();
1748                break;
1749            }
1750            case REPORT_USER_SWITCH_MSG: {
1751                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1752                break;
1753            }
1754            case CONTINUE_USER_SWITCH_MSG: {
1755                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1756                break;
1757            }
1758            case USER_SWITCH_TIMEOUT_MSG: {
1759                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1760                break;
1761            }
1762            case IMMERSIVE_MODE_LOCK_MSG: {
1763                final boolean nextState = (msg.arg1 != 0);
1764                if (mUpdateLock.isHeld() != nextState) {
1765                    if (DEBUG_IMMERSIVE) {
1766                        final ActivityRecord r = (ActivityRecord) msg.obj;
1767                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1768                    }
1769                    if (nextState) {
1770                        mUpdateLock.acquire();
1771                    } else {
1772                        mUpdateLock.release();
1773                    }
1774                }
1775                break;
1776            }
1777            case PERSIST_URI_GRANTS_MSG: {
1778                writeGrantedUriPermissions();
1779                break;
1780            }
1781            case REQUEST_ALL_PSS_MSG: {
1782                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1783                break;
1784            }
1785            case START_PROFILES_MSG: {
1786                synchronized (ActivityManagerService.this) {
1787                    startProfilesLocked();
1788                }
1789                break;
1790            }
1791            case UPDATE_TIME: {
1792                synchronized (ActivityManagerService.this) {
1793                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1794                        ProcessRecord r = mLruProcesses.get(i);
1795                        if (r.thread != null) {
1796                            try {
1797                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1798                            } catch (RemoteException ex) {
1799                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1800                            }
1801                        }
1802                    }
1803                }
1804                break;
1805            }
1806            case SYSTEM_USER_START_MSG: {
1807                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1808                        Integer.toString(msg.arg1), msg.arg1);
1809                mSystemServiceManager.startUser(msg.arg1);
1810                break;
1811            }
1812            case SYSTEM_USER_CURRENT_MSG: {
1813                mBatteryStatsService.noteEvent(
1814                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1815                        Integer.toString(msg.arg2), msg.arg2);
1816                mBatteryStatsService.noteEvent(
1817                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1818                        Integer.toString(msg.arg1), msg.arg1);
1819                mSystemServiceManager.switchUser(msg.arg1);
1820                break;
1821            }
1822            case ENTER_ANIMATION_COMPLETE_MSG: {
1823                synchronized (ActivityManagerService.this) {
1824                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1825                    if (r != null && r.app != null && r.app.thread != null) {
1826                        try {
1827                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1828                        } catch (RemoteException e) {
1829                        }
1830                    }
1831                }
1832                break;
1833            }
1834            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1835                enableScreenAfterBoot();
1836                break;
1837            }
1838            }
1839        }
1840    };
1841
1842    static final int COLLECT_PSS_BG_MSG = 1;
1843
1844    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1845        @Override
1846        public void handleMessage(Message msg) {
1847            switch (msg.what) {
1848            case COLLECT_PSS_BG_MSG: {
1849                long start = SystemClock.uptimeMillis();
1850                MemInfoReader memInfo = null;
1851                synchronized (ActivityManagerService.this) {
1852                    if (mFullPssPending) {
1853                        mFullPssPending = false;
1854                        memInfo = new MemInfoReader();
1855                    }
1856                }
1857                if (memInfo != null) {
1858                    updateCpuStatsNow();
1859                    long nativeTotalPss = 0;
1860                    synchronized (mProcessCpuThread) {
1861                        final int N = mProcessCpuTracker.countStats();
1862                        for (int j=0; j<N; j++) {
1863                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1864                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1865                                // This is definitely an application process; skip it.
1866                                continue;
1867                            }
1868                            synchronized (mPidsSelfLocked) {
1869                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1870                                    // This is one of our own processes; skip it.
1871                                    continue;
1872                                }
1873                            }
1874                            nativeTotalPss += Debug.getPss(st.pid, null);
1875                        }
1876                    }
1877                    memInfo.readMemInfo();
1878                    synchronized (this) {
1879                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1880                                + (SystemClock.uptimeMillis()-start) + "ms");
1881                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1882                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1883                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1884                                        +memInfo.getSlabSizeKb(),
1885                                nativeTotalPss);
1886                    }
1887                }
1888
1889                int i=0, num=0;
1890                long[] tmp = new long[1];
1891                do {
1892                    ProcessRecord proc;
1893                    int procState;
1894                    int pid;
1895                    synchronized (ActivityManagerService.this) {
1896                        if (i >= mPendingPssProcesses.size()) {
1897                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1898                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1899                            mPendingPssProcesses.clear();
1900                            return;
1901                        }
1902                        proc = mPendingPssProcesses.get(i);
1903                        procState = proc.pssProcState;
1904                        if (proc.thread != null && procState == proc.setProcState) {
1905                            pid = proc.pid;
1906                        } else {
1907                            proc = null;
1908                            pid = 0;
1909                        }
1910                        i++;
1911                    }
1912                    if (proc != null) {
1913                        long pss = Debug.getPss(pid, tmp);
1914                        synchronized (ActivityManagerService.this) {
1915                            if (proc.thread != null && proc.setProcState == procState
1916                                    && proc.pid == pid) {
1917                                num++;
1918                                proc.lastPssTime = SystemClock.uptimeMillis();
1919                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1920                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1921                                        + ": " + pss + " lastPss=" + proc.lastPss
1922                                        + " state=" + ProcessList.makeProcStateString(procState));
1923                                if (proc.initialIdlePss == 0) {
1924                                    proc.initialIdlePss = pss;
1925                                }
1926                                proc.lastPss = pss;
1927                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1928                                    proc.lastCachedPss = pss;
1929                                }
1930                            }
1931                        }
1932                    }
1933                } while (true);
1934            }
1935            }
1936        }
1937    };
1938
1939    /**
1940     * Monitor for package changes and update our internal state.
1941     */
1942    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1943        @Override
1944        public void onPackageRemoved(String packageName, int uid) {
1945            // Remove all tasks with activities in the specified package from the list of recent tasks
1946            synchronized (ActivityManagerService.this) {
1947                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1948                    TaskRecord tr = mRecentTasks.get(i);
1949                    ComponentName cn = tr.intent.getComponent();
1950                    if (cn != null && cn.getPackageName().equals(packageName)) {
1951                        // If the package name matches, remove the task and kill the process
1952                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1953                    }
1954                }
1955            }
1956        }
1957
1958        @Override
1959        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1960            onPackageModified(packageName);
1961            return true;
1962        }
1963
1964        @Override
1965        public void onPackageModified(String packageName) {
1966            final PackageManager pm = mContext.getPackageManager();
1967            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1968                    new ArrayList<Pair<Intent, Integer>>();
1969            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1970            // Copy the list of recent tasks so that we don't hold onto the lock on
1971            // ActivityManagerService for long periods while checking if components exist.
1972            synchronized (ActivityManagerService.this) {
1973                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1974                    TaskRecord tr = mRecentTasks.get(i);
1975                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1976                }
1977            }
1978            // Check the recent tasks and filter out all tasks with components that no longer exist.
1979            Intent tmpI = new Intent();
1980            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1981                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1982                ComponentName cn = p.first.getComponent();
1983                if (cn != null && cn.getPackageName().equals(packageName)) {
1984                    try {
1985                        // Add the task to the list to remove if the component no longer exists
1986                        tmpI.setComponent(cn);
1987                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1988                            tasksToRemove.add(p.second);
1989                        }
1990                    } catch (Exception e) {}
1991                }
1992            }
1993            // Prune all the tasks with removed components from the list of recent tasks
1994            synchronized (ActivityManagerService.this) {
1995                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1996                    // Remove the task but don't kill the process (since other components in that
1997                    // package may still be running and in the background)
1998                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1999                }
2000            }
2001        }
2002
2003        @Override
2004        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2005            // Force stop the specified packages
2006            if (packages != null) {
2007                for (String pkg : packages) {
2008                    synchronized (ActivityManagerService.this) {
2009                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2010                                "finished booting")) {
2011                            return true;
2012                        }
2013                    }
2014                }
2015            }
2016            return false;
2017        }
2018    };
2019
2020    public void setSystemProcess() {
2021        try {
2022            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2023            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2024            ServiceManager.addService("meminfo", new MemBinder(this));
2025            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2026            ServiceManager.addService("dbinfo", new DbBinder(this));
2027            if (MONITOR_CPU_USAGE) {
2028                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2029            }
2030            ServiceManager.addService("permission", new PermissionController(this));
2031
2032            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2033                    "android", STOCK_PM_FLAGS);
2034            mSystemThread.installSystemApplicationInfo(info);
2035
2036            synchronized (this) {
2037                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2038                app.persistent = true;
2039                app.pid = MY_PID;
2040                app.maxAdj = ProcessList.SYSTEM_ADJ;
2041                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2042                mProcessNames.put(app.processName, app.uid, app);
2043                synchronized (mPidsSelfLocked) {
2044                    mPidsSelfLocked.put(app.pid, app);
2045                }
2046                updateLruProcessLocked(app, false, null);
2047                updateOomAdjLocked();
2048            }
2049        } catch (PackageManager.NameNotFoundException e) {
2050            throw new RuntimeException(
2051                    "Unable to find android system package", e);
2052        }
2053    }
2054
2055    public void setWindowManager(WindowManagerService wm) {
2056        mWindowManager = wm;
2057        mStackSupervisor.setWindowManager(wm);
2058    }
2059
2060    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2061        mUsageStatsService = usageStatsManager;
2062    }
2063
2064    public void startObservingNativeCrashes() {
2065        final NativeCrashListener ncl = new NativeCrashListener(this);
2066        ncl.start();
2067    }
2068
2069    public IAppOpsService getAppOpsService() {
2070        return mAppOpsService;
2071    }
2072
2073    static class MemBinder extends Binder {
2074        ActivityManagerService mActivityManagerService;
2075        MemBinder(ActivityManagerService activityManagerService) {
2076            mActivityManagerService = activityManagerService;
2077        }
2078
2079        @Override
2080        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2081            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2082                    != PackageManager.PERMISSION_GRANTED) {
2083                pw.println("Permission Denial: can't dump meminfo from from pid="
2084                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2085                        + " without permission " + android.Manifest.permission.DUMP);
2086                return;
2087            }
2088
2089            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2090        }
2091    }
2092
2093    static class GraphicsBinder extends Binder {
2094        ActivityManagerService mActivityManagerService;
2095        GraphicsBinder(ActivityManagerService activityManagerService) {
2096            mActivityManagerService = activityManagerService;
2097        }
2098
2099        @Override
2100        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2101            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2102                    != PackageManager.PERMISSION_GRANTED) {
2103                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2104                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2105                        + " without permission " + android.Manifest.permission.DUMP);
2106                return;
2107            }
2108
2109            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2110        }
2111    }
2112
2113    static class DbBinder extends Binder {
2114        ActivityManagerService mActivityManagerService;
2115        DbBinder(ActivityManagerService activityManagerService) {
2116            mActivityManagerService = activityManagerService;
2117        }
2118
2119        @Override
2120        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2121            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2122                    != PackageManager.PERMISSION_GRANTED) {
2123                pw.println("Permission Denial: can't dump dbinfo from from pid="
2124                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2125                        + " without permission " + android.Manifest.permission.DUMP);
2126                return;
2127            }
2128
2129            mActivityManagerService.dumpDbInfo(fd, pw, args);
2130        }
2131    }
2132
2133    static class CpuBinder extends Binder {
2134        ActivityManagerService mActivityManagerService;
2135        CpuBinder(ActivityManagerService activityManagerService) {
2136            mActivityManagerService = activityManagerService;
2137        }
2138
2139        @Override
2140        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2141            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2142                    != PackageManager.PERMISSION_GRANTED) {
2143                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2144                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2145                        + " without permission " + android.Manifest.permission.DUMP);
2146                return;
2147            }
2148
2149            synchronized (mActivityManagerService.mProcessCpuThread) {
2150                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2151                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2152                        SystemClock.uptimeMillis()));
2153            }
2154        }
2155    }
2156
2157    public static final class Lifecycle extends SystemService {
2158        private final ActivityManagerService mService;
2159
2160        public Lifecycle(Context context) {
2161            super(context);
2162            mService = new ActivityManagerService(context);
2163        }
2164
2165        @Override
2166        public void onStart() {
2167            mService.start();
2168        }
2169
2170        public ActivityManagerService getService() {
2171            return mService;
2172        }
2173    }
2174
2175    // Note: This method is invoked on the main thread but may need to attach various
2176    // handlers to other threads.  So take care to be explicit about the looper.
2177    public ActivityManagerService(Context systemContext) {
2178        mContext = systemContext;
2179        mFactoryTest = FactoryTest.getMode();
2180        mSystemThread = ActivityThread.currentActivityThread();
2181
2182        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2183
2184        mHandlerThread = new ServiceThread(TAG,
2185                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2186        mHandlerThread.start();
2187        mHandler = new MainHandler(mHandlerThread.getLooper());
2188
2189        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2190                "foreground", BROADCAST_FG_TIMEOUT, false);
2191        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2192                "background", BROADCAST_BG_TIMEOUT, true);
2193        mBroadcastQueues[0] = mFgBroadcastQueue;
2194        mBroadcastQueues[1] = mBgBroadcastQueue;
2195
2196        mServices = new ActiveServices(this);
2197        mProviderMap = new ProviderMap(this);
2198
2199        // TODO: Move creation of battery stats service outside of activity manager service.
2200        File dataDir = Environment.getDataDirectory();
2201        File systemDir = new File(dataDir, "system");
2202        systemDir.mkdirs();
2203        mBatteryStatsService = new BatteryStatsService(new File(
2204                systemDir, "batterystats.bin").toString(), mHandler);
2205        mBatteryStatsService.getActiveStatistics().readLocked();
2206        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2207        mOnBattery = DEBUG_POWER ? true
2208                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2209        mBatteryStatsService.getActiveStatistics().setCallback(this);
2210
2211        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2212
2213        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2214
2215        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2216
2217        // User 0 is the first and only user that runs at boot.
2218        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2219        mUserLru.add(Integer.valueOf(0));
2220        updateStartedUserArrayLocked();
2221
2222        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2223            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2224
2225        mConfiguration.setToDefaults();
2226        mConfiguration.setLocale(Locale.getDefault());
2227
2228        mConfigurationSeq = mConfiguration.seq = 1;
2229        mProcessCpuTracker.init();
2230
2231        mHasRecents = mContext.getResources().getBoolean(
2232                com.android.internal.R.bool.config_hasRecents);
2233
2234        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2235        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2236        mStackSupervisor = new ActivityStackSupervisor(this);
2237        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2238
2239        mProcessCpuThread = new Thread("CpuTracker") {
2240            @Override
2241            public void run() {
2242                while (true) {
2243                    try {
2244                        try {
2245                            synchronized(this) {
2246                                final long now = SystemClock.uptimeMillis();
2247                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2248                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2249                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2250                                //        + ", write delay=" + nextWriteDelay);
2251                                if (nextWriteDelay < nextCpuDelay) {
2252                                    nextCpuDelay = nextWriteDelay;
2253                                }
2254                                if (nextCpuDelay > 0) {
2255                                    mProcessCpuMutexFree.set(true);
2256                                    this.wait(nextCpuDelay);
2257                                }
2258                            }
2259                        } catch (InterruptedException e) {
2260                        }
2261                        updateCpuStatsNow();
2262                    } catch (Exception e) {
2263                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2264                    }
2265                }
2266            }
2267        };
2268
2269        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2270
2271        Watchdog.getInstance().addMonitor(this);
2272        Watchdog.getInstance().addThread(mHandler);
2273    }
2274
2275    public void setSystemServiceManager(SystemServiceManager mgr) {
2276        mSystemServiceManager = mgr;
2277    }
2278
2279    private void start() {
2280        Process.removeAllProcessGroups();
2281        mProcessCpuThread.start();
2282
2283        mBatteryStatsService.publish(mContext);
2284        mAppOpsService.publish(mContext);
2285        Slog.d("AppOps", "AppOpsService published");
2286        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2287    }
2288
2289    public void initPowerManagement() {
2290        mStackSupervisor.initPowerManagement();
2291        mBatteryStatsService.initPowerManagement();
2292    }
2293
2294    @Override
2295    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2296            throws RemoteException {
2297        if (code == SYSPROPS_TRANSACTION) {
2298            // We need to tell all apps about the system property change.
2299            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2300            synchronized(this) {
2301                final int NP = mProcessNames.getMap().size();
2302                for (int ip=0; ip<NP; ip++) {
2303                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2304                    final int NA = apps.size();
2305                    for (int ia=0; ia<NA; ia++) {
2306                        ProcessRecord app = apps.valueAt(ia);
2307                        if (app.thread != null) {
2308                            procs.add(app.thread.asBinder());
2309                        }
2310                    }
2311                }
2312            }
2313
2314            int N = procs.size();
2315            for (int i=0; i<N; i++) {
2316                Parcel data2 = Parcel.obtain();
2317                try {
2318                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2319                } catch (RemoteException e) {
2320                }
2321                data2.recycle();
2322            }
2323        }
2324        try {
2325            return super.onTransact(code, data, reply, flags);
2326        } catch (RuntimeException e) {
2327            // The activity manager only throws security exceptions, so let's
2328            // log all others.
2329            if (!(e instanceof SecurityException)) {
2330                Slog.wtf(TAG, "Activity Manager Crash", e);
2331            }
2332            throw e;
2333        }
2334    }
2335
2336    void updateCpuStats() {
2337        final long now = SystemClock.uptimeMillis();
2338        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2339            return;
2340        }
2341        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2342            synchronized (mProcessCpuThread) {
2343                mProcessCpuThread.notify();
2344            }
2345        }
2346    }
2347
2348    void updateCpuStatsNow() {
2349        synchronized (mProcessCpuThread) {
2350            mProcessCpuMutexFree.set(false);
2351            final long now = SystemClock.uptimeMillis();
2352            boolean haveNewCpuStats = false;
2353
2354            if (MONITOR_CPU_USAGE &&
2355                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2356                mLastCpuTime.set(now);
2357                haveNewCpuStats = true;
2358                mProcessCpuTracker.update();
2359                //Slog.i(TAG, mProcessCpu.printCurrentState());
2360                //Slog.i(TAG, "Total CPU usage: "
2361                //        + mProcessCpu.getTotalCpuPercent() + "%");
2362
2363                // Slog the cpu usage if the property is set.
2364                if ("true".equals(SystemProperties.get("events.cpu"))) {
2365                    int user = mProcessCpuTracker.getLastUserTime();
2366                    int system = mProcessCpuTracker.getLastSystemTime();
2367                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2368                    int irq = mProcessCpuTracker.getLastIrqTime();
2369                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2370                    int idle = mProcessCpuTracker.getLastIdleTime();
2371
2372                    int total = user + system + iowait + irq + softIrq + idle;
2373                    if (total == 0) total = 1;
2374
2375                    EventLog.writeEvent(EventLogTags.CPU,
2376                            ((user+system+iowait+irq+softIrq) * 100) / total,
2377                            (user * 100) / total,
2378                            (system * 100) / total,
2379                            (iowait * 100) / total,
2380                            (irq * 100) / total,
2381                            (softIrq * 100) / total);
2382                }
2383            }
2384
2385            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2386            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2387            synchronized(bstats) {
2388                synchronized(mPidsSelfLocked) {
2389                    if (haveNewCpuStats) {
2390                        if (mOnBattery) {
2391                            int perc = bstats.startAddingCpuLocked();
2392                            int totalUTime = 0;
2393                            int totalSTime = 0;
2394                            final int N = mProcessCpuTracker.countStats();
2395                            for (int i=0; i<N; i++) {
2396                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2397                                if (!st.working) {
2398                                    continue;
2399                                }
2400                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2401                                int otherUTime = (st.rel_utime*perc)/100;
2402                                int otherSTime = (st.rel_stime*perc)/100;
2403                                totalUTime += otherUTime;
2404                                totalSTime += otherSTime;
2405                                if (pr != null) {
2406                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2407                                    if (ps == null || !ps.isActive()) {
2408                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2409                                                pr.info.uid, pr.processName);
2410                                    }
2411                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2412                                            st.rel_stime-otherSTime);
2413                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2414                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2415                                } else {
2416                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2417                                    if (ps == null || !ps.isActive()) {
2418                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2419                                                bstats.mapUid(st.uid), st.name);
2420                                    }
2421                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2422                                            st.rel_stime-otherSTime);
2423                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2424                                }
2425                            }
2426                            bstats.finishAddingCpuLocked(perc, totalUTime,
2427                                    totalSTime, cpuSpeedTimes);
2428                        }
2429                    }
2430                }
2431
2432                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2433                    mLastWriteTime = now;
2434                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2435                }
2436            }
2437        }
2438    }
2439
2440    @Override
2441    public void batteryNeedsCpuUpdate() {
2442        updateCpuStatsNow();
2443    }
2444
2445    @Override
2446    public void batteryPowerChanged(boolean onBattery) {
2447        // When plugging in, update the CPU stats first before changing
2448        // the plug state.
2449        updateCpuStatsNow();
2450        synchronized (this) {
2451            synchronized(mPidsSelfLocked) {
2452                mOnBattery = DEBUG_POWER ? true : onBattery;
2453            }
2454        }
2455    }
2456
2457    /**
2458     * Initialize the application bind args. These are passed to each
2459     * process when the bindApplication() IPC is sent to the process. They're
2460     * lazily setup to make sure the services are running when they're asked for.
2461     */
2462    private HashMap<String, IBinder> getCommonServicesLocked() {
2463        if (mAppBindArgs == null) {
2464            mAppBindArgs = new HashMap<String, IBinder>();
2465
2466            // Setup the application init args
2467            mAppBindArgs.put("package", ServiceManager.getService("package"));
2468            mAppBindArgs.put("window", ServiceManager.getService("window"));
2469            mAppBindArgs.put(Context.ALARM_SERVICE,
2470                    ServiceManager.getService(Context.ALARM_SERVICE));
2471        }
2472        return mAppBindArgs;
2473    }
2474
2475    final void setFocusedActivityLocked(ActivityRecord r) {
2476        if (mFocusedActivity != r) {
2477            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2478            mFocusedActivity = r;
2479            if (r.task != null && r.task.voiceInteractor != null) {
2480                startRunningVoiceLocked();
2481            } else {
2482                finishRunningVoiceLocked();
2483            }
2484            mStackSupervisor.setFocusedStack(r);
2485            if (r != null) {
2486                mWindowManager.setFocusedApp(r.appToken, true);
2487            }
2488            applyUpdateLockStateLocked(r);
2489        }
2490    }
2491
2492    final void clearFocusedActivity(ActivityRecord r) {
2493        if (mFocusedActivity == r) {
2494            mFocusedActivity = null;
2495        }
2496    }
2497
2498    @Override
2499    public void setFocusedStack(int stackId) {
2500        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2501        synchronized (ActivityManagerService.this) {
2502            ActivityStack stack = mStackSupervisor.getStack(stackId);
2503            if (stack != null) {
2504                ActivityRecord r = stack.topRunningActivityLocked(null);
2505                if (r != null) {
2506                    setFocusedActivityLocked(r);
2507                }
2508            }
2509        }
2510    }
2511
2512    @Override
2513    public void notifyActivityDrawn(IBinder token) {
2514        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2515        synchronized (this) {
2516            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2517            if (r != null) {
2518                r.task.stack.notifyActivityDrawnLocked(r);
2519            }
2520        }
2521    }
2522
2523    final void applyUpdateLockStateLocked(ActivityRecord r) {
2524        // Modifications to the UpdateLock state are done on our handler, outside
2525        // the activity manager's locks.  The new state is determined based on the
2526        // state *now* of the relevant activity record.  The object is passed to
2527        // the handler solely for logging detail, not to be consulted/modified.
2528        final boolean nextState = r != null && r.immersive;
2529        mHandler.sendMessage(
2530                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2531    }
2532
2533    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2534        Message msg = Message.obtain();
2535        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2536        msg.obj = r.task.askedCompatMode ? null : r;
2537        mHandler.sendMessage(msg);
2538    }
2539
2540    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2541            String what, Object obj, ProcessRecord srcApp) {
2542        app.lastActivityTime = now;
2543
2544        if (app.activities.size() > 0) {
2545            // Don't want to touch dependent processes that are hosting activities.
2546            return index;
2547        }
2548
2549        int lrui = mLruProcesses.lastIndexOf(app);
2550        if (lrui < 0) {
2551            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2552                    + what + " " + obj + " from " + srcApp);
2553            return index;
2554        }
2555
2556        if (lrui >= index) {
2557            // Don't want to cause this to move dependent processes *back* in the
2558            // list as if they were less frequently used.
2559            return index;
2560        }
2561
2562        if (lrui >= mLruProcessActivityStart) {
2563            // Don't want to touch dependent processes that are hosting activities.
2564            return index;
2565        }
2566
2567        mLruProcesses.remove(lrui);
2568        if (index > 0) {
2569            index--;
2570        }
2571        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2572                + " in LRU list: " + app);
2573        mLruProcesses.add(index, app);
2574        return index;
2575    }
2576
2577    final void removeLruProcessLocked(ProcessRecord app) {
2578        int lrui = mLruProcesses.lastIndexOf(app);
2579        if (lrui >= 0) {
2580            if (lrui <= mLruProcessActivityStart) {
2581                mLruProcessActivityStart--;
2582            }
2583            if (lrui <= mLruProcessServiceStart) {
2584                mLruProcessServiceStart--;
2585            }
2586            mLruProcesses.remove(lrui);
2587        }
2588    }
2589
2590    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2591            ProcessRecord client) {
2592        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2593                || app.treatLikeActivity;
2594        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2595        if (!activityChange && hasActivity) {
2596            // The process has activities, so we are only allowing activity-based adjustments
2597            // to move it.  It should be kept in the front of the list with other
2598            // processes that have activities, and we don't want those to change their
2599            // order except due to activity operations.
2600            return;
2601        }
2602
2603        mLruSeq++;
2604        final long now = SystemClock.uptimeMillis();
2605        app.lastActivityTime = now;
2606
2607        // First a quick reject: if the app is already at the position we will
2608        // put it, then there is nothing to do.
2609        if (hasActivity) {
2610            final int N = mLruProcesses.size();
2611            if (N > 0 && mLruProcesses.get(N-1) == app) {
2612                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2613                return;
2614            }
2615        } else {
2616            if (mLruProcessServiceStart > 0
2617                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2618                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2619                return;
2620            }
2621        }
2622
2623        int lrui = mLruProcesses.lastIndexOf(app);
2624
2625        if (app.persistent && lrui >= 0) {
2626            // We don't care about the position of persistent processes, as long as
2627            // they are in the list.
2628            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2629            return;
2630        }
2631
2632        /* In progress: compute new position first, so we can avoid doing work
2633           if the process is not actually going to move.  Not yet working.
2634        int addIndex;
2635        int nextIndex;
2636        boolean inActivity = false, inService = false;
2637        if (hasActivity) {
2638            // Process has activities, put it at the very tipsy-top.
2639            addIndex = mLruProcesses.size();
2640            nextIndex = mLruProcessServiceStart;
2641            inActivity = true;
2642        } else if (hasService) {
2643            // Process has services, put it at the top of the service list.
2644            addIndex = mLruProcessActivityStart;
2645            nextIndex = mLruProcessServiceStart;
2646            inActivity = true;
2647            inService = true;
2648        } else  {
2649            // Process not otherwise of interest, it goes to the top of the non-service area.
2650            addIndex = mLruProcessServiceStart;
2651            if (client != null) {
2652                int clientIndex = mLruProcesses.lastIndexOf(client);
2653                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2654                        + app);
2655                if (clientIndex >= 0 && addIndex > clientIndex) {
2656                    addIndex = clientIndex;
2657                }
2658            }
2659            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2660        }
2661
2662        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2663                + mLruProcessActivityStart + "): " + app);
2664        */
2665
2666        if (lrui >= 0) {
2667            if (lrui < mLruProcessActivityStart) {
2668                mLruProcessActivityStart--;
2669            }
2670            if (lrui < mLruProcessServiceStart) {
2671                mLruProcessServiceStart--;
2672            }
2673            /*
2674            if (addIndex > lrui) {
2675                addIndex--;
2676            }
2677            if (nextIndex > lrui) {
2678                nextIndex--;
2679            }
2680            */
2681            mLruProcesses.remove(lrui);
2682        }
2683
2684        /*
2685        mLruProcesses.add(addIndex, app);
2686        if (inActivity) {
2687            mLruProcessActivityStart++;
2688        }
2689        if (inService) {
2690            mLruProcessActivityStart++;
2691        }
2692        */
2693
2694        int nextIndex;
2695        if (hasActivity) {
2696            final int N = mLruProcesses.size();
2697            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2698                // Process doesn't have activities, but has clients with
2699                // activities...  move it up, but one below the top (the top
2700                // should always have a real activity).
2701                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2702                mLruProcesses.add(N-1, app);
2703                // To keep it from spamming the LRU list (by making a bunch of clients),
2704                // we will push down any other entries owned by the app.
2705                final int uid = app.info.uid;
2706                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2707                    ProcessRecord subProc = mLruProcesses.get(i);
2708                    if (subProc.info.uid == uid) {
2709                        // We want to push this one down the list.  If the process after
2710                        // it is for the same uid, however, don't do so, because we don't
2711                        // want them internally to be re-ordered.
2712                        if (mLruProcesses.get(i-1).info.uid != uid) {
2713                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2714                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2715                            ProcessRecord tmp = mLruProcesses.get(i);
2716                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2717                            mLruProcesses.set(i-1, tmp);
2718                            i--;
2719                        }
2720                    } else {
2721                        // A gap, we can stop here.
2722                        break;
2723                    }
2724                }
2725            } else {
2726                // Process has activities, put it at the very tipsy-top.
2727                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2728                mLruProcesses.add(app);
2729            }
2730            nextIndex = mLruProcessServiceStart;
2731        } else if (hasService) {
2732            // Process has services, put it at the top of the service list.
2733            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2734            mLruProcesses.add(mLruProcessActivityStart, app);
2735            nextIndex = mLruProcessServiceStart;
2736            mLruProcessActivityStart++;
2737        } else  {
2738            // Process not otherwise of interest, it goes to the top of the non-service area.
2739            int index = mLruProcessServiceStart;
2740            if (client != null) {
2741                // If there is a client, don't allow the process to be moved up higher
2742                // in the list than that client.
2743                int clientIndex = mLruProcesses.lastIndexOf(client);
2744                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2745                        + " when updating " + app);
2746                if (clientIndex <= lrui) {
2747                    // Don't allow the client index restriction to push it down farther in the
2748                    // list than it already is.
2749                    clientIndex = lrui;
2750                }
2751                if (clientIndex >= 0 && index > clientIndex) {
2752                    index = clientIndex;
2753                }
2754            }
2755            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2756            mLruProcesses.add(index, app);
2757            nextIndex = index-1;
2758            mLruProcessActivityStart++;
2759            mLruProcessServiceStart++;
2760        }
2761
2762        // If the app is currently using a content provider or service,
2763        // bump those processes as well.
2764        for (int j=app.connections.size()-1; j>=0; j--) {
2765            ConnectionRecord cr = app.connections.valueAt(j);
2766            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2767                    && cr.binding.service.app != null
2768                    && cr.binding.service.app.lruSeq != mLruSeq
2769                    && !cr.binding.service.app.persistent) {
2770                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2771                        "service connection", cr, app);
2772            }
2773        }
2774        for (int j=app.conProviders.size()-1; j>=0; j--) {
2775            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2776            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2777                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2778                        "provider reference", cpr, app);
2779            }
2780        }
2781    }
2782
2783    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2784        if (uid == Process.SYSTEM_UID) {
2785            // The system gets to run in any process.  If there are multiple
2786            // processes with the same uid, just pick the first (this
2787            // should never happen).
2788            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2789            if (procs == null) return null;
2790            final int N = procs.size();
2791            for (int i = 0; i < N; i++) {
2792                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2793            }
2794        }
2795        ProcessRecord proc = mProcessNames.get(processName, uid);
2796        if (false && proc != null && !keepIfLarge
2797                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2798                && proc.lastCachedPss >= 4000) {
2799            // Turn this condition on to cause killing to happen regularly, for testing.
2800            if (proc.baseProcessTracker != null) {
2801                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2802            }
2803            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2804                    + "k from cached");
2805        } else if (proc != null && !keepIfLarge
2806                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2807                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2808            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2809            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2810                if (proc.baseProcessTracker != null) {
2811                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2812                }
2813                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2814                        + "k from cached");
2815            }
2816        }
2817        return proc;
2818    }
2819
2820    void ensurePackageDexOpt(String packageName) {
2821        IPackageManager pm = AppGlobals.getPackageManager();
2822        try {
2823            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2824                mDidDexOpt = true;
2825            }
2826        } catch (RemoteException e) {
2827        }
2828    }
2829
2830    boolean isNextTransitionForward() {
2831        int transit = mWindowManager.getPendingAppTransition();
2832        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2833                || transit == AppTransition.TRANSIT_TASK_OPEN
2834                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2835    }
2836
2837    final ProcessRecord startProcessLocked(String processName,
2838            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2839            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2840            boolean isolated, boolean keepIfLarge) {
2841        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2842                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2843                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2844                null /* crashHandler */);
2845    }
2846
2847    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2848            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2849            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2850            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2851        ProcessRecord app;
2852        if (!isolated) {
2853            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2854        } else {
2855            // If this is an isolated process, it can't re-use an existing process.
2856            app = null;
2857        }
2858        // We don't have to do anything more if:
2859        // (1) There is an existing application record; and
2860        // (2) The caller doesn't think it is dead, OR there is no thread
2861        //     object attached to it so we know it couldn't have crashed; and
2862        // (3) There is a pid assigned to it, so it is either starting or
2863        //     already running.
2864        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2865                + " app=" + app + " knownToBeDead=" + knownToBeDead
2866                + " thread=" + (app != null ? app.thread : null)
2867                + " pid=" + (app != null ? app.pid : -1));
2868        if (app != null && app.pid > 0) {
2869            if (!knownToBeDead || app.thread == null) {
2870                // We already have the app running, or are waiting for it to
2871                // come up (we have a pid but not yet its thread), so keep it.
2872                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2873                // If this is a new package in the process, add the package to the list
2874                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2875                return app;
2876            }
2877
2878            // An application record is attached to a previous process,
2879            // clean it up now.
2880            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2881            Process.killProcessGroup(app.info.uid, app.pid);
2882            handleAppDiedLocked(app, true, true);
2883        }
2884
2885        String hostingNameStr = hostingName != null
2886                ? hostingName.flattenToShortString() : null;
2887
2888        if (!isolated) {
2889            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2890                // If we are in the background, then check to see if this process
2891                // is bad.  If so, we will just silently fail.
2892                if (mBadProcesses.get(info.processName, info.uid) != null) {
2893                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2894                            + "/" + info.processName);
2895                    return null;
2896                }
2897            } else {
2898                // When the user is explicitly starting a process, then clear its
2899                // crash count so that we won't make it bad until they see at
2900                // least one crash dialog again, and make the process good again
2901                // if it had been bad.
2902                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2903                        + "/" + info.processName);
2904                mProcessCrashTimes.remove(info.processName, info.uid);
2905                if (mBadProcesses.get(info.processName, info.uid) != null) {
2906                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2907                            UserHandle.getUserId(info.uid), info.uid,
2908                            info.processName);
2909                    mBadProcesses.remove(info.processName, info.uid);
2910                    if (app != null) {
2911                        app.bad = false;
2912                    }
2913                }
2914            }
2915        }
2916
2917        if (app == null) {
2918            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2919            app.crashHandler = crashHandler;
2920            if (app == null) {
2921                Slog.w(TAG, "Failed making new process record for "
2922                        + processName + "/" + info.uid + " isolated=" + isolated);
2923                return null;
2924            }
2925            mProcessNames.put(processName, app.uid, app);
2926            if (isolated) {
2927                mIsolatedProcesses.put(app.uid, app);
2928            }
2929        } else {
2930            // If this is a new package in the process, add the package to the list
2931            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2932        }
2933
2934        // If the system is not ready yet, then hold off on starting this
2935        // process until it is.
2936        if (!mProcessesReady
2937                && !isAllowedWhileBooting(info)
2938                && !allowWhileBooting) {
2939            if (!mProcessesOnHold.contains(app)) {
2940                mProcessesOnHold.add(app);
2941            }
2942            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2943            return app;
2944        }
2945
2946        startProcessLocked(
2947                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2948        return (app.pid != 0) ? app : null;
2949    }
2950
2951    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2952        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2953    }
2954
2955    private final void startProcessLocked(ProcessRecord app,
2956            String hostingType, String hostingNameStr) {
2957        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2958                null /* entryPoint */, null /* entryPointArgs */);
2959    }
2960
2961    private final void startProcessLocked(ProcessRecord app, String hostingType,
2962            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2963        if (app.pid > 0 && app.pid != MY_PID) {
2964            synchronized (mPidsSelfLocked) {
2965                mPidsSelfLocked.remove(app.pid);
2966                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2967            }
2968            app.setPid(0);
2969        }
2970
2971        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2972                "startProcessLocked removing on hold: " + app);
2973        mProcessesOnHold.remove(app);
2974
2975        updateCpuStats();
2976
2977        try {
2978            int uid = app.uid;
2979
2980            int[] gids = null;
2981            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2982            if (!app.isolated) {
2983                int[] permGids = null;
2984                try {
2985                    final PackageManager pm = mContext.getPackageManager();
2986                    permGids = pm.getPackageGids(app.info.packageName);
2987
2988                    if (Environment.isExternalStorageEmulated()) {
2989                        if (pm.checkPermission(
2990                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2991                                app.info.packageName) == PERMISSION_GRANTED) {
2992                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2993                        } else {
2994                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2995                        }
2996                    }
2997                } catch (PackageManager.NameNotFoundException e) {
2998                    Slog.w(TAG, "Unable to retrieve gids", e);
2999                }
3000
3001                /*
3002                 * Add shared application and profile GIDs so applications can share some
3003                 * resources like shared libraries and access user-wide resources
3004                 */
3005                if (permGids == null) {
3006                    gids = new int[2];
3007                } else {
3008                    gids = new int[permGids.length + 2];
3009                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3010                }
3011                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3012                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3013            }
3014            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3015                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3016                        && mTopComponent != null
3017                        && app.processName.equals(mTopComponent.getPackageName())) {
3018                    uid = 0;
3019                }
3020                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3021                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3022                    uid = 0;
3023                }
3024            }
3025            int debugFlags = 0;
3026            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3027                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3028                // Also turn on CheckJNI for debuggable apps. It's quite
3029                // awkward to turn on otherwise.
3030                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3031            }
3032            // Run the app in safe mode if its manifest requests so or the
3033            // system is booted in safe mode.
3034            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3035                mSafeMode == true) {
3036                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3037            }
3038            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3039                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3040            }
3041            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3042                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3043            }
3044            if ("1".equals(SystemProperties.get("debug.assert"))) {
3045                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3046            }
3047
3048            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3049            if (requiredAbi == null) {
3050                requiredAbi = Build.SUPPORTED_ABIS[0];
3051            }
3052
3053            // Start the process.  It will either succeed and return a result containing
3054            // the PID of the new process, or else throw a RuntimeException.
3055            boolean isActivityProcess = (entryPoint == null);
3056            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3057            Process.ProcessStartResult startResult = Process.start(entryPoint,
3058                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3059                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
3060
3061            if (app.isolated) {
3062                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3063            }
3064            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3065
3066            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3067                    UserHandle.getUserId(uid), startResult.pid, uid,
3068                    app.processName, hostingType,
3069                    hostingNameStr != null ? hostingNameStr : "");
3070
3071            if (app.persistent) {
3072                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3073            }
3074
3075            StringBuilder buf = mStringBuilder;
3076            buf.setLength(0);
3077            buf.append("Start proc ");
3078            buf.append(app.processName);
3079            if (!isActivityProcess) {
3080                buf.append(" [");
3081                buf.append(entryPoint);
3082                buf.append("]");
3083            }
3084            buf.append(" for ");
3085            buf.append(hostingType);
3086            if (hostingNameStr != null) {
3087                buf.append(" ");
3088                buf.append(hostingNameStr);
3089            }
3090            buf.append(": pid=");
3091            buf.append(startResult.pid);
3092            buf.append(" uid=");
3093            buf.append(uid);
3094            buf.append(" gids={");
3095            if (gids != null) {
3096                for (int gi=0; gi<gids.length; gi++) {
3097                    if (gi != 0) buf.append(", ");
3098                    buf.append(gids[gi]);
3099
3100                }
3101            }
3102            buf.append("}");
3103            if (requiredAbi != null) {
3104                buf.append(" abi=");
3105                buf.append(requiredAbi);
3106            }
3107            Slog.i(TAG, buf.toString());
3108            app.setPid(startResult.pid);
3109            app.usingWrapper = startResult.usingWrapper;
3110            app.removed = false;
3111            app.killedByAm = false;
3112            synchronized (mPidsSelfLocked) {
3113                this.mPidsSelfLocked.put(startResult.pid, app);
3114                if (isActivityProcess) {
3115                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3116                    msg.obj = app;
3117                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3118                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3119                }
3120            }
3121        } catch (RuntimeException e) {
3122            // XXX do better error recovery.
3123            app.setPid(0);
3124            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3125            if (app.isolated) {
3126                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3127            }
3128            Slog.e(TAG, "Failure starting process " + app.processName, e);
3129        }
3130    }
3131
3132    void updateUsageStats(ActivityRecord component, boolean resumed) {
3133        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3134        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3135        if (resumed) {
3136            if (mUsageStatsService != null) {
3137                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3138                        System.currentTimeMillis(),
3139                        UsageStats.Event.MOVE_TO_FOREGROUND);
3140            }
3141            synchronized (stats) {
3142                stats.noteActivityResumedLocked(component.app.uid);
3143            }
3144        } else {
3145            if (mUsageStatsService != null) {
3146                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3147                        System.currentTimeMillis(),
3148                        UsageStats.Event.MOVE_TO_BACKGROUND);
3149            }
3150            synchronized (stats) {
3151                stats.noteActivityPausedLocked(component.app.uid);
3152            }
3153        }
3154    }
3155
3156    Intent getHomeIntent() {
3157        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3158        intent.setComponent(mTopComponent);
3159        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3160            intent.addCategory(Intent.CATEGORY_HOME);
3161        }
3162        return intent;
3163    }
3164
3165    boolean startHomeActivityLocked(int userId) {
3166        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3167                && mTopAction == null) {
3168            // We are running in factory test mode, but unable to find
3169            // the factory test app, so just sit around displaying the
3170            // error message and don't try to start anything.
3171            return false;
3172        }
3173        Intent intent = getHomeIntent();
3174        ActivityInfo aInfo =
3175            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3176        if (aInfo != null) {
3177            intent.setComponent(new ComponentName(
3178                    aInfo.applicationInfo.packageName, aInfo.name));
3179            // Don't do this if the home app is currently being
3180            // instrumented.
3181            aInfo = new ActivityInfo(aInfo);
3182            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3183            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3184                    aInfo.applicationInfo.uid, true);
3185            if (app == null || app.instrumentationClass == null) {
3186                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3187                mStackSupervisor.startHomeActivity(intent, aInfo);
3188            }
3189        }
3190
3191        return true;
3192    }
3193
3194    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3195        ActivityInfo ai = null;
3196        ComponentName comp = intent.getComponent();
3197        try {
3198            if (comp != null) {
3199                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3200            } else {
3201                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3202                        intent,
3203                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3204                            flags, userId);
3205
3206                if (info != null) {
3207                    ai = info.activityInfo;
3208                }
3209            }
3210        } catch (RemoteException e) {
3211            // ignore
3212        }
3213
3214        return ai;
3215    }
3216
3217    /**
3218     * Starts the "new version setup screen" if appropriate.
3219     */
3220    void startSetupActivityLocked() {
3221        // Only do this once per boot.
3222        if (mCheckedForSetup) {
3223            return;
3224        }
3225
3226        // We will show this screen if the current one is a different
3227        // version than the last one shown, and we are not running in
3228        // low-level factory test mode.
3229        final ContentResolver resolver = mContext.getContentResolver();
3230        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3231                Settings.Global.getInt(resolver,
3232                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3233            mCheckedForSetup = true;
3234
3235            // See if we should be showing the platform update setup UI.
3236            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3237            List<ResolveInfo> ris = mContext.getPackageManager()
3238                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3239
3240            // We don't allow third party apps to replace this.
3241            ResolveInfo ri = null;
3242            for (int i=0; ris != null && i<ris.size(); i++) {
3243                if ((ris.get(i).activityInfo.applicationInfo.flags
3244                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3245                    ri = ris.get(i);
3246                    break;
3247                }
3248            }
3249
3250            if (ri != null) {
3251                String vers = ri.activityInfo.metaData != null
3252                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3253                        : null;
3254                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3255                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3256                            Intent.METADATA_SETUP_VERSION);
3257                }
3258                String lastVers = Settings.Secure.getString(
3259                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3260                if (vers != null && !vers.equals(lastVers)) {
3261                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3262                    intent.setComponent(new ComponentName(
3263                            ri.activityInfo.packageName, ri.activityInfo.name));
3264                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3265                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3266                }
3267            }
3268        }
3269    }
3270
3271    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3272        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3273    }
3274
3275    void enforceNotIsolatedCaller(String caller) {
3276        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3277            throw new SecurityException("Isolated process not allowed to call " + caller);
3278        }
3279    }
3280
3281    @Override
3282    public int getFrontActivityScreenCompatMode() {
3283        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3284        synchronized (this) {
3285            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3286        }
3287    }
3288
3289    @Override
3290    public void setFrontActivityScreenCompatMode(int mode) {
3291        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3292                "setFrontActivityScreenCompatMode");
3293        synchronized (this) {
3294            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3295        }
3296    }
3297
3298    @Override
3299    public int getPackageScreenCompatMode(String packageName) {
3300        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3301        synchronized (this) {
3302            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3303        }
3304    }
3305
3306    @Override
3307    public void setPackageScreenCompatMode(String packageName, int mode) {
3308        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3309                "setPackageScreenCompatMode");
3310        synchronized (this) {
3311            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3312        }
3313    }
3314
3315    @Override
3316    public boolean getPackageAskScreenCompat(String packageName) {
3317        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3318        synchronized (this) {
3319            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3320        }
3321    }
3322
3323    @Override
3324    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3325        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3326                "setPackageAskScreenCompat");
3327        synchronized (this) {
3328            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3329        }
3330    }
3331
3332    private void dispatchProcessesChanged() {
3333        int N;
3334        synchronized (this) {
3335            N = mPendingProcessChanges.size();
3336            if (mActiveProcessChanges.length < N) {
3337                mActiveProcessChanges = new ProcessChangeItem[N];
3338            }
3339            mPendingProcessChanges.toArray(mActiveProcessChanges);
3340            mAvailProcessChanges.addAll(mPendingProcessChanges);
3341            mPendingProcessChanges.clear();
3342            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3343        }
3344
3345        int i = mProcessObservers.beginBroadcast();
3346        while (i > 0) {
3347            i--;
3348            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3349            if (observer != null) {
3350                try {
3351                    for (int j=0; j<N; j++) {
3352                        ProcessChangeItem item = mActiveProcessChanges[j];
3353                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3354                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3355                                    + item.pid + " uid=" + item.uid + ": "
3356                                    + item.foregroundActivities);
3357                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3358                                    item.foregroundActivities);
3359                        }
3360                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3361                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3362                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3363                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3364                        }
3365                    }
3366                } catch (RemoteException e) {
3367                }
3368            }
3369        }
3370        mProcessObservers.finishBroadcast();
3371    }
3372
3373    private void dispatchProcessDied(int pid, int uid) {
3374        int i = mProcessObservers.beginBroadcast();
3375        while (i > 0) {
3376            i--;
3377            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3378            if (observer != null) {
3379                try {
3380                    observer.onProcessDied(pid, uid);
3381                } catch (RemoteException e) {
3382                }
3383            }
3384        }
3385        mProcessObservers.finishBroadcast();
3386    }
3387
3388    @Override
3389    public final int startActivity(IApplicationThread caller, String callingPackage,
3390            Intent intent, String resolvedType, IBinder resultTo,
3391            String resultWho, int requestCode, int startFlags,
3392            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3393        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3394                resultWho, requestCode,
3395                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3396    }
3397
3398    @Override
3399    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3400            Intent intent, String resolvedType, IBinder resultTo,
3401            String resultWho, int requestCode, int startFlags,
3402            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3403        enforceNotIsolatedCaller("startActivity");
3404        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3405                false, ALLOW_FULL_ONLY, "startActivity", null);
3406        // TODO: Switch to user app stacks here.
3407        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3408                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3409                null, null, options, userId, null);
3410    }
3411
3412    @Override
3413    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3414            Intent intent, String resolvedType, IBinder resultTo,
3415            String resultWho, int requestCode, int startFlags, String profileFile,
3416            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3417        enforceNotIsolatedCaller("startActivityAndWait");
3418        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3419                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3420        WaitResult res = new WaitResult();
3421        // TODO: Switch to user app stacks here.
3422        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3423                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3424                res, null, options, userId, null);
3425        return res;
3426    }
3427
3428    @Override
3429    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3430            Intent intent, String resolvedType, IBinder resultTo,
3431            String resultWho, int requestCode, int startFlags, Configuration config,
3432            Bundle options, int userId) {
3433        enforceNotIsolatedCaller("startActivityWithConfig");
3434        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3435                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3436        // TODO: Switch to user app stacks here.
3437        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3438                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3439                null, null, null, config, options, userId, null);
3440        return ret;
3441    }
3442
3443    @Override
3444    public int startActivityIntentSender(IApplicationThread caller,
3445            IntentSender intent, Intent fillInIntent, String resolvedType,
3446            IBinder resultTo, String resultWho, int requestCode,
3447            int flagsMask, int flagsValues, Bundle options) {
3448        enforceNotIsolatedCaller("startActivityIntentSender");
3449        // Refuse possible leaked file descriptors
3450        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3451            throw new IllegalArgumentException("File descriptors passed in Intent");
3452        }
3453
3454        IIntentSender sender = intent.getTarget();
3455        if (!(sender instanceof PendingIntentRecord)) {
3456            throw new IllegalArgumentException("Bad PendingIntent object");
3457        }
3458
3459        PendingIntentRecord pir = (PendingIntentRecord)sender;
3460
3461        synchronized (this) {
3462            // If this is coming from the currently resumed activity, it is
3463            // effectively saying that app switches are allowed at this point.
3464            final ActivityStack stack = getFocusedStack();
3465            if (stack.mResumedActivity != null &&
3466                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3467                mAppSwitchesAllowedTime = 0;
3468            }
3469        }
3470        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3471                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3472        return ret;
3473    }
3474
3475    @Override
3476    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3477            Intent intent, String resolvedType, IVoiceInteractionSession session,
3478            IVoiceInteractor interactor, int startFlags, String profileFile,
3479            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3480        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3481                != PackageManager.PERMISSION_GRANTED) {
3482            String msg = "Permission Denial: startVoiceActivity() from pid="
3483                    + Binder.getCallingPid()
3484                    + ", uid=" + Binder.getCallingUid()
3485                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3486            Slog.w(TAG, msg);
3487            throw new SecurityException(msg);
3488        }
3489        if (session == null || interactor == null) {
3490            throw new NullPointerException("null session or interactor");
3491        }
3492        userId = handleIncomingUser(callingPid, callingUid, userId,
3493                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3494        // TODO: Switch to user app stacks here.
3495        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3496                resolvedType, session, interactor, null, null, 0, startFlags,
3497                profileFile, profileFd, null, null, options, userId, null);
3498    }
3499
3500    @Override
3501    public boolean startNextMatchingActivity(IBinder callingActivity,
3502            Intent intent, Bundle options) {
3503        // Refuse possible leaked file descriptors
3504        if (intent != null && intent.hasFileDescriptors() == true) {
3505            throw new IllegalArgumentException("File descriptors passed in Intent");
3506        }
3507
3508        synchronized (this) {
3509            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3510            if (r == null) {
3511                ActivityOptions.abort(options);
3512                return false;
3513            }
3514            if (r.app == null || r.app.thread == null) {
3515                // The caller is not running...  d'oh!
3516                ActivityOptions.abort(options);
3517                return false;
3518            }
3519            intent = new Intent(intent);
3520            // The caller is not allowed to change the data.
3521            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3522            // And we are resetting to find the next component...
3523            intent.setComponent(null);
3524
3525            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3526
3527            ActivityInfo aInfo = null;
3528            try {
3529                List<ResolveInfo> resolves =
3530                    AppGlobals.getPackageManager().queryIntentActivities(
3531                            intent, r.resolvedType,
3532                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3533                            UserHandle.getCallingUserId());
3534
3535                // Look for the original activity in the list...
3536                final int N = resolves != null ? resolves.size() : 0;
3537                for (int i=0; i<N; i++) {
3538                    ResolveInfo rInfo = resolves.get(i);
3539                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3540                            && rInfo.activityInfo.name.equals(r.info.name)) {
3541                        // We found the current one...  the next matching is
3542                        // after it.
3543                        i++;
3544                        if (i<N) {
3545                            aInfo = resolves.get(i).activityInfo;
3546                        }
3547                        if (debug) {
3548                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3549                                    + "/" + r.info.name);
3550                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3551                                    + "/" + aInfo.name);
3552                        }
3553                        break;
3554                    }
3555                }
3556            } catch (RemoteException e) {
3557            }
3558
3559            if (aInfo == null) {
3560                // Nobody who is next!
3561                ActivityOptions.abort(options);
3562                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3563                return false;
3564            }
3565
3566            intent.setComponent(new ComponentName(
3567                    aInfo.applicationInfo.packageName, aInfo.name));
3568            intent.setFlags(intent.getFlags()&~(
3569                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3570                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3571                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3572                    Intent.FLAG_ACTIVITY_NEW_TASK));
3573
3574            // Okay now we need to start the new activity, replacing the
3575            // currently running activity.  This is a little tricky because
3576            // we want to start the new one as if the current one is finished,
3577            // but not finish the current one first so that there is no flicker.
3578            // And thus...
3579            final boolean wasFinishing = r.finishing;
3580            r.finishing = true;
3581
3582            // Propagate reply information over to the new activity.
3583            final ActivityRecord resultTo = r.resultTo;
3584            final String resultWho = r.resultWho;
3585            final int requestCode = r.requestCode;
3586            r.resultTo = null;
3587            if (resultTo != null) {
3588                resultTo.removeResultsLocked(r, resultWho, requestCode);
3589            }
3590
3591            final long origId = Binder.clearCallingIdentity();
3592            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3593                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3594                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3595                    options, false, null, null);
3596            Binder.restoreCallingIdentity(origId);
3597
3598            r.finishing = wasFinishing;
3599            if (res != ActivityManager.START_SUCCESS) {
3600                return false;
3601            }
3602            return true;
3603        }
3604    }
3605
3606    @Override
3607    public final int startActivityFromRecents(int taskId, Bundle options) {
3608        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3609            String msg = "Permission Denial: startActivityFromRecents called without " +
3610                    START_TASKS_FROM_RECENTS;
3611            Slog.w(TAG, msg);
3612            throw new SecurityException(msg);
3613        }
3614        final int callingUid;
3615        final String callingPackage;
3616        final Intent intent;
3617        final int userId;
3618        synchronized (this) {
3619            final TaskRecord task = recentTaskForIdLocked(taskId);
3620            if (task == null) {
3621                throw new ActivityNotFoundException("Task " + taskId + " not found.");
3622            }
3623            callingUid = task.mCallingUid;
3624            callingPackage = task.mCallingPackage;
3625            intent = task.intent;
3626            userId = task.userId;
3627        }
3628        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3629                options, userId, null);
3630    }
3631
3632    final int startActivityInPackage(int uid, String callingPackage,
3633            Intent intent, String resolvedType, IBinder resultTo,
3634            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3635                    IActivityContainer container) {
3636
3637        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3638                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3639
3640        // TODO: Switch to user app stacks here.
3641        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3642                null, null, resultTo, resultWho, requestCode, startFlags,
3643                null, null, null, null, options, userId, container);
3644        return ret;
3645    }
3646
3647    @Override
3648    public final int startActivities(IApplicationThread caller, String callingPackage,
3649            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3650            int userId) {
3651        enforceNotIsolatedCaller("startActivities");
3652        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3653                false, ALLOW_FULL_ONLY, "startActivity", null);
3654        // TODO: Switch to user app stacks here.
3655        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3656                resolvedTypes, resultTo, options, userId);
3657        return ret;
3658    }
3659
3660    final int startActivitiesInPackage(int uid, String callingPackage,
3661            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3662            Bundle options, int userId) {
3663
3664        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3665                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3666        // TODO: Switch to user app stacks here.
3667        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3668                resultTo, options, userId);
3669        return ret;
3670    }
3671
3672    //explicitly remove thd old information in mRecentTasks when removing existing user.
3673    private void removeRecentTasksForUser(int userId) {
3674        if(userId <= 0) {
3675            Slog.i(TAG, "Can't remove recent task on user " + userId);
3676            return;
3677        }
3678
3679        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3680            TaskRecord tr = mRecentTasks.get(i);
3681            if (tr.userId == userId) {
3682                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3683                        + " when finishing user" + userId);
3684                tr.disposeThumbnail();
3685                mRecentTasks.remove(i);
3686            }
3687        }
3688
3689        // Remove tasks from persistent storage.
3690        mTaskPersister.wakeup(null, true);
3691    }
3692
3693    final void addRecentTaskLocked(TaskRecord task) {
3694        int N = mRecentTasks.size();
3695        // Quick case: check if the top-most recent task is the same.
3696        if (N > 0 && mRecentTasks.get(0) == task) {
3697            return;
3698        }
3699        // Another quick case: never add voice sessions.
3700        if (task.voiceSession != null) {
3701            return;
3702        }
3703        // Remove any existing entries that are the same kind of task.
3704        final Intent intent = task.intent;
3705        final boolean document = intent != null && intent.isDocument();
3706        final ComponentName comp = intent.getComponent();
3707
3708        int maxRecents = task.maxRecents - 1;
3709        for (int i=0; i<N; i++) {
3710            final TaskRecord tr = mRecentTasks.get(i);
3711            if (task != tr) {
3712                if (task.userId != tr.userId) {
3713                    continue;
3714                }
3715                if (i > MAX_RECENT_BITMAPS) {
3716                    tr.freeLastThumbnail();
3717                }
3718                final Intent trIntent = tr.intent;
3719                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3720                    (intent == null || !intent.filterEquals(trIntent))) {
3721                    continue;
3722                }
3723                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3724                if (document && trIsDocument) {
3725                    // These are the same document activity (not necessarily the same doc).
3726                    if (maxRecents > 0) {
3727                        --maxRecents;
3728                        continue;
3729                    }
3730                    // Hit the maximum number of documents for this task. Fall through
3731                    // and remove this document from recents.
3732                } else if (document || trIsDocument) {
3733                    // Only one of these is a document. Not the droid we're looking for.
3734                    continue;
3735                }
3736            }
3737
3738            // Either task and tr are the same or, their affinities match or their intents match
3739            // and neither of them is a document, or they are documents using the same activity
3740            // and their maxRecents has been reached.
3741            tr.disposeThumbnail();
3742            mRecentTasks.remove(i);
3743            if (task != tr) {
3744                tr.closeRecentsChain();
3745            }
3746            i--;
3747            N--;
3748            if (task.intent == null) {
3749                // If the new recent task we are adding is not fully
3750                // specified, then replace it with the existing recent task.
3751                task = tr;
3752            }
3753            notifyTaskPersisterLocked(tr, false);
3754        }
3755        if (N >= MAX_RECENT_TASKS) {
3756            final TaskRecord tr = mRecentTasks.remove(N - 1);
3757            tr.disposeThumbnail();
3758            tr.closeRecentsChain();
3759        }
3760        mRecentTasks.add(0, task);
3761    }
3762
3763    @Override
3764    public void reportActivityFullyDrawn(IBinder token) {
3765        synchronized (this) {
3766            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3767            if (r == null) {
3768                return;
3769            }
3770            r.reportFullyDrawnLocked();
3771        }
3772    }
3773
3774    @Override
3775    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3776        synchronized (this) {
3777            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3778            if (r == null) {
3779                return;
3780            }
3781            final long origId = Binder.clearCallingIdentity();
3782            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3783            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3784                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3785            if (config != null) {
3786                r.frozenBeforeDestroy = true;
3787                if (!updateConfigurationLocked(config, r, false, false)) {
3788                    mStackSupervisor.resumeTopActivitiesLocked();
3789                }
3790            }
3791            Binder.restoreCallingIdentity(origId);
3792        }
3793    }
3794
3795    @Override
3796    public int getRequestedOrientation(IBinder token) {
3797        synchronized (this) {
3798            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3799            if (r == null) {
3800                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3801            }
3802            return mWindowManager.getAppOrientation(r.appToken);
3803        }
3804    }
3805
3806    /**
3807     * This is the internal entry point for handling Activity.finish().
3808     *
3809     * @param token The Binder token referencing the Activity we want to finish.
3810     * @param resultCode Result code, if any, from this Activity.
3811     * @param resultData Result data (Intent), if any, from this Activity.
3812     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3813     *            the root Activity in the task.
3814     *
3815     * @return Returns true if the activity successfully finished, or false if it is still running.
3816     */
3817    @Override
3818    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3819            boolean finishTask) {
3820        // Refuse possible leaked file descriptors
3821        if (resultData != null && resultData.hasFileDescriptors() == true) {
3822            throw new IllegalArgumentException("File descriptors passed in Intent");
3823        }
3824
3825        synchronized(this) {
3826            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3827            if (r == null) {
3828                return true;
3829            }
3830            // Keep track of the root activity of the task before we finish it
3831            TaskRecord tr = r.task;
3832            ActivityRecord rootR = tr.getRootActivity();
3833            // Do not allow task to finish in Lock Task mode.
3834            if (tr == mStackSupervisor.mLockTaskModeTask) {
3835                if (rootR == r) {
3836                    mStackSupervisor.showLockTaskToast();
3837                    return false;
3838                }
3839            }
3840            if (mController != null) {
3841                // Find the first activity that is not finishing.
3842                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3843                if (next != null) {
3844                    // ask watcher if this is allowed
3845                    boolean resumeOK = true;
3846                    try {
3847                        resumeOK = mController.activityResuming(next.packageName);
3848                    } catch (RemoteException e) {
3849                        mController = null;
3850                        Watchdog.getInstance().setActivityController(null);
3851                    }
3852
3853                    if (!resumeOK) {
3854                        return false;
3855                    }
3856                }
3857            }
3858            final long origId = Binder.clearCallingIdentity();
3859            try {
3860                boolean res;
3861                if (finishTask && r == rootR) {
3862                    // If requested, remove the task that is associated to this activity only if it
3863                    // was the root activity in the task.  The result code and data is ignored because
3864                    // we don't support returning them across task boundaries.
3865                    res = removeTaskByIdLocked(tr.taskId, 0);
3866                } else {
3867                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3868                            resultData, "app-request", true);
3869                }
3870                return res;
3871            } finally {
3872                Binder.restoreCallingIdentity(origId);
3873            }
3874        }
3875    }
3876
3877    @Override
3878    public final void finishHeavyWeightApp() {
3879        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3880                != PackageManager.PERMISSION_GRANTED) {
3881            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3882                    + Binder.getCallingPid()
3883                    + ", uid=" + Binder.getCallingUid()
3884                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3885            Slog.w(TAG, msg);
3886            throw new SecurityException(msg);
3887        }
3888
3889        synchronized(this) {
3890            if (mHeavyWeightProcess == null) {
3891                return;
3892            }
3893
3894            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3895                    mHeavyWeightProcess.activities);
3896            for (int i=0; i<activities.size(); i++) {
3897                ActivityRecord r = activities.get(i);
3898                if (!r.finishing) {
3899                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3900                            null, "finish-heavy", true);
3901                }
3902            }
3903
3904            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3905                    mHeavyWeightProcess.userId, 0));
3906            mHeavyWeightProcess = null;
3907        }
3908    }
3909
3910    @Override
3911    public void crashApplication(int uid, int initialPid, String packageName,
3912            String message) {
3913        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3914                != PackageManager.PERMISSION_GRANTED) {
3915            String msg = "Permission Denial: crashApplication() from pid="
3916                    + Binder.getCallingPid()
3917                    + ", uid=" + Binder.getCallingUid()
3918                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3919            Slog.w(TAG, msg);
3920            throw new SecurityException(msg);
3921        }
3922
3923        synchronized(this) {
3924            ProcessRecord proc = null;
3925
3926            // Figure out which process to kill.  We don't trust that initialPid
3927            // still has any relation to current pids, so must scan through the
3928            // list.
3929            synchronized (mPidsSelfLocked) {
3930                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3931                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3932                    if (p.uid != uid) {
3933                        continue;
3934                    }
3935                    if (p.pid == initialPid) {
3936                        proc = p;
3937                        break;
3938                    }
3939                    if (p.pkgList.containsKey(packageName)) {
3940                        proc = p;
3941                    }
3942                }
3943            }
3944
3945            if (proc == null) {
3946                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3947                        + " initialPid=" + initialPid
3948                        + " packageName=" + packageName);
3949                return;
3950            }
3951
3952            if (proc.thread != null) {
3953                if (proc.pid == Process.myPid()) {
3954                    Log.w(TAG, "crashApplication: trying to crash self!");
3955                    return;
3956                }
3957                long ident = Binder.clearCallingIdentity();
3958                try {
3959                    proc.thread.scheduleCrash(message);
3960                } catch (RemoteException e) {
3961                }
3962                Binder.restoreCallingIdentity(ident);
3963            }
3964        }
3965    }
3966
3967    @Override
3968    public final void finishSubActivity(IBinder token, String resultWho,
3969            int requestCode) {
3970        synchronized(this) {
3971            final long origId = Binder.clearCallingIdentity();
3972            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3973            if (r != null) {
3974                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3975            }
3976            Binder.restoreCallingIdentity(origId);
3977        }
3978    }
3979
3980    @Override
3981    public boolean finishActivityAffinity(IBinder token) {
3982        synchronized(this) {
3983            final long origId = Binder.clearCallingIdentity();
3984            try {
3985                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3986
3987                ActivityRecord rootR = r.task.getRootActivity();
3988                // Do not allow task to finish in Lock Task mode.
3989                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3990                    if (rootR == r) {
3991                        mStackSupervisor.showLockTaskToast();
3992                        return false;
3993                    }
3994                }
3995                boolean res = false;
3996                if (r != null) {
3997                    res = r.task.stack.finishActivityAffinityLocked(r);
3998                }
3999                return res;
4000            } finally {
4001                Binder.restoreCallingIdentity(origId);
4002            }
4003        }
4004    }
4005
4006    @Override
4007    public void finishVoiceTask(IVoiceInteractionSession session) {
4008        synchronized(this) {
4009            final long origId = Binder.clearCallingIdentity();
4010            try {
4011                mStackSupervisor.finishVoiceTask(session);
4012            } finally {
4013                Binder.restoreCallingIdentity(origId);
4014            }
4015        }
4016
4017    }
4018
4019    @Override
4020    public boolean willActivityBeVisible(IBinder token) {
4021        synchronized(this) {
4022            ActivityStack stack = ActivityRecord.getStackLocked(token);
4023            if (stack != null) {
4024                return stack.willActivityBeVisibleLocked(token);
4025            }
4026            return false;
4027        }
4028    }
4029
4030    @Override
4031    public void overridePendingTransition(IBinder token, String packageName,
4032            int enterAnim, int exitAnim) {
4033        synchronized(this) {
4034            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4035            if (self == null) {
4036                return;
4037            }
4038
4039            final long origId = Binder.clearCallingIdentity();
4040
4041            if (self.state == ActivityState.RESUMED
4042                    || self.state == ActivityState.PAUSING) {
4043                mWindowManager.overridePendingAppTransition(packageName,
4044                        enterAnim, exitAnim, null);
4045            }
4046
4047            Binder.restoreCallingIdentity(origId);
4048        }
4049    }
4050
4051    /**
4052     * Main function for removing an existing process from the activity manager
4053     * as a result of that process going away.  Clears out all connections
4054     * to the process.
4055     */
4056    private final void handleAppDiedLocked(ProcessRecord app,
4057            boolean restarting, boolean allowRestart) {
4058        int pid = app.pid;
4059        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4060        if (!restarting) {
4061            removeLruProcessLocked(app);
4062            if (pid > 0) {
4063                ProcessList.remove(pid);
4064            }
4065        }
4066
4067        if (mProfileProc == app) {
4068            clearProfilerLocked();
4069        }
4070
4071        // Remove this application's activities from active lists.
4072        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4073
4074        app.activities.clear();
4075
4076        if (app.instrumentationClass != null) {
4077            Slog.w(TAG, "Crash of app " + app.processName
4078                  + " running instrumentation " + app.instrumentationClass);
4079            Bundle info = new Bundle();
4080            info.putString("shortMsg", "Process crashed.");
4081            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4082        }
4083
4084        if (!restarting) {
4085            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4086                // If there was nothing to resume, and we are not already
4087                // restarting this process, but there is a visible activity that
4088                // is hosted by the process...  then make sure all visible
4089                // activities are running, taking care of restarting this
4090                // process.
4091                if (hasVisibleActivities) {
4092                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4093                }
4094            }
4095        }
4096    }
4097
4098    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4099        IBinder threadBinder = thread.asBinder();
4100        // Find the application record.
4101        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4102            ProcessRecord rec = mLruProcesses.get(i);
4103            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4104                return i;
4105            }
4106        }
4107        return -1;
4108    }
4109
4110    final ProcessRecord getRecordForAppLocked(
4111            IApplicationThread thread) {
4112        if (thread == null) {
4113            return null;
4114        }
4115
4116        int appIndex = getLRURecordIndexForAppLocked(thread);
4117        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4118    }
4119
4120    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4121        // If there are no longer any background processes running,
4122        // and the app that died was not running instrumentation,
4123        // then tell everyone we are now low on memory.
4124        boolean haveBg = false;
4125        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4126            ProcessRecord rec = mLruProcesses.get(i);
4127            if (rec.thread != null
4128                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4129                haveBg = true;
4130                break;
4131            }
4132        }
4133
4134        if (!haveBg) {
4135            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4136            if (doReport) {
4137                long now = SystemClock.uptimeMillis();
4138                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4139                    doReport = false;
4140                } else {
4141                    mLastMemUsageReportTime = now;
4142                }
4143            }
4144            final ArrayList<ProcessMemInfo> memInfos
4145                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4146            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4147            long now = SystemClock.uptimeMillis();
4148            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4149                ProcessRecord rec = mLruProcesses.get(i);
4150                if (rec == dyingProc || rec.thread == null) {
4151                    continue;
4152                }
4153                if (doReport) {
4154                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4155                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4156                }
4157                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4158                    // The low memory report is overriding any current
4159                    // state for a GC request.  Make sure to do
4160                    // heavy/important/visible/foreground processes first.
4161                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4162                        rec.lastRequestedGc = 0;
4163                    } else {
4164                        rec.lastRequestedGc = rec.lastLowMemory;
4165                    }
4166                    rec.reportLowMemory = true;
4167                    rec.lastLowMemory = now;
4168                    mProcessesToGc.remove(rec);
4169                    addProcessToGcListLocked(rec);
4170                }
4171            }
4172            if (doReport) {
4173                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4174                mHandler.sendMessage(msg);
4175            }
4176            scheduleAppGcsLocked();
4177        }
4178    }
4179
4180    final void appDiedLocked(ProcessRecord app, int pid,
4181            IApplicationThread thread) {
4182
4183        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4184        synchronized (stats) {
4185            stats.noteProcessDiedLocked(app.info.uid, pid);
4186        }
4187
4188        Process.killProcessGroup(app.info.uid, pid);
4189
4190        // Clean up already done if the process has been re-started.
4191        if (app.pid == pid && app.thread != null &&
4192                app.thread.asBinder() == thread.asBinder()) {
4193            boolean doLowMem = app.instrumentationClass == null;
4194            boolean doOomAdj = doLowMem;
4195            if (!app.killedByAm) {
4196                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4197                        + ") has died.");
4198                mAllowLowerMemLevel = true;
4199            } else {
4200                // Note that we always want to do oom adj to update our state with the
4201                // new number of procs.
4202                mAllowLowerMemLevel = false;
4203                doLowMem = false;
4204            }
4205            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4206            if (DEBUG_CLEANUP) Slog.v(
4207                TAG, "Dying app: " + app + ", pid: " + pid
4208                + ", thread: " + thread.asBinder());
4209            handleAppDiedLocked(app, false, true);
4210
4211            if (doOomAdj) {
4212                updateOomAdjLocked();
4213            }
4214            if (doLowMem) {
4215                doLowMemReportIfNeededLocked(app);
4216            }
4217        } else if (app.pid != pid) {
4218            // A new process has already been started.
4219            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4220                    + ") has died and restarted (pid " + app.pid + ").");
4221            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4222        } else if (DEBUG_PROCESSES) {
4223            Slog.d(TAG, "Received spurious death notification for thread "
4224                    + thread.asBinder());
4225        }
4226    }
4227
4228    /**
4229     * If a stack trace dump file is configured, dump process stack traces.
4230     * @param clearTraces causes the dump file to be erased prior to the new
4231     *    traces being written, if true; when false, the new traces will be
4232     *    appended to any existing file content.
4233     * @param firstPids of dalvik VM processes to dump stack traces for first
4234     * @param lastPids of dalvik VM processes to dump stack traces for last
4235     * @param nativeProcs optional list of native process names to dump stack crawls
4236     * @return file containing stack traces, or null if no dump file is configured
4237     */
4238    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4239            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4240        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4241        if (tracesPath == null || tracesPath.length() == 0) {
4242            return null;
4243        }
4244
4245        File tracesFile = new File(tracesPath);
4246        try {
4247            File tracesDir = tracesFile.getParentFile();
4248            if (!tracesDir.exists()) {
4249                tracesFile.mkdirs();
4250                if (!SELinux.restorecon(tracesDir)) {
4251                    return null;
4252                }
4253            }
4254            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4255
4256            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4257            tracesFile.createNewFile();
4258            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4259        } catch (IOException e) {
4260            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4261            return null;
4262        }
4263
4264        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4265        return tracesFile;
4266    }
4267
4268    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4269            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4270        // Use a FileObserver to detect when traces finish writing.
4271        // The order of traces is considered important to maintain for legibility.
4272        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4273            @Override
4274            public synchronized void onEvent(int event, String path) { notify(); }
4275        };
4276
4277        try {
4278            observer.startWatching();
4279
4280            // First collect all of the stacks of the most important pids.
4281            if (firstPids != null) {
4282                try {
4283                    int num = firstPids.size();
4284                    for (int i = 0; i < num; i++) {
4285                        synchronized (observer) {
4286                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4287                            observer.wait(200);  // Wait for write-close, give up after 200msec
4288                        }
4289                    }
4290                } catch (InterruptedException e) {
4291                    Log.wtf(TAG, e);
4292                }
4293            }
4294
4295            // Next collect the stacks of the native pids
4296            if (nativeProcs != null) {
4297                int[] pids = Process.getPidsForCommands(nativeProcs);
4298                if (pids != null) {
4299                    for (int pid : pids) {
4300                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4301                    }
4302                }
4303            }
4304
4305            // Lastly, measure CPU usage.
4306            if (processCpuTracker != null) {
4307                processCpuTracker.init();
4308                System.gc();
4309                processCpuTracker.update();
4310                try {
4311                    synchronized (processCpuTracker) {
4312                        processCpuTracker.wait(500); // measure over 1/2 second.
4313                    }
4314                } catch (InterruptedException e) {
4315                }
4316                processCpuTracker.update();
4317
4318                // We'll take the stack crawls of just the top apps using CPU.
4319                final int N = processCpuTracker.countWorkingStats();
4320                int numProcs = 0;
4321                for (int i=0; i<N && numProcs<5; i++) {
4322                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4323                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4324                        numProcs++;
4325                        try {
4326                            synchronized (observer) {
4327                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4328                                observer.wait(200);  // Wait for write-close, give up after 200msec
4329                            }
4330                        } catch (InterruptedException e) {
4331                            Log.wtf(TAG, e);
4332                        }
4333
4334                    }
4335                }
4336            }
4337        } finally {
4338            observer.stopWatching();
4339        }
4340    }
4341
4342    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4343        if (true || IS_USER_BUILD) {
4344            return;
4345        }
4346        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4347        if (tracesPath == null || tracesPath.length() == 0) {
4348            return;
4349        }
4350
4351        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4352        StrictMode.allowThreadDiskWrites();
4353        try {
4354            final File tracesFile = new File(tracesPath);
4355            final File tracesDir = tracesFile.getParentFile();
4356            final File tracesTmp = new File(tracesDir, "__tmp__");
4357            try {
4358                if (!tracesDir.exists()) {
4359                    tracesFile.mkdirs();
4360                    if (!SELinux.restorecon(tracesDir.getPath())) {
4361                        return;
4362                    }
4363                }
4364                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4365
4366                if (tracesFile.exists()) {
4367                    tracesTmp.delete();
4368                    tracesFile.renameTo(tracesTmp);
4369                }
4370                StringBuilder sb = new StringBuilder();
4371                Time tobj = new Time();
4372                tobj.set(System.currentTimeMillis());
4373                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4374                sb.append(": ");
4375                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4376                sb.append(" since ");
4377                sb.append(msg);
4378                FileOutputStream fos = new FileOutputStream(tracesFile);
4379                fos.write(sb.toString().getBytes());
4380                if (app == null) {
4381                    fos.write("\n*** No application process!".getBytes());
4382                }
4383                fos.close();
4384                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4385            } catch (IOException e) {
4386                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4387                return;
4388            }
4389
4390            if (app != null) {
4391                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4392                firstPids.add(app.pid);
4393                dumpStackTraces(tracesPath, firstPids, null, null, null);
4394            }
4395
4396            File lastTracesFile = null;
4397            File curTracesFile = null;
4398            for (int i=9; i>=0; i--) {
4399                String name = String.format(Locale.US, "slow%02d.txt", i);
4400                curTracesFile = new File(tracesDir, name);
4401                if (curTracesFile.exists()) {
4402                    if (lastTracesFile != null) {
4403                        curTracesFile.renameTo(lastTracesFile);
4404                    } else {
4405                        curTracesFile.delete();
4406                    }
4407                }
4408                lastTracesFile = curTracesFile;
4409            }
4410            tracesFile.renameTo(curTracesFile);
4411            if (tracesTmp.exists()) {
4412                tracesTmp.renameTo(tracesFile);
4413            }
4414        } finally {
4415            StrictMode.setThreadPolicy(oldPolicy);
4416        }
4417    }
4418
4419    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4420            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4421        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4422        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4423
4424        if (mController != null) {
4425            try {
4426                // 0 == continue, -1 = kill process immediately
4427                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4428                if (res < 0 && app.pid != MY_PID) {
4429                    Process.killProcess(app.pid);
4430                    Process.killProcessGroup(app.info.uid, app.pid);
4431                }
4432            } catch (RemoteException e) {
4433                mController = null;
4434                Watchdog.getInstance().setActivityController(null);
4435            }
4436        }
4437
4438        long anrTime = SystemClock.uptimeMillis();
4439        if (MONITOR_CPU_USAGE) {
4440            updateCpuStatsNow();
4441        }
4442
4443        synchronized (this) {
4444            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4445            if (mShuttingDown) {
4446                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4447                return;
4448            } else if (app.notResponding) {
4449                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4450                return;
4451            } else if (app.crashing) {
4452                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4453                return;
4454            }
4455
4456            // In case we come through here for the same app before completing
4457            // this one, mark as anring now so we will bail out.
4458            app.notResponding = true;
4459
4460            // Log the ANR to the event log.
4461            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4462                    app.processName, app.info.flags, annotation);
4463
4464            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4465            firstPids.add(app.pid);
4466
4467            int parentPid = app.pid;
4468            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4469            if (parentPid != app.pid) firstPids.add(parentPid);
4470
4471            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4472
4473            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4474                ProcessRecord r = mLruProcesses.get(i);
4475                if (r != null && r.thread != null) {
4476                    int pid = r.pid;
4477                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4478                        if (r.persistent) {
4479                            firstPids.add(pid);
4480                        } else {
4481                            lastPids.put(pid, Boolean.TRUE);
4482                        }
4483                    }
4484                }
4485            }
4486        }
4487
4488        // Log the ANR to the main log.
4489        StringBuilder info = new StringBuilder();
4490        info.setLength(0);
4491        info.append("ANR in ").append(app.processName);
4492        if (activity != null && activity.shortComponentName != null) {
4493            info.append(" (").append(activity.shortComponentName).append(")");
4494        }
4495        info.append("\n");
4496        info.append("PID: ").append(app.pid).append("\n");
4497        if (annotation != null) {
4498            info.append("Reason: ").append(annotation).append("\n");
4499        }
4500        if (parent != null && parent != activity) {
4501            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4502        }
4503
4504        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4505
4506        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4507                NATIVE_STACKS_OF_INTEREST);
4508
4509        String cpuInfo = null;
4510        if (MONITOR_CPU_USAGE) {
4511            updateCpuStatsNow();
4512            synchronized (mProcessCpuThread) {
4513                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4514            }
4515            info.append(processCpuTracker.printCurrentLoad());
4516            info.append(cpuInfo);
4517        }
4518
4519        info.append(processCpuTracker.printCurrentState(anrTime));
4520
4521        Slog.e(TAG, info.toString());
4522        if (tracesFile == null) {
4523            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4524            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4525        }
4526
4527        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4528                cpuInfo, tracesFile, null);
4529
4530        if (mController != null) {
4531            try {
4532                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4533                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4534                if (res != 0) {
4535                    if (res < 0 && app.pid != MY_PID) {
4536                        Process.killProcess(app.pid);
4537                        Process.killProcessGroup(app.info.uid, app.pid);
4538                    } else {
4539                        synchronized (this) {
4540                            mServices.scheduleServiceTimeoutLocked(app);
4541                        }
4542                    }
4543                    return;
4544                }
4545            } catch (RemoteException e) {
4546                mController = null;
4547                Watchdog.getInstance().setActivityController(null);
4548            }
4549        }
4550
4551        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4552        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4553                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4554
4555        synchronized (this) {
4556            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4557                killUnneededProcessLocked(app, "background ANR");
4558                return;
4559            }
4560
4561            // Set the app's notResponding state, and look up the errorReportReceiver
4562            makeAppNotRespondingLocked(app,
4563                    activity != null ? activity.shortComponentName : null,
4564                    annotation != null ? "ANR " + annotation : "ANR",
4565                    info.toString());
4566
4567            // Bring up the infamous App Not Responding dialog
4568            Message msg = Message.obtain();
4569            HashMap<String, Object> map = new HashMap<String, Object>();
4570            msg.what = SHOW_NOT_RESPONDING_MSG;
4571            msg.obj = map;
4572            msg.arg1 = aboveSystem ? 1 : 0;
4573            map.put("app", app);
4574            if (activity != null) {
4575                map.put("activity", activity);
4576            }
4577
4578            mHandler.sendMessage(msg);
4579        }
4580    }
4581
4582    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4583        if (!mLaunchWarningShown) {
4584            mLaunchWarningShown = true;
4585            mHandler.post(new Runnable() {
4586                @Override
4587                public void run() {
4588                    synchronized (ActivityManagerService.this) {
4589                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4590                        d.show();
4591                        mHandler.postDelayed(new Runnable() {
4592                            @Override
4593                            public void run() {
4594                                synchronized (ActivityManagerService.this) {
4595                                    d.dismiss();
4596                                    mLaunchWarningShown = false;
4597                                }
4598                            }
4599                        }, 4000);
4600                    }
4601                }
4602            });
4603        }
4604    }
4605
4606    @Override
4607    public boolean clearApplicationUserData(final String packageName,
4608            final IPackageDataObserver observer, int userId) {
4609        enforceNotIsolatedCaller("clearApplicationUserData");
4610        int uid = Binder.getCallingUid();
4611        int pid = Binder.getCallingPid();
4612        userId = handleIncomingUser(pid, uid,
4613                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4614        long callingId = Binder.clearCallingIdentity();
4615        try {
4616            IPackageManager pm = AppGlobals.getPackageManager();
4617            int pkgUid = -1;
4618            synchronized(this) {
4619                try {
4620                    pkgUid = pm.getPackageUid(packageName, userId);
4621                } catch (RemoteException e) {
4622                }
4623                if (pkgUid == -1) {
4624                    Slog.w(TAG, "Invalid packageName: " + packageName);
4625                    if (observer != null) {
4626                        try {
4627                            observer.onRemoveCompleted(packageName, false);
4628                        } catch (RemoteException e) {
4629                            Slog.i(TAG, "Observer no longer exists.");
4630                        }
4631                    }
4632                    return false;
4633                }
4634                if (uid == pkgUid || checkComponentPermission(
4635                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4636                        pid, uid, -1, true)
4637                        == PackageManager.PERMISSION_GRANTED) {
4638                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4639                } else {
4640                    throw new SecurityException("PID " + pid + " does not have permission "
4641                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4642                                    + " of package " + packageName);
4643                }
4644            }
4645
4646            try {
4647                // Clear application user data
4648                pm.clearApplicationUserData(packageName, observer, userId);
4649
4650                // Remove all permissions granted from/to this package
4651                removeUriPermissionsForPackageLocked(packageName, userId, true);
4652
4653                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4654                        Uri.fromParts("package", packageName, null));
4655                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4656                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4657                        null, null, 0, null, null, null, false, false, userId);
4658            } catch (RemoteException e) {
4659            }
4660        } finally {
4661            Binder.restoreCallingIdentity(callingId);
4662        }
4663        return true;
4664    }
4665
4666    @Override
4667    public void killBackgroundProcesses(final String packageName, int userId) {
4668        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4669                != PackageManager.PERMISSION_GRANTED &&
4670                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4671                        != PackageManager.PERMISSION_GRANTED) {
4672            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4673                    + Binder.getCallingPid()
4674                    + ", uid=" + Binder.getCallingUid()
4675                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4676            Slog.w(TAG, msg);
4677            throw new SecurityException(msg);
4678        }
4679
4680        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4681                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4682        long callingId = Binder.clearCallingIdentity();
4683        try {
4684            IPackageManager pm = AppGlobals.getPackageManager();
4685            synchronized(this) {
4686                int appId = -1;
4687                try {
4688                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4689                } catch (RemoteException e) {
4690                }
4691                if (appId == -1) {
4692                    Slog.w(TAG, "Invalid packageName: " + packageName);
4693                    return;
4694                }
4695                killPackageProcessesLocked(packageName, appId, userId,
4696                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4697            }
4698        } finally {
4699            Binder.restoreCallingIdentity(callingId);
4700        }
4701    }
4702
4703    @Override
4704    public void killAllBackgroundProcesses() {
4705        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4706                != PackageManager.PERMISSION_GRANTED) {
4707            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4708                    + Binder.getCallingPid()
4709                    + ", uid=" + Binder.getCallingUid()
4710                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4711            Slog.w(TAG, msg);
4712            throw new SecurityException(msg);
4713        }
4714
4715        long callingId = Binder.clearCallingIdentity();
4716        try {
4717            synchronized(this) {
4718                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4719                final int NP = mProcessNames.getMap().size();
4720                for (int ip=0; ip<NP; ip++) {
4721                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4722                    final int NA = apps.size();
4723                    for (int ia=0; ia<NA; ia++) {
4724                        ProcessRecord app = apps.valueAt(ia);
4725                        if (app.persistent) {
4726                            // we don't kill persistent processes
4727                            continue;
4728                        }
4729                        if (app.removed) {
4730                            procs.add(app);
4731                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4732                            app.removed = true;
4733                            procs.add(app);
4734                        }
4735                    }
4736                }
4737
4738                int N = procs.size();
4739                for (int i=0; i<N; i++) {
4740                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4741                }
4742                mAllowLowerMemLevel = true;
4743                updateOomAdjLocked();
4744                doLowMemReportIfNeededLocked(null);
4745            }
4746        } finally {
4747            Binder.restoreCallingIdentity(callingId);
4748        }
4749    }
4750
4751    @Override
4752    public void forceStopPackage(final String packageName, int userId) {
4753        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4754                != PackageManager.PERMISSION_GRANTED) {
4755            String msg = "Permission Denial: forceStopPackage() from pid="
4756                    + Binder.getCallingPid()
4757                    + ", uid=" + Binder.getCallingUid()
4758                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4759            Slog.w(TAG, msg);
4760            throw new SecurityException(msg);
4761        }
4762        final int callingPid = Binder.getCallingPid();
4763        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4764                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4765        long callingId = Binder.clearCallingIdentity();
4766        try {
4767            IPackageManager pm = AppGlobals.getPackageManager();
4768            synchronized(this) {
4769                int[] users = userId == UserHandle.USER_ALL
4770                        ? getUsersLocked() : new int[] { userId };
4771                for (int user : users) {
4772                    int pkgUid = -1;
4773                    try {
4774                        pkgUid = pm.getPackageUid(packageName, user);
4775                    } catch (RemoteException e) {
4776                    }
4777                    if (pkgUid == -1) {
4778                        Slog.w(TAG, "Invalid packageName: " + packageName);
4779                        continue;
4780                    }
4781                    try {
4782                        pm.setPackageStoppedState(packageName, true, user);
4783                    } catch (RemoteException e) {
4784                    } catch (IllegalArgumentException e) {
4785                        Slog.w(TAG, "Failed trying to unstop package "
4786                                + packageName + ": " + e);
4787                    }
4788                    if (isUserRunningLocked(user, false)) {
4789                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4790                    }
4791                }
4792            }
4793        } finally {
4794            Binder.restoreCallingIdentity(callingId);
4795        }
4796    }
4797
4798    @Override
4799    public void addPackageDependency(String packageName) {
4800        synchronized (this) {
4801            int callingPid = Binder.getCallingPid();
4802            if (callingPid == Process.myPid()) {
4803                //  Yeah, um, no.
4804                Slog.w(TAG, "Can't addPackageDependency on system process");
4805                return;
4806            }
4807            ProcessRecord proc;
4808            synchronized (mPidsSelfLocked) {
4809                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4810            }
4811            if (proc != null) {
4812                if (proc.pkgDeps == null) {
4813                    proc.pkgDeps = new ArraySet<String>(1);
4814                }
4815                proc.pkgDeps.add(packageName);
4816            }
4817        }
4818    }
4819
4820    /*
4821     * The pkg name and app id have to be specified.
4822     */
4823    @Override
4824    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4825        if (pkg == null) {
4826            return;
4827        }
4828        // Make sure the uid is valid.
4829        if (appid < 0) {
4830            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4831            return;
4832        }
4833        int callerUid = Binder.getCallingUid();
4834        // Only the system server can kill an application
4835        if (callerUid == Process.SYSTEM_UID) {
4836            // Post an aysnc message to kill the application
4837            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4838            msg.arg1 = appid;
4839            msg.arg2 = 0;
4840            Bundle bundle = new Bundle();
4841            bundle.putString("pkg", pkg);
4842            bundle.putString("reason", reason);
4843            msg.obj = bundle;
4844            mHandler.sendMessage(msg);
4845        } else {
4846            throw new SecurityException(callerUid + " cannot kill pkg: " +
4847                    pkg);
4848        }
4849    }
4850
4851    @Override
4852    public void closeSystemDialogs(String reason) {
4853        enforceNotIsolatedCaller("closeSystemDialogs");
4854
4855        final int pid = Binder.getCallingPid();
4856        final int uid = Binder.getCallingUid();
4857        final long origId = Binder.clearCallingIdentity();
4858        try {
4859            synchronized (this) {
4860                // Only allow this from foreground processes, so that background
4861                // applications can't abuse it to prevent system UI from being shown.
4862                if (uid >= Process.FIRST_APPLICATION_UID) {
4863                    ProcessRecord proc;
4864                    synchronized (mPidsSelfLocked) {
4865                        proc = mPidsSelfLocked.get(pid);
4866                    }
4867                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4868                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4869                                + " from background process " + proc);
4870                        return;
4871                    }
4872                }
4873                closeSystemDialogsLocked(reason);
4874            }
4875        } finally {
4876            Binder.restoreCallingIdentity(origId);
4877        }
4878    }
4879
4880    void closeSystemDialogsLocked(String reason) {
4881        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4882        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4883                | Intent.FLAG_RECEIVER_FOREGROUND);
4884        if (reason != null) {
4885            intent.putExtra("reason", reason);
4886        }
4887        mWindowManager.closeSystemDialogs(reason);
4888
4889        mStackSupervisor.closeSystemDialogsLocked();
4890
4891        broadcastIntentLocked(null, null, intent, null,
4892                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4893                Process.SYSTEM_UID, UserHandle.USER_ALL);
4894    }
4895
4896    @Override
4897    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4898        enforceNotIsolatedCaller("getProcessMemoryInfo");
4899        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4900        for (int i=pids.length-1; i>=0; i--) {
4901            ProcessRecord proc;
4902            int oomAdj;
4903            synchronized (this) {
4904                synchronized (mPidsSelfLocked) {
4905                    proc = mPidsSelfLocked.get(pids[i]);
4906                    oomAdj = proc != null ? proc.setAdj : 0;
4907                }
4908            }
4909            infos[i] = new Debug.MemoryInfo();
4910            Debug.getMemoryInfo(pids[i], infos[i]);
4911            if (proc != null) {
4912                synchronized (this) {
4913                    if (proc.thread != null && proc.setAdj == oomAdj) {
4914                        // Record this for posterity if the process has been stable.
4915                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4916                                infos[i].getTotalUss(), false, proc.pkgList);
4917                    }
4918                }
4919            }
4920        }
4921        return infos;
4922    }
4923
4924    @Override
4925    public long[] getProcessPss(int[] pids) {
4926        enforceNotIsolatedCaller("getProcessPss");
4927        long[] pss = new long[pids.length];
4928        for (int i=pids.length-1; i>=0; i--) {
4929            ProcessRecord proc;
4930            int oomAdj;
4931            synchronized (this) {
4932                synchronized (mPidsSelfLocked) {
4933                    proc = mPidsSelfLocked.get(pids[i]);
4934                    oomAdj = proc != null ? proc.setAdj : 0;
4935                }
4936            }
4937            long[] tmpUss = new long[1];
4938            pss[i] = Debug.getPss(pids[i], tmpUss);
4939            if (proc != null) {
4940                synchronized (this) {
4941                    if (proc.thread != null && proc.setAdj == oomAdj) {
4942                        // Record this for posterity if the process has been stable.
4943                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4944                    }
4945                }
4946            }
4947        }
4948        return pss;
4949    }
4950
4951    @Override
4952    public void killApplicationProcess(String processName, int uid) {
4953        if (processName == null) {
4954            return;
4955        }
4956
4957        int callerUid = Binder.getCallingUid();
4958        // Only the system server can kill an application
4959        if (callerUid == Process.SYSTEM_UID) {
4960            synchronized (this) {
4961                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4962                if (app != null && app.thread != null) {
4963                    try {
4964                        app.thread.scheduleSuicide();
4965                    } catch (RemoteException e) {
4966                        // If the other end already died, then our work here is done.
4967                    }
4968                } else {
4969                    Slog.w(TAG, "Process/uid not found attempting kill of "
4970                            + processName + " / " + uid);
4971                }
4972            }
4973        } else {
4974            throw new SecurityException(callerUid + " cannot kill app process: " +
4975                    processName);
4976        }
4977    }
4978
4979    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4980        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4981                false, true, false, false, UserHandle.getUserId(uid), reason);
4982        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4983                Uri.fromParts("package", packageName, null));
4984        if (!mProcessesReady) {
4985            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4986                    | Intent.FLAG_RECEIVER_FOREGROUND);
4987        }
4988        intent.putExtra(Intent.EXTRA_UID, uid);
4989        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4990        broadcastIntentLocked(null, null, intent,
4991                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4992                false, false,
4993                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4994    }
4995
4996    private void forceStopUserLocked(int userId, String reason) {
4997        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4998        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4999        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5000                | Intent.FLAG_RECEIVER_FOREGROUND);
5001        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5002        broadcastIntentLocked(null, null, intent,
5003                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5004                false, false,
5005                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5006    }
5007
5008    private final boolean killPackageProcessesLocked(String packageName, int appId,
5009            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5010            boolean doit, boolean evenPersistent, String reason) {
5011        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5012
5013        // Remove all processes this package may have touched: all with the
5014        // same UID (except for the system or root user), and all whose name
5015        // matches the package name.
5016        final int NP = mProcessNames.getMap().size();
5017        for (int ip=0; ip<NP; ip++) {
5018            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5019            final int NA = apps.size();
5020            for (int ia=0; ia<NA; ia++) {
5021                ProcessRecord app = apps.valueAt(ia);
5022                if (app.persistent && !evenPersistent) {
5023                    // we don't kill persistent processes
5024                    continue;
5025                }
5026                if (app.removed) {
5027                    if (doit) {
5028                        procs.add(app);
5029                    }
5030                    continue;
5031                }
5032
5033                // Skip process if it doesn't meet our oom adj requirement.
5034                if (app.setAdj < minOomAdj) {
5035                    continue;
5036                }
5037
5038                // If no package is specified, we call all processes under the
5039                // give user id.
5040                if (packageName == null) {
5041                    if (app.userId != userId) {
5042                        continue;
5043                    }
5044                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5045                        continue;
5046                    }
5047                // Package has been specified, we want to hit all processes
5048                // that match it.  We need to qualify this by the processes
5049                // that are running under the specified app and user ID.
5050                } else {
5051                    final boolean isDep = app.pkgDeps != null
5052                            && app.pkgDeps.contains(packageName);
5053                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5054                        continue;
5055                    }
5056                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5057                        continue;
5058                    }
5059                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5060                        continue;
5061                    }
5062                }
5063
5064                // Process has passed all conditions, kill it!
5065                if (!doit) {
5066                    return true;
5067                }
5068                app.removed = true;
5069                procs.add(app);
5070            }
5071        }
5072
5073        int N = procs.size();
5074        for (int i=0; i<N; i++) {
5075            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5076        }
5077        updateOomAdjLocked();
5078        return N > 0;
5079    }
5080
5081    private final boolean forceStopPackageLocked(String name, int appId,
5082            boolean callerWillRestart, boolean purgeCache, boolean doit,
5083            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5084        int i;
5085        int N;
5086
5087        if (userId == UserHandle.USER_ALL && name == null) {
5088            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5089        }
5090
5091        if (appId < 0 && name != null) {
5092            try {
5093                appId = UserHandle.getAppId(
5094                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5095            } catch (RemoteException e) {
5096            }
5097        }
5098
5099        if (doit) {
5100            if (name != null) {
5101                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5102                        + " user=" + userId + ": " + reason);
5103            } else {
5104                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5105            }
5106
5107            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5108            for (int ip=pmap.size()-1; ip>=0; ip--) {
5109                SparseArray<Long> ba = pmap.valueAt(ip);
5110                for (i=ba.size()-1; i>=0; i--) {
5111                    boolean remove = false;
5112                    final int entUid = ba.keyAt(i);
5113                    if (name != null) {
5114                        if (userId == UserHandle.USER_ALL) {
5115                            if (UserHandle.getAppId(entUid) == appId) {
5116                                remove = true;
5117                            }
5118                        } else {
5119                            if (entUid == UserHandle.getUid(userId, appId)) {
5120                                remove = true;
5121                            }
5122                        }
5123                    } else if (UserHandle.getUserId(entUid) == userId) {
5124                        remove = true;
5125                    }
5126                    if (remove) {
5127                        ba.removeAt(i);
5128                    }
5129                }
5130                if (ba.size() == 0) {
5131                    pmap.removeAt(ip);
5132                }
5133            }
5134        }
5135
5136        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5137                -100, callerWillRestart, true, doit, evenPersistent,
5138                name == null ? ("stop user " + userId) : ("stop " + name));
5139
5140        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5141            if (!doit) {
5142                return true;
5143            }
5144            didSomething = true;
5145        }
5146
5147        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5148            if (!doit) {
5149                return true;
5150            }
5151            didSomething = true;
5152        }
5153
5154        if (name == null) {
5155            // Remove all sticky broadcasts from this user.
5156            mStickyBroadcasts.remove(userId);
5157        }
5158
5159        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5160        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5161                userId, providers)) {
5162            if (!doit) {
5163                return true;
5164            }
5165            didSomething = true;
5166        }
5167        N = providers.size();
5168        for (i=0; i<N; i++) {
5169            removeDyingProviderLocked(null, providers.get(i), true);
5170        }
5171
5172        // Remove transient permissions granted from/to this package/user
5173        removeUriPermissionsForPackageLocked(name, userId, false);
5174
5175        if (name == null || uninstalling) {
5176            // Remove pending intents.  For now we only do this when force
5177            // stopping users, because we have some problems when doing this
5178            // for packages -- app widgets are not currently cleaned up for
5179            // such packages, so they can be left with bad pending intents.
5180            if (mIntentSenderRecords.size() > 0) {
5181                Iterator<WeakReference<PendingIntentRecord>> it
5182                        = mIntentSenderRecords.values().iterator();
5183                while (it.hasNext()) {
5184                    WeakReference<PendingIntentRecord> wpir = it.next();
5185                    if (wpir == null) {
5186                        it.remove();
5187                        continue;
5188                    }
5189                    PendingIntentRecord pir = wpir.get();
5190                    if (pir == null) {
5191                        it.remove();
5192                        continue;
5193                    }
5194                    if (name == null) {
5195                        // Stopping user, remove all objects for the user.
5196                        if (pir.key.userId != userId) {
5197                            // Not the same user, skip it.
5198                            continue;
5199                        }
5200                    } else {
5201                        if (UserHandle.getAppId(pir.uid) != appId) {
5202                            // Different app id, skip it.
5203                            continue;
5204                        }
5205                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5206                            // Different user, skip it.
5207                            continue;
5208                        }
5209                        if (!pir.key.packageName.equals(name)) {
5210                            // Different package, skip it.
5211                            continue;
5212                        }
5213                    }
5214                    if (!doit) {
5215                        return true;
5216                    }
5217                    didSomething = true;
5218                    it.remove();
5219                    pir.canceled = true;
5220                    if (pir.key.activity != null) {
5221                        pir.key.activity.pendingResults.remove(pir.ref);
5222                    }
5223                }
5224            }
5225        }
5226
5227        if (doit) {
5228            if (purgeCache && name != null) {
5229                AttributeCache ac = AttributeCache.instance();
5230                if (ac != null) {
5231                    ac.removePackage(name);
5232                }
5233            }
5234            if (mBooted) {
5235                mStackSupervisor.resumeTopActivitiesLocked();
5236                mStackSupervisor.scheduleIdleLocked();
5237            }
5238        }
5239
5240        return didSomething;
5241    }
5242
5243    private final boolean removeProcessLocked(ProcessRecord app,
5244            boolean callerWillRestart, boolean allowRestart, String reason) {
5245        final String name = app.processName;
5246        final int uid = app.uid;
5247        if (DEBUG_PROCESSES) Slog.d(
5248            TAG, "Force removing proc " + app.toShortString() + " (" + name
5249            + "/" + uid + ")");
5250
5251        mProcessNames.remove(name, uid);
5252        mIsolatedProcesses.remove(app.uid);
5253        if (mHeavyWeightProcess == app) {
5254            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5255                    mHeavyWeightProcess.userId, 0));
5256            mHeavyWeightProcess = null;
5257        }
5258        boolean needRestart = false;
5259        if (app.pid > 0 && app.pid != MY_PID) {
5260            int pid = app.pid;
5261            synchronized (mPidsSelfLocked) {
5262                mPidsSelfLocked.remove(pid);
5263                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5264            }
5265            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5266            if (app.isolated) {
5267                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5268            }
5269            killUnneededProcessLocked(app, reason);
5270            Process.killProcessGroup(app.info.uid, app.pid);
5271            handleAppDiedLocked(app, true, allowRestart);
5272            removeLruProcessLocked(app);
5273
5274            if (app.persistent && !app.isolated) {
5275                if (!callerWillRestart) {
5276                    addAppLocked(app.info, false, null /* ABI override */);
5277                } else {
5278                    needRestart = true;
5279                }
5280            }
5281        } else {
5282            mRemovedProcesses.add(app);
5283        }
5284
5285        return needRestart;
5286    }
5287
5288    private final void processStartTimedOutLocked(ProcessRecord app) {
5289        final int pid = app.pid;
5290        boolean gone = false;
5291        synchronized (mPidsSelfLocked) {
5292            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5293            if (knownApp != null && knownApp.thread == null) {
5294                mPidsSelfLocked.remove(pid);
5295                gone = true;
5296            }
5297        }
5298
5299        if (gone) {
5300            Slog.w(TAG, "Process " + app + " failed to attach");
5301            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5302                    pid, app.uid, app.processName);
5303            mProcessNames.remove(app.processName, app.uid);
5304            mIsolatedProcesses.remove(app.uid);
5305            if (mHeavyWeightProcess == app) {
5306                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5307                        mHeavyWeightProcess.userId, 0));
5308                mHeavyWeightProcess = null;
5309            }
5310            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5311            if (app.isolated) {
5312                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5313            }
5314            // Take care of any launching providers waiting for this process.
5315            checkAppInLaunchingProvidersLocked(app, true);
5316            // Take care of any services that are waiting for the process.
5317            mServices.processStartTimedOutLocked(app);
5318            killUnneededProcessLocked(app, "start timeout");
5319            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5320                Slog.w(TAG, "Unattached app died before backup, skipping");
5321                try {
5322                    IBackupManager bm = IBackupManager.Stub.asInterface(
5323                            ServiceManager.getService(Context.BACKUP_SERVICE));
5324                    bm.agentDisconnected(app.info.packageName);
5325                } catch (RemoteException e) {
5326                    // Can't happen; the backup manager is local
5327                }
5328            }
5329            if (isPendingBroadcastProcessLocked(pid)) {
5330                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5331                skipPendingBroadcastLocked(pid);
5332            }
5333        } else {
5334            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5335        }
5336    }
5337
5338    private final boolean attachApplicationLocked(IApplicationThread thread,
5339            int pid) {
5340
5341        // Find the application record that is being attached...  either via
5342        // the pid if we are running in multiple processes, or just pull the
5343        // next app record if we are emulating process with anonymous threads.
5344        ProcessRecord app;
5345        if (pid != MY_PID && pid >= 0) {
5346            synchronized (mPidsSelfLocked) {
5347                app = mPidsSelfLocked.get(pid);
5348            }
5349        } else {
5350            app = null;
5351        }
5352
5353        if (app == null) {
5354            Slog.w(TAG, "No pending application record for pid " + pid
5355                    + " (IApplicationThread " + thread + "); dropping process");
5356            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5357            if (pid > 0 && pid != MY_PID) {
5358                Process.killProcessQuiet(pid);
5359                //TODO: Process.killProcessGroup(app.info.uid, pid);
5360            } else {
5361                try {
5362                    thread.scheduleExit();
5363                } catch (Exception e) {
5364                    // Ignore exceptions.
5365                }
5366            }
5367            return false;
5368        }
5369
5370        // If this application record is still attached to a previous
5371        // process, clean it up now.
5372        if (app.thread != null) {
5373            handleAppDiedLocked(app, true, true);
5374        }
5375
5376        // Tell the process all about itself.
5377
5378        if (localLOGV) Slog.v(
5379                TAG, "Binding process pid " + pid + " to record " + app);
5380
5381        final String processName = app.processName;
5382        try {
5383            AppDeathRecipient adr = new AppDeathRecipient(
5384                    app, pid, thread);
5385            thread.asBinder().linkToDeath(adr, 0);
5386            app.deathRecipient = adr;
5387        } catch (RemoteException e) {
5388            app.resetPackageList(mProcessStats);
5389            startProcessLocked(app, "link fail", processName);
5390            return false;
5391        }
5392
5393        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5394
5395        app.makeActive(thread, mProcessStats);
5396        app.curAdj = app.setAdj = -100;
5397        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5398        app.forcingToForeground = null;
5399        updateProcessForegroundLocked(app, false, false);
5400        app.hasShownUi = false;
5401        app.debugging = false;
5402        app.cached = false;
5403
5404        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5405
5406        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5407        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5408
5409        if (!normalMode) {
5410            Slog.i(TAG, "Launching preboot mode app: " + app);
5411        }
5412
5413        if (localLOGV) Slog.v(
5414            TAG, "New app record " + app
5415            + " thread=" + thread.asBinder() + " pid=" + pid);
5416        try {
5417            int testMode = IApplicationThread.DEBUG_OFF;
5418            if (mDebugApp != null && mDebugApp.equals(processName)) {
5419                testMode = mWaitForDebugger
5420                    ? IApplicationThread.DEBUG_WAIT
5421                    : IApplicationThread.DEBUG_ON;
5422                app.debugging = true;
5423                if (mDebugTransient) {
5424                    mDebugApp = mOrigDebugApp;
5425                    mWaitForDebugger = mOrigWaitForDebugger;
5426                }
5427            }
5428            String profileFile = app.instrumentationProfileFile;
5429            ParcelFileDescriptor profileFd = null;
5430            boolean profileAutoStop = false;
5431            if (mProfileApp != null && mProfileApp.equals(processName)) {
5432                mProfileProc = app;
5433                profileFile = mProfileFile;
5434                profileFd = mProfileFd;
5435                profileAutoStop = mAutoStopProfiler;
5436            }
5437            boolean enableOpenGlTrace = false;
5438            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5439                enableOpenGlTrace = true;
5440                mOpenGlTraceApp = null;
5441            }
5442
5443            // If the app is being launched for restore or full backup, set it up specially
5444            boolean isRestrictedBackupMode = false;
5445            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5446                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5447                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5448                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5449            }
5450
5451            ensurePackageDexOpt(app.instrumentationInfo != null
5452                    ? app.instrumentationInfo.packageName
5453                    : app.info.packageName);
5454            if (app.instrumentationClass != null) {
5455                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5456            }
5457            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5458                    + processName + " with config " + mConfiguration);
5459            ApplicationInfo appInfo = app.instrumentationInfo != null
5460                    ? app.instrumentationInfo : app.info;
5461            app.compat = compatibilityInfoForPackageLocked(appInfo);
5462            if (profileFd != null) {
5463                profileFd = profileFd.dup();
5464            }
5465            thread.bindApplication(processName, appInfo, providers,
5466                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5467                    app.instrumentationArguments, app.instrumentationWatcher,
5468                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5469                    isRestrictedBackupMode || !normalMode, app.persistent,
5470                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5471                    mCoreSettingsObserver.getCoreSettingsLocked());
5472            updateLruProcessLocked(app, false, null);
5473            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5474        } catch (Exception e) {
5475            // todo: Yikes!  What should we do?  For now we will try to
5476            // start another process, but that could easily get us in
5477            // an infinite loop of restarting processes...
5478            Slog.w(TAG, "Exception thrown during bind!", e);
5479
5480            app.resetPackageList(mProcessStats);
5481            app.unlinkDeathRecipient();
5482            startProcessLocked(app, "bind fail", processName);
5483            return false;
5484        }
5485
5486        // Remove this record from the list of starting applications.
5487        mPersistentStartingProcesses.remove(app);
5488        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5489                "Attach application locked removing on hold: " + app);
5490        mProcessesOnHold.remove(app);
5491
5492        boolean badApp = false;
5493        boolean didSomething = false;
5494
5495        // See if the top visible activity is waiting to run in this process...
5496        if (normalMode) {
5497            try {
5498                if (mStackSupervisor.attachApplicationLocked(app)) {
5499                    didSomething = true;
5500                }
5501            } catch (Exception e) {
5502                badApp = true;
5503            }
5504        }
5505
5506        // Find any services that should be running in this process...
5507        if (!badApp) {
5508            try {
5509                didSomething |= mServices.attachApplicationLocked(app, processName);
5510            } catch (Exception e) {
5511                badApp = true;
5512            }
5513        }
5514
5515        // Check if a next-broadcast receiver is in this process...
5516        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5517            try {
5518                didSomething |= sendPendingBroadcastsLocked(app);
5519            } catch (Exception e) {
5520                // If the app died trying to launch the receiver we declare it 'bad'
5521                badApp = true;
5522            }
5523        }
5524
5525        // Check whether the next backup agent is in this process...
5526        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5527            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5528            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5529            try {
5530                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5531                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5532                        mBackupTarget.backupMode);
5533            } catch (Exception e) {
5534                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5535                e.printStackTrace();
5536            }
5537        }
5538
5539        if (badApp) {
5540            // todo: Also need to kill application to deal with all
5541            // kinds of exceptions.
5542            handleAppDiedLocked(app, false, true);
5543            return false;
5544        }
5545
5546        if (!didSomething) {
5547            updateOomAdjLocked();
5548        }
5549
5550        return true;
5551    }
5552
5553    @Override
5554    public final void attachApplication(IApplicationThread thread) {
5555        synchronized (this) {
5556            int callingPid = Binder.getCallingPid();
5557            final long origId = Binder.clearCallingIdentity();
5558            attachApplicationLocked(thread, callingPid);
5559            Binder.restoreCallingIdentity(origId);
5560        }
5561    }
5562
5563    @Override
5564    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5565        final long origId = Binder.clearCallingIdentity();
5566        synchronized (this) {
5567            ActivityStack stack = ActivityRecord.getStackLocked(token);
5568            if (stack != null) {
5569                ActivityRecord r =
5570                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5571                if (stopProfiling) {
5572                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5573                        try {
5574                            mProfileFd.close();
5575                        } catch (IOException e) {
5576                        }
5577                        clearProfilerLocked();
5578                    }
5579                }
5580            }
5581        }
5582        Binder.restoreCallingIdentity(origId);
5583    }
5584
5585    void postEnableScreenAfterBootLocked() {
5586        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
5587    }
5588
5589    void enableScreenAfterBoot() {
5590        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5591                SystemClock.uptimeMillis());
5592        mWindowManager.enableScreenAfterBoot();
5593
5594        synchronized (this) {
5595            updateEventDispatchingLocked();
5596        }
5597    }
5598
5599    @Override
5600    public void showBootMessage(final CharSequence msg, final boolean always) {
5601        enforceNotIsolatedCaller("showBootMessage");
5602        mWindowManager.showBootMessage(msg, always);
5603    }
5604
5605    @Override
5606    public void dismissKeyguardOnNextActivity() {
5607        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5608        final long token = Binder.clearCallingIdentity();
5609        try {
5610            synchronized (this) {
5611                if (DEBUG_LOCKSCREEN) logLockScreen("");
5612                if (mLockScreenShown) {
5613                    mLockScreenShown = false;
5614                    comeOutOfSleepIfNeededLocked();
5615                }
5616                mStackSupervisor.setDismissKeyguard(true);
5617            }
5618        } finally {
5619            Binder.restoreCallingIdentity(token);
5620        }
5621    }
5622
5623    final void finishBooting() {
5624        // Register receivers to handle package update events
5625        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5626
5627        synchronized (this) {
5628            // Ensure that any processes we had put on hold are now started
5629            // up.
5630            final int NP = mProcessesOnHold.size();
5631            if (NP > 0) {
5632                ArrayList<ProcessRecord> procs =
5633                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5634                for (int ip=0; ip<NP; ip++) {
5635                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5636                            + procs.get(ip));
5637                    startProcessLocked(procs.get(ip), "on-hold", null);
5638                }
5639            }
5640
5641            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5642                // Start looking for apps that are abusing wake locks.
5643                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5644                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5645                // Tell anyone interested that we are done booting!
5646                SystemProperties.set("sys.boot_completed", "1");
5647                SystemProperties.set("dev.bootcomplete", "1");
5648                for (int i=0; i<mStartedUsers.size(); i++) {
5649                    UserStartedState uss = mStartedUsers.valueAt(i);
5650                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5651                        uss.mState = UserStartedState.STATE_RUNNING;
5652                        final int userId = mStartedUsers.keyAt(i);
5653                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5654                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5655                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5656                        broadcastIntentLocked(null, null, intent, null,
5657                                new IIntentReceiver.Stub() {
5658                                    @Override
5659                                    public void performReceive(Intent intent, int resultCode,
5660                                            String data, Bundle extras, boolean ordered,
5661                                            boolean sticky, int sendingUser) {
5662                                        synchronized (ActivityManagerService.this) {
5663                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5664                                                    true, false);
5665                                        }
5666                                    }
5667                                },
5668                                0, null, null,
5669                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5670                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5671                                userId);
5672                    }
5673                }
5674                scheduleStartProfilesLocked();
5675            }
5676        }
5677    }
5678
5679    final void ensureBootCompleted() {
5680        boolean booting;
5681        boolean enableScreen;
5682        synchronized (this) {
5683            booting = mBooting;
5684            mBooting = false;
5685            enableScreen = !mBooted;
5686            mBooted = true;
5687        }
5688
5689        if (booting) {
5690            finishBooting();
5691        }
5692
5693        if (enableScreen) {
5694            enableScreenAfterBoot();
5695        }
5696    }
5697
5698    @Override
5699    public final void activityResumed(IBinder token) {
5700        final long origId = Binder.clearCallingIdentity();
5701        synchronized(this) {
5702            ActivityStack stack = ActivityRecord.getStackLocked(token);
5703            if (stack != null) {
5704                ActivityRecord.activityResumedLocked(token);
5705            }
5706        }
5707        Binder.restoreCallingIdentity(origId);
5708    }
5709
5710    @Override
5711    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5712        final long origId = Binder.clearCallingIdentity();
5713        synchronized(this) {
5714            ActivityStack stack = ActivityRecord.getStackLocked(token);
5715            if (stack != null) {
5716                stack.activityPausedLocked(token, false, persistentState);
5717            }
5718        }
5719        Binder.restoreCallingIdentity(origId);
5720    }
5721
5722    @Override
5723    public final void activityStopped(IBinder token, Bundle icicle,
5724            PersistableBundle persistentState, CharSequence description) {
5725        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5726
5727        // Refuse possible leaked file descriptors
5728        if (icicle != null && icicle.hasFileDescriptors()) {
5729            throw new IllegalArgumentException("File descriptors passed in Bundle");
5730        }
5731
5732        final long origId = Binder.clearCallingIdentity();
5733
5734        synchronized (this) {
5735            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5736            if (r != null) {
5737                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5738            }
5739        }
5740
5741        trimApplications();
5742
5743        Binder.restoreCallingIdentity(origId);
5744    }
5745
5746    @Override
5747    public final void activityDestroyed(IBinder token) {
5748        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5749        synchronized (this) {
5750            ActivityStack stack = ActivityRecord.getStackLocked(token);
5751            if (stack != null) {
5752                stack.activityDestroyedLocked(token);
5753            }
5754        }
5755    }
5756
5757    @Override
5758    public final void mediaResourcesReleased(IBinder token) {
5759        final long origId = Binder.clearCallingIdentity();
5760        try {
5761            synchronized (this) {
5762                ActivityStack stack = ActivityRecord.getStackLocked(token);
5763                if (stack != null) {
5764                    stack.mediaResourcesReleased(token);
5765                }
5766            }
5767        } finally {
5768            Binder.restoreCallingIdentity(origId);
5769        }
5770    }
5771
5772    @Override
5773    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5774        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5775    }
5776
5777    @Override
5778    public final void notifyEnterAnimationComplete(IBinder token) {
5779        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5780    }
5781
5782    @Override
5783    public String getCallingPackage(IBinder token) {
5784        synchronized (this) {
5785            ActivityRecord r = getCallingRecordLocked(token);
5786            return r != null ? r.info.packageName : null;
5787        }
5788    }
5789
5790    @Override
5791    public ComponentName getCallingActivity(IBinder token) {
5792        synchronized (this) {
5793            ActivityRecord r = getCallingRecordLocked(token);
5794            return r != null ? r.intent.getComponent() : null;
5795        }
5796    }
5797
5798    private ActivityRecord getCallingRecordLocked(IBinder token) {
5799        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5800        if (r == null) {
5801            return null;
5802        }
5803        return r.resultTo;
5804    }
5805
5806    @Override
5807    public ComponentName getActivityClassForToken(IBinder token) {
5808        synchronized(this) {
5809            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5810            if (r == null) {
5811                return null;
5812            }
5813            return r.intent.getComponent();
5814        }
5815    }
5816
5817    @Override
5818    public String getPackageForToken(IBinder token) {
5819        synchronized(this) {
5820            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5821            if (r == null) {
5822                return null;
5823            }
5824            return r.packageName;
5825        }
5826    }
5827
5828    @Override
5829    public IIntentSender getIntentSender(int type,
5830            String packageName, IBinder token, String resultWho,
5831            int requestCode, Intent[] intents, String[] resolvedTypes,
5832            int flags, Bundle options, int userId) {
5833        enforceNotIsolatedCaller("getIntentSender");
5834        // Refuse possible leaked file descriptors
5835        if (intents != null) {
5836            if (intents.length < 1) {
5837                throw new IllegalArgumentException("Intents array length must be >= 1");
5838            }
5839            for (int i=0; i<intents.length; i++) {
5840                Intent intent = intents[i];
5841                if (intent != null) {
5842                    if (intent.hasFileDescriptors()) {
5843                        throw new IllegalArgumentException("File descriptors passed in Intent");
5844                    }
5845                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5846                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5847                        throw new IllegalArgumentException(
5848                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5849                    }
5850                    intents[i] = new Intent(intent);
5851                }
5852            }
5853            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5854                throw new IllegalArgumentException(
5855                        "Intent array length does not match resolvedTypes length");
5856            }
5857        }
5858        if (options != null) {
5859            if (options.hasFileDescriptors()) {
5860                throw new IllegalArgumentException("File descriptors passed in options");
5861            }
5862        }
5863
5864        synchronized(this) {
5865            int callingUid = Binder.getCallingUid();
5866            int origUserId = userId;
5867            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5868                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5869                    ALLOW_NON_FULL, "getIntentSender", null);
5870            if (origUserId == UserHandle.USER_CURRENT) {
5871                // We don't want to evaluate this until the pending intent is
5872                // actually executed.  However, we do want to always do the
5873                // security checking for it above.
5874                userId = UserHandle.USER_CURRENT;
5875            }
5876            try {
5877                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5878                    int uid = AppGlobals.getPackageManager()
5879                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5880                    if (!UserHandle.isSameApp(callingUid, uid)) {
5881                        String msg = "Permission Denial: getIntentSender() from pid="
5882                            + Binder.getCallingPid()
5883                            + ", uid=" + Binder.getCallingUid()
5884                            + ", (need uid=" + uid + ")"
5885                            + " is not allowed to send as package " + packageName;
5886                        Slog.w(TAG, msg);
5887                        throw new SecurityException(msg);
5888                    }
5889                }
5890
5891                return getIntentSenderLocked(type, packageName, callingUid, userId,
5892                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5893
5894            } catch (RemoteException e) {
5895                throw new SecurityException(e);
5896            }
5897        }
5898    }
5899
5900    IIntentSender getIntentSenderLocked(int type, String packageName,
5901            int callingUid, int userId, IBinder token, String resultWho,
5902            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5903            Bundle options) {
5904        if (DEBUG_MU)
5905            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5906        ActivityRecord activity = null;
5907        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5908            activity = ActivityRecord.isInStackLocked(token);
5909            if (activity == null) {
5910                return null;
5911            }
5912            if (activity.finishing) {
5913                return null;
5914            }
5915        }
5916
5917        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5918        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5919        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5920        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5921                |PendingIntent.FLAG_UPDATE_CURRENT);
5922
5923        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5924                type, packageName, activity, resultWho,
5925                requestCode, intents, resolvedTypes, flags, options, userId);
5926        WeakReference<PendingIntentRecord> ref;
5927        ref = mIntentSenderRecords.get(key);
5928        PendingIntentRecord rec = ref != null ? ref.get() : null;
5929        if (rec != null) {
5930            if (!cancelCurrent) {
5931                if (updateCurrent) {
5932                    if (rec.key.requestIntent != null) {
5933                        rec.key.requestIntent.replaceExtras(intents != null ?
5934                                intents[intents.length - 1] : null);
5935                    }
5936                    if (intents != null) {
5937                        intents[intents.length-1] = rec.key.requestIntent;
5938                        rec.key.allIntents = intents;
5939                        rec.key.allResolvedTypes = resolvedTypes;
5940                    } else {
5941                        rec.key.allIntents = null;
5942                        rec.key.allResolvedTypes = null;
5943                    }
5944                }
5945                return rec;
5946            }
5947            rec.canceled = true;
5948            mIntentSenderRecords.remove(key);
5949        }
5950        if (noCreate) {
5951            return rec;
5952        }
5953        rec = new PendingIntentRecord(this, key, callingUid);
5954        mIntentSenderRecords.put(key, rec.ref);
5955        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5956            if (activity.pendingResults == null) {
5957                activity.pendingResults
5958                        = new HashSet<WeakReference<PendingIntentRecord>>();
5959            }
5960            activity.pendingResults.add(rec.ref);
5961        }
5962        return rec;
5963    }
5964
5965    @Override
5966    public void cancelIntentSender(IIntentSender sender) {
5967        if (!(sender instanceof PendingIntentRecord)) {
5968            return;
5969        }
5970        synchronized(this) {
5971            PendingIntentRecord rec = (PendingIntentRecord)sender;
5972            try {
5973                int uid = AppGlobals.getPackageManager()
5974                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5975                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5976                    String msg = "Permission Denial: cancelIntentSender() from pid="
5977                        + Binder.getCallingPid()
5978                        + ", uid=" + Binder.getCallingUid()
5979                        + " is not allowed to cancel packges "
5980                        + rec.key.packageName;
5981                    Slog.w(TAG, msg);
5982                    throw new SecurityException(msg);
5983                }
5984            } catch (RemoteException e) {
5985                throw new SecurityException(e);
5986            }
5987            cancelIntentSenderLocked(rec, true);
5988        }
5989    }
5990
5991    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5992        rec.canceled = true;
5993        mIntentSenderRecords.remove(rec.key);
5994        if (cleanActivity && rec.key.activity != null) {
5995            rec.key.activity.pendingResults.remove(rec.ref);
5996        }
5997    }
5998
5999    @Override
6000    public String getPackageForIntentSender(IIntentSender pendingResult) {
6001        if (!(pendingResult instanceof PendingIntentRecord)) {
6002            return null;
6003        }
6004        try {
6005            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6006            return res.key.packageName;
6007        } catch (ClassCastException e) {
6008        }
6009        return null;
6010    }
6011
6012    @Override
6013    public int getUidForIntentSender(IIntentSender sender) {
6014        if (sender instanceof PendingIntentRecord) {
6015            try {
6016                PendingIntentRecord res = (PendingIntentRecord)sender;
6017                return res.uid;
6018            } catch (ClassCastException e) {
6019            }
6020        }
6021        return -1;
6022    }
6023
6024    @Override
6025    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6026        if (!(pendingResult instanceof PendingIntentRecord)) {
6027            return false;
6028        }
6029        try {
6030            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6031            if (res.key.allIntents == null) {
6032                return false;
6033            }
6034            for (int i=0; i<res.key.allIntents.length; i++) {
6035                Intent intent = res.key.allIntents[i];
6036                if (intent.getPackage() != null && intent.getComponent() != null) {
6037                    return false;
6038                }
6039            }
6040            return true;
6041        } catch (ClassCastException e) {
6042        }
6043        return false;
6044    }
6045
6046    @Override
6047    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6048        if (!(pendingResult instanceof PendingIntentRecord)) {
6049            return false;
6050        }
6051        try {
6052            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6053            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6054                return true;
6055            }
6056            return false;
6057        } catch (ClassCastException e) {
6058        }
6059        return false;
6060    }
6061
6062    @Override
6063    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6064        if (!(pendingResult instanceof PendingIntentRecord)) {
6065            return null;
6066        }
6067        try {
6068            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6069            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6070        } catch (ClassCastException e) {
6071        }
6072        return null;
6073    }
6074
6075    @Override
6076    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6077        if (!(pendingResult instanceof PendingIntentRecord)) {
6078            return null;
6079        }
6080        try {
6081            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6082            Intent intent = res.key.requestIntent;
6083            if (intent != null) {
6084                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6085                        || res.lastTagPrefix.equals(prefix))) {
6086                    return res.lastTag;
6087                }
6088                res.lastTagPrefix = prefix;
6089                StringBuilder sb = new StringBuilder(128);
6090                if (prefix != null) {
6091                    sb.append(prefix);
6092                }
6093                if (intent.getAction() != null) {
6094                    sb.append(intent.getAction());
6095                } else if (intent.getComponent() != null) {
6096                    intent.getComponent().appendShortString(sb);
6097                } else {
6098                    sb.append("?");
6099                }
6100                return res.lastTag = sb.toString();
6101            }
6102        } catch (ClassCastException e) {
6103        }
6104        return null;
6105    }
6106
6107    @Override
6108    public void setProcessLimit(int max) {
6109        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6110                "setProcessLimit()");
6111        synchronized (this) {
6112            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6113            mProcessLimitOverride = max;
6114        }
6115        trimApplications();
6116    }
6117
6118    @Override
6119    public int getProcessLimit() {
6120        synchronized (this) {
6121            return mProcessLimitOverride;
6122        }
6123    }
6124
6125    void foregroundTokenDied(ForegroundToken token) {
6126        synchronized (ActivityManagerService.this) {
6127            synchronized (mPidsSelfLocked) {
6128                ForegroundToken cur
6129                    = mForegroundProcesses.get(token.pid);
6130                if (cur != token) {
6131                    return;
6132                }
6133                mForegroundProcesses.remove(token.pid);
6134                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6135                if (pr == null) {
6136                    return;
6137                }
6138                pr.forcingToForeground = null;
6139                updateProcessForegroundLocked(pr, false, false);
6140            }
6141            updateOomAdjLocked();
6142        }
6143    }
6144
6145    @Override
6146    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6147        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6148                "setProcessForeground()");
6149        synchronized(this) {
6150            boolean changed = false;
6151
6152            synchronized (mPidsSelfLocked) {
6153                ProcessRecord pr = mPidsSelfLocked.get(pid);
6154                if (pr == null && isForeground) {
6155                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6156                    return;
6157                }
6158                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6159                if (oldToken != null) {
6160                    oldToken.token.unlinkToDeath(oldToken, 0);
6161                    mForegroundProcesses.remove(pid);
6162                    if (pr != null) {
6163                        pr.forcingToForeground = null;
6164                    }
6165                    changed = true;
6166                }
6167                if (isForeground && token != null) {
6168                    ForegroundToken newToken = new ForegroundToken() {
6169                        @Override
6170                        public void binderDied() {
6171                            foregroundTokenDied(this);
6172                        }
6173                    };
6174                    newToken.pid = pid;
6175                    newToken.token = token;
6176                    try {
6177                        token.linkToDeath(newToken, 0);
6178                        mForegroundProcesses.put(pid, newToken);
6179                        pr.forcingToForeground = token;
6180                        changed = true;
6181                    } catch (RemoteException e) {
6182                        // If the process died while doing this, we will later
6183                        // do the cleanup with the process death link.
6184                    }
6185                }
6186            }
6187
6188            if (changed) {
6189                updateOomAdjLocked();
6190            }
6191        }
6192    }
6193
6194    // =========================================================
6195    // PERMISSIONS
6196    // =========================================================
6197
6198    static class PermissionController extends IPermissionController.Stub {
6199        ActivityManagerService mActivityManagerService;
6200        PermissionController(ActivityManagerService activityManagerService) {
6201            mActivityManagerService = activityManagerService;
6202        }
6203
6204        @Override
6205        public boolean checkPermission(String permission, int pid, int uid) {
6206            return mActivityManagerService.checkPermission(permission, pid,
6207                    uid) == PackageManager.PERMISSION_GRANTED;
6208        }
6209    }
6210
6211    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6212        @Override
6213        public int checkComponentPermission(String permission, int pid, int uid,
6214                int owningUid, boolean exported) {
6215            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6216                    owningUid, exported);
6217        }
6218
6219        @Override
6220        public Object getAMSLock() {
6221            return ActivityManagerService.this;
6222        }
6223    }
6224
6225    /**
6226     * This can be called with or without the global lock held.
6227     */
6228    int checkComponentPermission(String permission, int pid, int uid,
6229            int owningUid, boolean exported) {
6230        // We might be performing an operation on behalf of an indirect binder
6231        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6232        // client identity accordingly before proceeding.
6233        Identity tlsIdentity = sCallerIdentity.get();
6234        if (tlsIdentity != null) {
6235            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6236                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6237            uid = tlsIdentity.uid;
6238            pid = tlsIdentity.pid;
6239        }
6240
6241        if (pid == MY_PID) {
6242            return PackageManager.PERMISSION_GRANTED;
6243        }
6244
6245        return ActivityManager.checkComponentPermission(permission, uid,
6246                owningUid, exported);
6247    }
6248
6249    /**
6250     * As the only public entry point for permissions checking, this method
6251     * can enforce the semantic that requesting a check on a null global
6252     * permission is automatically denied.  (Internally a null permission
6253     * string is used when calling {@link #checkComponentPermission} in cases
6254     * when only uid-based security is needed.)
6255     *
6256     * This can be called with or without the global lock held.
6257     */
6258    @Override
6259    public int checkPermission(String permission, int pid, int uid) {
6260        if (permission == null) {
6261            return PackageManager.PERMISSION_DENIED;
6262        }
6263        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6264    }
6265
6266    /**
6267     * Binder IPC calls go through the public entry point.
6268     * This can be called with or without the global lock held.
6269     */
6270    int checkCallingPermission(String permission) {
6271        return checkPermission(permission,
6272                Binder.getCallingPid(),
6273                UserHandle.getAppId(Binder.getCallingUid()));
6274    }
6275
6276    /**
6277     * This can be called with or without the global lock held.
6278     */
6279    void enforceCallingPermission(String permission, String func) {
6280        if (checkCallingPermission(permission)
6281                == PackageManager.PERMISSION_GRANTED) {
6282            return;
6283        }
6284
6285        String msg = "Permission Denial: " + func + " from pid="
6286                + Binder.getCallingPid()
6287                + ", uid=" + Binder.getCallingUid()
6288                + " requires " + permission;
6289        Slog.w(TAG, msg);
6290        throw new SecurityException(msg);
6291    }
6292
6293    /**
6294     * Determine if UID is holding permissions required to access {@link Uri} in
6295     * the given {@link ProviderInfo}. Final permission checking is always done
6296     * in {@link ContentProvider}.
6297     */
6298    private final boolean checkHoldingPermissionsLocked(
6299            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6300        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6301                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6302        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6303            return false;
6304        }
6305        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6306    }
6307
6308    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6309            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6310        if (pi.applicationInfo.uid == uid) {
6311            return true;
6312        } else if (!pi.exported) {
6313            return false;
6314        }
6315
6316        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6317        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6318        try {
6319            // check if target holds top-level <provider> permissions
6320            if (!readMet && pi.readPermission != null && considerUidPermissions
6321                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6322                readMet = true;
6323            }
6324            if (!writeMet && pi.writePermission != null && considerUidPermissions
6325                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6326                writeMet = true;
6327            }
6328
6329            // track if unprotected read/write is allowed; any denied
6330            // <path-permission> below removes this ability
6331            boolean allowDefaultRead = pi.readPermission == null;
6332            boolean allowDefaultWrite = pi.writePermission == null;
6333
6334            // check if target holds any <path-permission> that match uri
6335            final PathPermission[] pps = pi.pathPermissions;
6336            if (pps != null) {
6337                final String path = grantUri.uri.getPath();
6338                int i = pps.length;
6339                while (i > 0 && (!readMet || !writeMet)) {
6340                    i--;
6341                    PathPermission pp = pps[i];
6342                    if (pp.match(path)) {
6343                        if (!readMet) {
6344                            final String pprperm = pp.getReadPermission();
6345                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6346                                    + pprperm + " for " + pp.getPath()
6347                                    + ": match=" + pp.match(path)
6348                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6349                            if (pprperm != null) {
6350                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6351                                        == PERMISSION_GRANTED) {
6352                                    readMet = true;
6353                                } else {
6354                                    allowDefaultRead = false;
6355                                }
6356                            }
6357                        }
6358                        if (!writeMet) {
6359                            final String ppwperm = pp.getWritePermission();
6360                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6361                                    + ppwperm + " for " + pp.getPath()
6362                                    + ": match=" + pp.match(path)
6363                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6364                            if (ppwperm != null) {
6365                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6366                                        == PERMISSION_GRANTED) {
6367                                    writeMet = true;
6368                                } else {
6369                                    allowDefaultWrite = false;
6370                                }
6371                            }
6372                        }
6373                    }
6374                }
6375            }
6376
6377            // grant unprotected <provider> read/write, if not blocked by
6378            // <path-permission> above
6379            if (allowDefaultRead) readMet = true;
6380            if (allowDefaultWrite) writeMet = true;
6381
6382        } catch (RemoteException e) {
6383            return false;
6384        }
6385
6386        return readMet && writeMet;
6387    }
6388
6389    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6390        ProviderInfo pi = null;
6391        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6392        if (cpr != null) {
6393            pi = cpr.info;
6394        } else {
6395            try {
6396                pi = AppGlobals.getPackageManager().resolveContentProvider(
6397                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6398            } catch (RemoteException ex) {
6399            }
6400        }
6401        return pi;
6402    }
6403
6404    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6405        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6406        if (targetUris != null) {
6407            return targetUris.get(grantUri);
6408        }
6409        return null;
6410    }
6411
6412    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6413            String targetPkg, int targetUid, GrantUri grantUri) {
6414        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6415        if (targetUris == null) {
6416            targetUris = Maps.newArrayMap();
6417            mGrantedUriPermissions.put(targetUid, targetUris);
6418        }
6419
6420        UriPermission perm = targetUris.get(grantUri);
6421        if (perm == null) {
6422            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6423            targetUris.put(grantUri, perm);
6424        }
6425
6426        return perm;
6427    }
6428
6429    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6430            final int modeFlags) {
6431        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6432        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6433                : UriPermission.STRENGTH_OWNED;
6434
6435        // Root gets to do everything.
6436        if (uid == 0) {
6437            return true;
6438        }
6439
6440        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6441        if (perms == null) return false;
6442
6443        // First look for exact match
6444        final UriPermission exactPerm = perms.get(grantUri);
6445        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6446            return true;
6447        }
6448
6449        // No exact match, look for prefixes
6450        final int N = perms.size();
6451        for (int i = 0; i < N; i++) {
6452            final UriPermission perm = perms.valueAt(i);
6453            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6454                    && perm.getStrength(modeFlags) >= minStrength) {
6455                return true;
6456            }
6457        }
6458
6459        return false;
6460    }
6461
6462    @Override
6463    public int checkUriPermission(Uri uri, int pid, int uid,
6464            final int modeFlags, int userId) {
6465        enforceNotIsolatedCaller("checkUriPermission");
6466
6467        // Another redirected-binder-call permissions check as in
6468        // {@link checkComponentPermission}.
6469        Identity tlsIdentity = sCallerIdentity.get();
6470        if (tlsIdentity != null) {
6471            uid = tlsIdentity.uid;
6472            pid = tlsIdentity.pid;
6473        }
6474
6475        // Our own process gets to do everything.
6476        if (pid == MY_PID) {
6477            return PackageManager.PERMISSION_GRANTED;
6478        }
6479        synchronized (this) {
6480            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6481                    ? PackageManager.PERMISSION_GRANTED
6482                    : PackageManager.PERMISSION_DENIED;
6483        }
6484    }
6485
6486    /**
6487     * Check if the targetPkg can be granted permission to access uri by
6488     * the callingUid using the given modeFlags.  Throws a security exception
6489     * if callingUid is not allowed to do this.  Returns the uid of the target
6490     * if the URI permission grant should be performed; returns -1 if it is not
6491     * needed (for example targetPkg already has permission to access the URI).
6492     * If you already know the uid of the target, you can supply it in
6493     * lastTargetUid else set that to -1.
6494     */
6495    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6496            final int modeFlags, int lastTargetUid) {
6497        if (!Intent.isAccessUriMode(modeFlags)) {
6498            return -1;
6499        }
6500
6501        if (targetPkg != null) {
6502            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6503                    "Checking grant " + targetPkg + " permission to " + grantUri);
6504        }
6505
6506        final IPackageManager pm = AppGlobals.getPackageManager();
6507
6508        // If this is not a content: uri, we can't do anything with it.
6509        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6510            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6511                    "Can't grant URI permission for non-content URI: " + grantUri);
6512            return -1;
6513        }
6514
6515        final String authority = grantUri.uri.getAuthority();
6516        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6517        if (pi == null) {
6518            Slog.w(TAG, "No content provider found for permission check: " +
6519                    grantUri.uri.toSafeString());
6520            return -1;
6521        }
6522
6523        int targetUid = lastTargetUid;
6524        if (targetUid < 0 && targetPkg != null) {
6525            try {
6526                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6527                if (targetUid < 0) {
6528                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6529                            "Can't grant URI permission no uid for: " + targetPkg);
6530                    return -1;
6531                }
6532            } catch (RemoteException ex) {
6533                return -1;
6534            }
6535        }
6536
6537        if (targetUid >= 0) {
6538            // First...  does the target actually need this permission?
6539            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6540                // No need to grant the target this permission.
6541                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6542                        "Target " + targetPkg + " already has full permission to " + grantUri);
6543                return -1;
6544            }
6545        } else {
6546            // First...  there is no target package, so can anyone access it?
6547            boolean allowed = pi.exported;
6548            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6549                if (pi.readPermission != null) {
6550                    allowed = false;
6551                }
6552            }
6553            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6554                if (pi.writePermission != null) {
6555                    allowed = false;
6556                }
6557            }
6558            if (allowed) {
6559                return -1;
6560            }
6561        }
6562
6563        /* There is a special cross user grant if:
6564         * - The target is on another user.
6565         * - Apps on the current user can access the uri without any uid permissions.
6566         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6567         * grant uri permissions.
6568         */
6569        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6570                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6571                modeFlags, false /*without considering the uid permissions*/);
6572
6573        // Second...  is the provider allowing granting of URI permissions?
6574        if (!specialCrossUserGrant) {
6575            if (!pi.grantUriPermissions) {
6576                throw new SecurityException("Provider " + pi.packageName
6577                        + "/" + pi.name
6578                        + " does not allow granting of Uri permissions (uri "
6579                        + grantUri + ")");
6580            }
6581            if (pi.uriPermissionPatterns != null) {
6582                final int N = pi.uriPermissionPatterns.length;
6583                boolean allowed = false;
6584                for (int i=0; i<N; i++) {
6585                    if (pi.uriPermissionPatterns[i] != null
6586                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6587                        allowed = true;
6588                        break;
6589                    }
6590                }
6591                if (!allowed) {
6592                    throw new SecurityException("Provider " + pi.packageName
6593                            + "/" + pi.name
6594                            + " does not allow granting of permission to path of Uri "
6595                            + grantUri);
6596                }
6597            }
6598        }
6599
6600        // Third...  does the caller itself have permission to access
6601        // this uri?
6602        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6603            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6604                // Require they hold a strong enough Uri permission
6605                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6606                    throw new SecurityException("Uid " + callingUid
6607                            + " does not have permission to uri " + grantUri);
6608                }
6609            }
6610        }
6611        return targetUid;
6612    }
6613
6614    @Override
6615    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6616            final int modeFlags, int userId) {
6617        enforceNotIsolatedCaller("checkGrantUriPermission");
6618        synchronized(this) {
6619            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6620                    new GrantUri(userId, uri, false), modeFlags, -1);
6621        }
6622    }
6623
6624    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6625            final int modeFlags, UriPermissionOwner owner) {
6626        if (!Intent.isAccessUriMode(modeFlags)) {
6627            return;
6628        }
6629
6630        // So here we are: the caller has the assumed permission
6631        // to the uri, and the target doesn't.  Let's now give this to
6632        // the target.
6633
6634        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6635                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6636
6637        final String authority = grantUri.uri.getAuthority();
6638        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6639        if (pi == null) {
6640            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6641            return;
6642        }
6643
6644        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6645            grantUri.prefix = true;
6646        }
6647        final UriPermission perm = findOrCreateUriPermissionLocked(
6648                pi.packageName, targetPkg, targetUid, grantUri);
6649        perm.grantModes(modeFlags, owner);
6650    }
6651
6652    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6653            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6654        if (targetPkg == null) {
6655            throw new NullPointerException("targetPkg");
6656        }
6657        int targetUid;
6658        final IPackageManager pm = AppGlobals.getPackageManager();
6659        try {
6660            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6661        } catch (RemoteException ex) {
6662            return;
6663        }
6664
6665        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6666                targetUid);
6667        if (targetUid < 0) {
6668            return;
6669        }
6670
6671        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6672                owner);
6673    }
6674
6675    static class NeededUriGrants extends ArrayList<GrantUri> {
6676        final String targetPkg;
6677        final int targetUid;
6678        final int flags;
6679
6680        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6681            this.targetPkg = targetPkg;
6682            this.targetUid = targetUid;
6683            this.flags = flags;
6684        }
6685    }
6686
6687    /**
6688     * Like checkGrantUriPermissionLocked, but takes an Intent.
6689     */
6690    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6691            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6692        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6693                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6694                + " clip=" + (intent != null ? intent.getClipData() : null)
6695                + " from " + intent + "; flags=0x"
6696                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6697
6698        if (targetPkg == null) {
6699            throw new NullPointerException("targetPkg");
6700        }
6701
6702        if (intent == null) {
6703            return null;
6704        }
6705        Uri data = intent.getData();
6706        ClipData clip = intent.getClipData();
6707        if (data == null && clip == null) {
6708            return null;
6709        }
6710        // Default userId for uris in the intent (if they don't specify it themselves)
6711        int contentUserHint = intent.getContentUserHint();
6712        if (contentUserHint == UserHandle.USER_CURRENT) {
6713            contentUserHint = UserHandle.getUserId(callingUid);
6714        }
6715        final IPackageManager pm = AppGlobals.getPackageManager();
6716        int targetUid;
6717        if (needed != null) {
6718            targetUid = needed.targetUid;
6719        } else {
6720            try {
6721                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6722            } catch (RemoteException ex) {
6723                return null;
6724            }
6725            if (targetUid < 0) {
6726                if (DEBUG_URI_PERMISSION) {
6727                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6728                            + " on user " + targetUserId);
6729                }
6730                return null;
6731            }
6732        }
6733        if (data != null) {
6734            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6735            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6736                    targetUid);
6737            if (targetUid > 0) {
6738                if (needed == null) {
6739                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6740                }
6741                needed.add(grantUri);
6742            }
6743        }
6744        if (clip != null) {
6745            for (int i=0; i<clip.getItemCount(); i++) {
6746                Uri uri = clip.getItemAt(i).getUri();
6747                if (uri != null) {
6748                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6749                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6750                            targetUid);
6751                    if (targetUid > 0) {
6752                        if (needed == null) {
6753                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6754                        }
6755                        needed.add(grantUri);
6756                    }
6757                } else {
6758                    Intent clipIntent = clip.getItemAt(i).getIntent();
6759                    if (clipIntent != null) {
6760                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6761                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6762                        if (newNeeded != null) {
6763                            needed = newNeeded;
6764                        }
6765                    }
6766                }
6767            }
6768        }
6769
6770        return needed;
6771    }
6772
6773    /**
6774     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6775     */
6776    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6777            UriPermissionOwner owner) {
6778        if (needed != null) {
6779            for (int i=0; i<needed.size(); i++) {
6780                GrantUri grantUri = needed.get(i);
6781                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6782                        grantUri, needed.flags, owner);
6783            }
6784        }
6785    }
6786
6787    void grantUriPermissionFromIntentLocked(int callingUid,
6788            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6789        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6790                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6791        if (needed == null) {
6792            return;
6793        }
6794
6795        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6796    }
6797
6798    @Override
6799    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6800            final int modeFlags, int userId) {
6801        enforceNotIsolatedCaller("grantUriPermission");
6802        GrantUri grantUri = new GrantUri(userId, uri, false);
6803        synchronized(this) {
6804            final ProcessRecord r = getRecordForAppLocked(caller);
6805            if (r == null) {
6806                throw new SecurityException("Unable to find app for caller "
6807                        + caller
6808                        + " when granting permission to uri " + grantUri);
6809            }
6810            if (targetPkg == null) {
6811                throw new IllegalArgumentException("null target");
6812            }
6813            if (grantUri == null) {
6814                throw new IllegalArgumentException("null uri");
6815            }
6816
6817            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6818                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6819                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6820                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6821
6822            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6823                    UserHandle.getUserId(r.uid));
6824        }
6825    }
6826
6827    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6828        if (perm.modeFlags == 0) {
6829            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6830                    perm.targetUid);
6831            if (perms != null) {
6832                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6833                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6834
6835                perms.remove(perm.uri);
6836                if (perms.isEmpty()) {
6837                    mGrantedUriPermissions.remove(perm.targetUid);
6838                }
6839            }
6840        }
6841    }
6842
6843    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6844        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6845
6846        final IPackageManager pm = AppGlobals.getPackageManager();
6847        final String authority = grantUri.uri.getAuthority();
6848        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6849        if (pi == null) {
6850            Slog.w(TAG, "No content provider found for permission revoke: "
6851                    + grantUri.toSafeString());
6852            return;
6853        }
6854
6855        // Does the caller have this permission on the URI?
6856        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6857            // Right now, if you are not the original owner of the permission,
6858            // you are not allowed to revoke it.
6859            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6860                throw new SecurityException("Uid " + callingUid
6861                        + " does not have permission to uri " + grantUri);
6862            //}
6863        }
6864
6865        boolean persistChanged = false;
6866
6867        // Go through all of the permissions and remove any that match.
6868        int N = mGrantedUriPermissions.size();
6869        for (int i = 0; i < N; i++) {
6870            final int targetUid = mGrantedUriPermissions.keyAt(i);
6871            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6872
6873            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6874                final UriPermission perm = it.next();
6875                if (perm.uri.sourceUserId == grantUri.sourceUserId
6876                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6877                    if (DEBUG_URI_PERMISSION)
6878                        Slog.v(TAG,
6879                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6880                    persistChanged |= perm.revokeModes(
6881                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6882                    if (perm.modeFlags == 0) {
6883                        it.remove();
6884                    }
6885                }
6886            }
6887
6888            if (perms.isEmpty()) {
6889                mGrantedUriPermissions.remove(targetUid);
6890                N--;
6891                i--;
6892            }
6893        }
6894
6895        if (persistChanged) {
6896            schedulePersistUriGrants();
6897        }
6898    }
6899
6900    @Override
6901    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6902            int userId) {
6903        enforceNotIsolatedCaller("revokeUriPermission");
6904        synchronized(this) {
6905            final ProcessRecord r = getRecordForAppLocked(caller);
6906            if (r == null) {
6907                throw new SecurityException("Unable to find app for caller "
6908                        + caller
6909                        + " when revoking permission to uri " + uri);
6910            }
6911            if (uri == null) {
6912                Slog.w(TAG, "revokeUriPermission: null uri");
6913                return;
6914            }
6915
6916            if (!Intent.isAccessUriMode(modeFlags)) {
6917                return;
6918            }
6919
6920            final IPackageManager pm = AppGlobals.getPackageManager();
6921            final String authority = uri.getAuthority();
6922            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6923            if (pi == null) {
6924                Slog.w(TAG, "No content provider found for permission revoke: "
6925                        + uri.toSafeString());
6926                return;
6927            }
6928
6929            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6930        }
6931    }
6932
6933    /**
6934     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6935     * given package.
6936     *
6937     * @param packageName Package name to match, or {@code null} to apply to all
6938     *            packages.
6939     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6940     *            to all users.
6941     * @param persistable If persistable grants should be removed.
6942     */
6943    private void removeUriPermissionsForPackageLocked(
6944            String packageName, int userHandle, boolean persistable) {
6945        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6946            throw new IllegalArgumentException("Must narrow by either package or user");
6947        }
6948
6949        boolean persistChanged = false;
6950
6951        int N = mGrantedUriPermissions.size();
6952        for (int i = 0; i < N; i++) {
6953            final int targetUid = mGrantedUriPermissions.keyAt(i);
6954            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6955
6956            // Only inspect grants matching user
6957            if (userHandle == UserHandle.USER_ALL
6958                    || userHandle == UserHandle.getUserId(targetUid)) {
6959                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6960                    final UriPermission perm = it.next();
6961
6962                    // Only inspect grants matching package
6963                    if (packageName == null || perm.sourcePkg.equals(packageName)
6964                            || perm.targetPkg.equals(packageName)) {
6965                        persistChanged |= perm.revokeModes(
6966                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6967
6968                        // Only remove when no modes remain; any persisted grants
6969                        // will keep this alive.
6970                        if (perm.modeFlags == 0) {
6971                            it.remove();
6972                        }
6973                    }
6974                }
6975
6976                if (perms.isEmpty()) {
6977                    mGrantedUriPermissions.remove(targetUid);
6978                    N--;
6979                    i--;
6980                }
6981            }
6982        }
6983
6984        if (persistChanged) {
6985            schedulePersistUriGrants();
6986        }
6987    }
6988
6989    @Override
6990    public IBinder newUriPermissionOwner(String name) {
6991        enforceNotIsolatedCaller("newUriPermissionOwner");
6992        synchronized(this) {
6993            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6994            return owner.getExternalTokenLocked();
6995        }
6996    }
6997
6998    @Override
6999    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7000            final int modeFlags, int sourceUserId, int targetUserId) {
7001        synchronized(this) {
7002            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7003            if (owner == null) {
7004                throw new IllegalArgumentException("Unknown owner: " + token);
7005            }
7006            if (fromUid != Binder.getCallingUid()) {
7007                if (Binder.getCallingUid() != Process.myUid()) {
7008                    // Only system code can grant URI permissions on behalf
7009                    // of other users.
7010                    throw new SecurityException("nice try");
7011                }
7012            }
7013            if (targetPkg == null) {
7014                throw new IllegalArgumentException("null target");
7015            }
7016            if (uri == null) {
7017                throw new IllegalArgumentException("null uri");
7018            }
7019
7020            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7021                    modeFlags, owner, targetUserId);
7022        }
7023    }
7024
7025    @Override
7026    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7027        synchronized(this) {
7028            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7029            if (owner == null) {
7030                throw new IllegalArgumentException("Unknown owner: " + token);
7031            }
7032
7033            if (uri == null) {
7034                owner.removeUriPermissionsLocked(mode);
7035            } else {
7036                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7037            }
7038        }
7039    }
7040
7041    private void schedulePersistUriGrants() {
7042        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7043            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7044                    10 * DateUtils.SECOND_IN_MILLIS);
7045        }
7046    }
7047
7048    private void writeGrantedUriPermissions() {
7049        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7050
7051        // Snapshot permissions so we can persist without lock
7052        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7053        synchronized (this) {
7054            final int size = mGrantedUriPermissions.size();
7055            for (int i = 0; i < size; i++) {
7056                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7057                for (UriPermission perm : perms.values()) {
7058                    if (perm.persistedModeFlags != 0) {
7059                        persist.add(perm.snapshot());
7060                    }
7061                }
7062            }
7063        }
7064
7065        FileOutputStream fos = null;
7066        try {
7067            fos = mGrantFile.startWrite();
7068
7069            XmlSerializer out = new FastXmlSerializer();
7070            out.setOutput(fos, "utf-8");
7071            out.startDocument(null, true);
7072            out.startTag(null, TAG_URI_GRANTS);
7073            for (UriPermission.Snapshot perm : persist) {
7074                out.startTag(null, TAG_URI_GRANT);
7075                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7076                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7077                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7078                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7079                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7080                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7081                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7082                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7083                out.endTag(null, TAG_URI_GRANT);
7084            }
7085            out.endTag(null, TAG_URI_GRANTS);
7086            out.endDocument();
7087
7088            mGrantFile.finishWrite(fos);
7089        } catch (IOException e) {
7090            if (fos != null) {
7091                mGrantFile.failWrite(fos);
7092            }
7093        }
7094    }
7095
7096    private void readGrantedUriPermissionsLocked() {
7097        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7098
7099        final long now = System.currentTimeMillis();
7100
7101        FileInputStream fis = null;
7102        try {
7103            fis = mGrantFile.openRead();
7104            final XmlPullParser in = Xml.newPullParser();
7105            in.setInput(fis, null);
7106
7107            int type;
7108            while ((type = in.next()) != END_DOCUMENT) {
7109                final String tag = in.getName();
7110                if (type == START_TAG) {
7111                    if (TAG_URI_GRANT.equals(tag)) {
7112                        final int sourceUserId;
7113                        final int targetUserId;
7114                        final int userHandle = readIntAttribute(in,
7115                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7116                        if (userHandle != UserHandle.USER_NULL) {
7117                            // For backwards compatibility.
7118                            sourceUserId = userHandle;
7119                            targetUserId = userHandle;
7120                        } else {
7121                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7122                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7123                        }
7124                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7125                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7126                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7127                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7128                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7129                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7130
7131                        // Sanity check that provider still belongs to source package
7132                        final ProviderInfo pi = getProviderInfoLocked(
7133                                uri.getAuthority(), sourceUserId);
7134                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7135                            int targetUid = -1;
7136                            try {
7137                                targetUid = AppGlobals.getPackageManager()
7138                                        .getPackageUid(targetPkg, targetUserId);
7139                            } catch (RemoteException e) {
7140                            }
7141                            if (targetUid != -1) {
7142                                final UriPermission perm = findOrCreateUriPermissionLocked(
7143                                        sourcePkg, targetPkg, targetUid,
7144                                        new GrantUri(sourceUserId, uri, prefix));
7145                                perm.initPersistedModes(modeFlags, createdTime);
7146                            }
7147                        } else {
7148                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7149                                    + " but instead found " + pi);
7150                        }
7151                    }
7152                }
7153            }
7154        } catch (FileNotFoundException e) {
7155            // Missing grants is okay
7156        } catch (IOException e) {
7157            Log.wtf(TAG, "Failed reading Uri grants", e);
7158        } catch (XmlPullParserException e) {
7159            Log.wtf(TAG, "Failed reading Uri grants", e);
7160        } finally {
7161            IoUtils.closeQuietly(fis);
7162        }
7163    }
7164
7165    @Override
7166    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7167        enforceNotIsolatedCaller("takePersistableUriPermission");
7168
7169        Preconditions.checkFlagsArgument(modeFlags,
7170                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7171
7172        synchronized (this) {
7173            final int callingUid = Binder.getCallingUid();
7174            boolean persistChanged = false;
7175            GrantUri grantUri = new GrantUri(userId, uri, false);
7176
7177            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7178                    new GrantUri(userId, uri, false));
7179            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7180                    new GrantUri(userId, uri, true));
7181
7182            final boolean exactValid = (exactPerm != null)
7183                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7184            final boolean prefixValid = (prefixPerm != null)
7185                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7186
7187            if (!(exactValid || prefixValid)) {
7188                throw new SecurityException("No persistable permission grants found for UID "
7189                        + callingUid + " and Uri " + grantUri.toSafeString());
7190            }
7191
7192            if (exactValid) {
7193                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7194            }
7195            if (prefixValid) {
7196                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7197            }
7198
7199            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7200
7201            if (persistChanged) {
7202                schedulePersistUriGrants();
7203            }
7204        }
7205    }
7206
7207    @Override
7208    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7209        enforceNotIsolatedCaller("releasePersistableUriPermission");
7210
7211        Preconditions.checkFlagsArgument(modeFlags,
7212                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7213
7214        synchronized (this) {
7215            final int callingUid = Binder.getCallingUid();
7216            boolean persistChanged = false;
7217
7218            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7219                    new GrantUri(userId, uri, false));
7220            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7221                    new GrantUri(userId, uri, true));
7222            if (exactPerm == null && prefixPerm == null) {
7223                throw new SecurityException("No permission grants found for UID " + callingUid
7224                        + " and Uri " + uri.toSafeString());
7225            }
7226
7227            if (exactPerm != null) {
7228                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7229                removeUriPermissionIfNeededLocked(exactPerm);
7230            }
7231            if (prefixPerm != null) {
7232                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7233                removeUriPermissionIfNeededLocked(prefixPerm);
7234            }
7235
7236            if (persistChanged) {
7237                schedulePersistUriGrants();
7238            }
7239        }
7240    }
7241
7242    /**
7243     * Prune any older {@link UriPermission} for the given UID until outstanding
7244     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7245     *
7246     * @return if any mutations occured that require persisting.
7247     */
7248    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7249        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7250        if (perms == null) return false;
7251        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7252
7253        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7254        for (UriPermission perm : perms.values()) {
7255            if (perm.persistedModeFlags != 0) {
7256                persisted.add(perm);
7257            }
7258        }
7259
7260        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7261        if (trimCount <= 0) return false;
7262
7263        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7264        for (int i = 0; i < trimCount; i++) {
7265            final UriPermission perm = persisted.get(i);
7266
7267            if (DEBUG_URI_PERMISSION) {
7268                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7269            }
7270
7271            perm.releasePersistableModes(~0);
7272            removeUriPermissionIfNeededLocked(perm);
7273        }
7274
7275        return true;
7276    }
7277
7278    @Override
7279    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7280            String packageName, boolean incoming) {
7281        enforceNotIsolatedCaller("getPersistedUriPermissions");
7282        Preconditions.checkNotNull(packageName, "packageName");
7283
7284        final int callingUid = Binder.getCallingUid();
7285        final IPackageManager pm = AppGlobals.getPackageManager();
7286        try {
7287            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7288            if (packageUid != callingUid) {
7289                throw new SecurityException(
7290                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7291            }
7292        } catch (RemoteException e) {
7293            throw new SecurityException("Failed to verify package name ownership");
7294        }
7295
7296        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7297        synchronized (this) {
7298            if (incoming) {
7299                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7300                        callingUid);
7301                if (perms == null) {
7302                    Slog.w(TAG, "No permission grants found for " + packageName);
7303                } else {
7304                    for (UriPermission perm : perms.values()) {
7305                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7306                            result.add(perm.buildPersistedPublicApiObject());
7307                        }
7308                    }
7309                }
7310            } else {
7311                final int size = mGrantedUriPermissions.size();
7312                for (int i = 0; i < size; i++) {
7313                    final ArrayMap<GrantUri, UriPermission> perms =
7314                            mGrantedUriPermissions.valueAt(i);
7315                    for (UriPermission perm : perms.values()) {
7316                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7317                            result.add(perm.buildPersistedPublicApiObject());
7318                        }
7319                    }
7320                }
7321            }
7322        }
7323        return new ParceledListSlice<android.content.UriPermission>(result);
7324    }
7325
7326    @Override
7327    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7328        synchronized (this) {
7329            ProcessRecord app =
7330                who != null ? getRecordForAppLocked(who) : null;
7331            if (app == null) return;
7332
7333            Message msg = Message.obtain();
7334            msg.what = WAIT_FOR_DEBUGGER_MSG;
7335            msg.obj = app;
7336            msg.arg1 = waiting ? 1 : 0;
7337            mHandler.sendMessage(msg);
7338        }
7339    }
7340
7341    @Override
7342    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7343        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7344        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7345        outInfo.availMem = Process.getFreeMemory();
7346        outInfo.totalMem = Process.getTotalMemory();
7347        outInfo.threshold = homeAppMem;
7348        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7349        outInfo.hiddenAppThreshold = cachedAppMem;
7350        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7351                ProcessList.SERVICE_ADJ);
7352        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7353                ProcessList.VISIBLE_APP_ADJ);
7354        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7355                ProcessList.FOREGROUND_APP_ADJ);
7356    }
7357
7358    // =========================================================
7359    // TASK MANAGEMENT
7360    // =========================================================
7361
7362    @Override
7363    public List<IAppTask> getAppTasks() {
7364        final PackageManager pm = mContext.getPackageManager();
7365        int callingUid = Binder.getCallingUid();
7366        long ident = Binder.clearCallingIdentity();
7367
7368        // Compose the list of packages for this id to test against
7369        HashSet<String> packages = new HashSet<String>();
7370        String[] uidPackages = pm.getPackagesForUid(callingUid);
7371        for (int i = 0; i < uidPackages.length; i++) {
7372            packages.add(uidPackages[i]);
7373        }
7374
7375        synchronized(this) {
7376            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7377            try {
7378                if (localLOGV) Slog.v(TAG, "getAppTasks");
7379
7380                final int N = mRecentTasks.size();
7381                for (int i = 0; i < N; i++) {
7382                    TaskRecord tr = mRecentTasks.get(i);
7383                    // Skip tasks that are not created by the caller
7384                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7385                        ActivityManager.RecentTaskInfo taskInfo =
7386                                createRecentTaskInfoFromTaskRecord(tr);
7387                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7388                        list.add(taskImpl);
7389                    }
7390                }
7391            } finally {
7392                Binder.restoreCallingIdentity(ident);
7393            }
7394            return list;
7395        }
7396    }
7397
7398    @Override
7399    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7400        final int callingUid = Binder.getCallingUid();
7401        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7402
7403        synchronized(this) {
7404            if (localLOGV) Slog.v(
7405                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7406
7407            final boolean allowed = checkCallingPermission(
7408                    android.Manifest.permission.GET_TASKS)
7409                    == PackageManager.PERMISSION_GRANTED;
7410            if (!allowed) {
7411                Slog.w(TAG, "getTasks: caller " + callingUid
7412                        + " does not hold GET_TASKS; limiting output");
7413            }
7414
7415            // TODO: Improve with MRU list from all ActivityStacks.
7416            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7417        }
7418
7419        return list;
7420    }
7421
7422    TaskRecord getMostRecentTask() {
7423        return mRecentTasks.get(0);
7424    }
7425
7426    /**
7427     * Creates a new RecentTaskInfo from a TaskRecord.
7428     */
7429    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7430        // Update the task description to reflect any changes in the task stack
7431        tr.updateTaskDescription();
7432
7433        // Compose the recent task info
7434        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7435        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7436        rti.persistentId = tr.taskId;
7437        rti.baseIntent = new Intent(tr.getBaseIntent());
7438        rti.origActivity = tr.origActivity;
7439        rti.description = tr.lastDescription;
7440        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7441        rti.userId = tr.userId;
7442        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7443        rti.firstActiveTime = tr.firstActiveTime;
7444        rti.lastActiveTime = tr.lastActiveTime;
7445        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7446        return rti;
7447    }
7448
7449    @Override
7450    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7451        final int callingUid = Binder.getCallingUid();
7452        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7453                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7454
7455        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7456        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7457        synchronized (this) {
7458            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7459                    == PackageManager.PERMISSION_GRANTED;
7460            if (!allowed) {
7461                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7462                        + " does not hold GET_TASKS; limiting output");
7463            }
7464            final boolean detailed = checkCallingPermission(
7465                    android.Manifest.permission.GET_DETAILED_TASKS)
7466                    == PackageManager.PERMISSION_GRANTED;
7467
7468            IPackageManager pm = AppGlobals.getPackageManager();
7469
7470            final int N = mRecentTasks.size();
7471            ArrayList<ActivityManager.RecentTaskInfo> res
7472                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7473                            maxNum < N ? maxNum : N);
7474
7475            final Set<Integer> includedUsers;
7476            if (includeProfiles) {
7477                includedUsers = getProfileIdsLocked(userId);
7478            } else {
7479                includedUsers = new HashSet<Integer>();
7480            }
7481            includedUsers.add(Integer.valueOf(userId));
7482
7483            // Regroup affiliated tasks together.
7484            for (int i = 0; i < N; ) {
7485                TaskRecord task = mRecentTasks.remove(i);
7486                if (mTmpRecents.contains(task)) {
7487                    continue;
7488                }
7489                int affiliatedTaskId = task.mAffiliatedTaskId;
7490                while (true) {
7491                    TaskRecord next = task.mNextAffiliate;
7492                    if (next == null) {
7493                        break;
7494                    }
7495                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7496                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7497                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7498                        task.setNextAffiliate(null);
7499                        if (next.mPrevAffiliate == task) {
7500                            next.setPrevAffiliate(null);
7501                        }
7502                        break;
7503                    }
7504                    if (next.mPrevAffiliate != task) {
7505                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7506                                next.mPrevAffiliate + " task=" + task);
7507                        next.setPrevAffiliate(null);
7508                        break;
7509                    }
7510                    if (!mRecentTasks.contains(next)) {
7511                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7512                        task.setNextAffiliate(null);
7513                        if (next.mPrevAffiliate == task) {
7514                            next.setPrevAffiliate(null);
7515                        }
7516                        break;
7517                    }
7518                    task = next;
7519                }
7520                // task is now the end of the list
7521                do {
7522                    mRecentTasks.remove(task);
7523                    mRecentTasks.add(i++, task);
7524                    mTmpRecents.add(task);
7525                } while ((task = task.mPrevAffiliate) != null);
7526            }
7527            mTmpRecents.clear();
7528            // mRecentTasks is now in sorted, affiliated order.
7529
7530            for (int i=0; i<N && maxNum > 0; i++) {
7531                TaskRecord tr = mRecentTasks.get(i);
7532                // Only add calling user or related users recent tasks
7533                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7534
7535                // Return the entry if desired by the caller.  We always return
7536                // the first entry, because callers always expect this to be the
7537                // foreground app.  We may filter others if the caller has
7538                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7539                // we should exclude the entry.
7540
7541                if (i == 0
7542                        || withExcluded
7543                        || (tr.intent == null)
7544                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7545                                == 0)) {
7546                    if (!allowed) {
7547                        // If the caller doesn't have the GET_TASKS permission, then only
7548                        // allow them to see a small subset of tasks -- their own and home.
7549                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7550                            continue;
7551                        }
7552                    }
7553                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7554                        // Don't include auto remove tasks that are finished or finishing.
7555                        continue;
7556                    }
7557
7558                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7559                    if (!detailed) {
7560                        rti.baseIntent.replaceExtras((Bundle)null);
7561                    }
7562
7563                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7564                        // Check whether this activity is currently available.
7565                        try {
7566                            if (rti.origActivity != null) {
7567                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7568                                        == null) {
7569                                    continue;
7570                                }
7571                            } else if (rti.baseIntent != null) {
7572                                if (pm.queryIntentActivities(rti.baseIntent,
7573                                        null, 0, userId) == null) {
7574                                    continue;
7575                                }
7576                            }
7577                        } catch (RemoteException e) {
7578                            // Will never happen.
7579                        }
7580                    }
7581
7582                    res.add(rti);
7583                    maxNum--;
7584                }
7585            }
7586            return res;
7587        }
7588    }
7589
7590    private TaskRecord recentTaskForIdLocked(int id) {
7591        final int N = mRecentTasks.size();
7592            for (int i=0; i<N; i++) {
7593                TaskRecord tr = mRecentTasks.get(i);
7594                if (tr.taskId == id) {
7595                    return tr;
7596                }
7597            }
7598            return null;
7599    }
7600
7601    @Override
7602    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7603        synchronized (this) {
7604            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7605                    "getTaskThumbnail()");
7606            TaskRecord tr = recentTaskForIdLocked(id);
7607            if (tr != null) {
7608                return tr.getTaskThumbnailLocked();
7609            }
7610        }
7611        return null;
7612    }
7613
7614    @Override
7615    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7616        synchronized (this) {
7617            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7618            if (r != null) {
7619                r.taskDescription = td;
7620                r.task.updateTaskDescription();
7621            }
7622        }
7623    }
7624
7625    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7626        if (!pr.killedByAm) {
7627            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7628            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7629                    pr.processName, pr.setAdj, reason);
7630            pr.killedByAm = true;
7631            Process.killProcessQuiet(pr.pid);
7632            Process.killProcessGroup(pr.info.uid, pr.pid);
7633        }
7634    }
7635
7636    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7637        tr.disposeThumbnail();
7638        mRecentTasks.remove(tr);
7639        tr.closeRecentsChain();
7640        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7641        Intent baseIntent = new Intent(
7642                tr.intent != null ? tr.intent : tr.affinityIntent);
7643        ComponentName component = baseIntent.getComponent();
7644        if (component == null) {
7645            Slog.w(TAG, "Now component for base intent of task: " + tr);
7646            return;
7647        }
7648
7649        // Find any running services associated with this app.
7650        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7651
7652        if (killProcesses) {
7653            // Find any running processes associated with this app.
7654            final String pkg = component.getPackageName();
7655            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7656            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7657            for (int i=0; i<pmap.size(); i++) {
7658                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7659                for (int j=0; j<uids.size(); j++) {
7660                    ProcessRecord proc = uids.valueAt(j);
7661                    if (proc.userId != tr.userId) {
7662                        continue;
7663                    }
7664                    if (!proc.pkgList.containsKey(pkg)) {
7665                        continue;
7666                    }
7667                    procs.add(proc);
7668                }
7669            }
7670
7671            // Kill the running processes.
7672            for (int i=0; i<procs.size(); i++) {
7673                ProcessRecord pr = procs.get(i);
7674                if (pr == mHomeProcess) {
7675                    // Don't kill the home process along with tasks from the same package.
7676                    continue;
7677                }
7678                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7679                    killUnneededProcessLocked(pr, "remove task");
7680                } else {
7681                    pr.waitingToKill = "remove task";
7682                }
7683            }
7684        }
7685    }
7686
7687    /**
7688     * Removes the task with the specified task id.
7689     *
7690     * @param taskId Identifier of the task to be removed.
7691     * @param flags Additional operational flags.  May be 0 or
7692     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7693     * @return Returns true if the given task was found and removed.
7694     */
7695    private boolean removeTaskByIdLocked(int taskId, int flags) {
7696        TaskRecord tr = recentTaskForIdLocked(taskId);
7697        if (tr != null) {
7698            tr.removeTaskActivitiesLocked();
7699            cleanUpRemovedTaskLocked(tr, flags);
7700            if (tr.isPersistable) {
7701                notifyTaskPersisterLocked(null, true);
7702            }
7703            return true;
7704        }
7705        return false;
7706    }
7707
7708    @Override
7709    public boolean removeTask(int taskId, int flags) {
7710        synchronized (this) {
7711            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7712                    "removeTask()");
7713            long ident = Binder.clearCallingIdentity();
7714            try {
7715                return removeTaskByIdLocked(taskId, flags);
7716            } finally {
7717                Binder.restoreCallingIdentity(ident);
7718            }
7719        }
7720    }
7721
7722    /**
7723     * TODO: Add mController hook
7724     */
7725    @Override
7726    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7727        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7728                "moveTaskToFront()");
7729
7730        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7731        synchronized(this) {
7732            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7733                    Binder.getCallingUid(), "Task to front")) {
7734                ActivityOptions.abort(options);
7735                return;
7736            }
7737            final long origId = Binder.clearCallingIdentity();
7738            try {
7739                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7740                if (task == null) {
7741                    return;
7742                }
7743                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7744                    mStackSupervisor.showLockTaskToast();
7745                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7746                    return;
7747                }
7748                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7749                if (prev != null && prev.isRecentsActivity()) {
7750                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7751                }
7752                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7753            } finally {
7754                Binder.restoreCallingIdentity(origId);
7755            }
7756            ActivityOptions.abort(options);
7757        }
7758    }
7759
7760    @Override
7761    public void moveTaskToBack(int taskId) {
7762        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7763                "moveTaskToBack()");
7764
7765        synchronized(this) {
7766            TaskRecord tr = recentTaskForIdLocked(taskId);
7767            if (tr != null) {
7768                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7769                ActivityStack stack = tr.stack;
7770                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7771                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7772                            Binder.getCallingUid(), "Task to back")) {
7773                        return;
7774                    }
7775                }
7776                final long origId = Binder.clearCallingIdentity();
7777                try {
7778                    stack.moveTaskToBackLocked(taskId, null);
7779                } finally {
7780                    Binder.restoreCallingIdentity(origId);
7781                }
7782            }
7783        }
7784    }
7785
7786    /**
7787     * Moves an activity, and all of the other activities within the same task, to the bottom
7788     * of the history stack.  The activity's order within the task is unchanged.
7789     *
7790     * @param token A reference to the activity we wish to move
7791     * @param nonRoot If false then this only works if the activity is the root
7792     *                of a task; if true it will work for any activity in a task.
7793     * @return Returns true if the move completed, false if not.
7794     */
7795    @Override
7796    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7797        enforceNotIsolatedCaller("moveActivityTaskToBack");
7798        synchronized(this) {
7799            final long origId = Binder.clearCallingIdentity();
7800            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7801            if (taskId >= 0) {
7802                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7803            }
7804            Binder.restoreCallingIdentity(origId);
7805        }
7806        return false;
7807    }
7808
7809    @Override
7810    public void moveTaskBackwards(int task) {
7811        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7812                "moveTaskBackwards()");
7813
7814        synchronized(this) {
7815            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7816                    Binder.getCallingUid(), "Task backwards")) {
7817                return;
7818            }
7819            final long origId = Binder.clearCallingIdentity();
7820            moveTaskBackwardsLocked(task);
7821            Binder.restoreCallingIdentity(origId);
7822        }
7823    }
7824
7825    private final void moveTaskBackwardsLocked(int task) {
7826        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7827    }
7828
7829    @Override
7830    public IBinder getHomeActivityToken() throws RemoteException {
7831        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7832                "getHomeActivityToken()");
7833        synchronized (this) {
7834            return mStackSupervisor.getHomeActivityToken();
7835        }
7836    }
7837
7838    @Override
7839    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7840            IActivityContainerCallback callback) throws RemoteException {
7841        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7842                "createActivityContainer()");
7843        synchronized (this) {
7844            if (parentActivityToken == null) {
7845                throw new IllegalArgumentException("parent token must not be null");
7846            }
7847            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7848            if (r == null) {
7849                return null;
7850            }
7851            if (callback == null) {
7852                throw new IllegalArgumentException("callback must not be null");
7853            }
7854            return mStackSupervisor.createActivityContainer(r, callback);
7855        }
7856    }
7857
7858    @Override
7859    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7860        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7861                "deleteActivityContainer()");
7862        synchronized (this) {
7863            mStackSupervisor.deleteActivityContainer(container);
7864        }
7865    }
7866
7867    @Override
7868    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7869            throws RemoteException {
7870        synchronized (this) {
7871            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7872            if (stack != null) {
7873                return stack.mActivityContainer;
7874            }
7875            return null;
7876        }
7877    }
7878
7879    @Override
7880    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7881        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7882                "moveTaskToStack()");
7883        if (stackId == HOME_STACK_ID) {
7884            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7885                    new RuntimeException("here").fillInStackTrace());
7886        }
7887        synchronized (this) {
7888            long ident = Binder.clearCallingIdentity();
7889            try {
7890                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7891                        + stackId + " toTop=" + toTop);
7892                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7893            } finally {
7894                Binder.restoreCallingIdentity(ident);
7895            }
7896        }
7897    }
7898
7899    @Override
7900    public void resizeStack(int stackBoxId, Rect bounds) {
7901        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7902                "resizeStackBox()");
7903        long ident = Binder.clearCallingIdentity();
7904        try {
7905            mWindowManager.resizeStack(stackBoxId, bounds);
7906        } finally {
7907            Binder.restoreCallingIdentity(ident);
7908        }
7909    }
7910
7911    @Override
7912    public List<StackInfo> getAllStackInfos() {
7913        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7914                "getAllStackInfos()");
7915        long ident = Binder.clearCallingIdentity();
7916        try {
7917            synchronized (this) {
7918                return mStackSupervisor.getAllStackInfosLocked();
7919            }
7920        } finally {
7921            Binder.restoreCallingIdentity(ident);
7922        }
7923    }
7924
7925    @Override
7926    public StackInfo getStackInfo(int stackId) {
7927        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7928                "getStackInfo()");
7929        long ident = Binder.clearCallingIdentity();
7930        try {
7931            synchronized (this) {
7932                return mStackSupervisor.getStackInfoLocked(stackId);
7933            }
7934        } finally {
7935            Binder.restoreCallingIdentity(ident);
7936        }
7937    }
7938
7939    @Override
7940    public boolean isInHomeStack(int taskId) {
7941        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7942                "getStackInfo()");
7943        long ident = Binder.clearCallingIdentity();
7944        try {
7945            synchronized (this) {
7946                TaskRecord tr = recentTaskForIdLocked(taskId);
7947                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7948            }
7949        } finally {
7950            Binder.restoreCallingIdentity(ident);
7951        }
7952    }
7953
7954    @Override
7955    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7956        synchronized(this) {
7957            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7958        }
7959    }
7960
7961    private boolean isLockTaskAuthorized(String pkg) {
7962        final DevicePolicyManager dpm = (DevicePolicyManager)
7963                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7964        try {
7965            int uid = mContext.getPackageManager().getPackageUid(pkg,
7966                    Binder.getCallingUserHandle().getIdentifier());
7967            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7968        } catch (NameNotFoundException e) {
7969            return false;
7970        }
7971    }
7972
7973    void startLockTaskMode(TaskRecord task) {
7974        final String pkg;
7975        synchronized (this) {
7976            pkg = task.intent.getComponent().getPackageName();
7977        }
7978        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7979        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7980            final TaskRecord taskRecord = task;
7981            mHandler.post(new Runnable() {
7982                @Override
7983                public void run() {
7984                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7985                }
7986            });
7987            return;
7988        }
7989        long ident = Binder.clearCallingIdentity();
7990        try {
7991            synchronized (this) {
7992                // Since we lost lock on task, make sure it is still there.
7993                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7994                if (task != null) {
7995                    if (!isSystemInitiated
7996                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7997                        throw new IllegalArgumentException("Invalid task, not in foreground");
7998                    }
7999                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8000                }
8001            }
8002        } finally {
8003            Binder.restoreCallingIdentity(ident);
8004        }
8005    }
8006
8007    @Override
8008    public void startLockTaskMode(int taskId) {
8009        final TaskRecord task;
8010        long ident = Binder.clearCallingIdentity();
8011        try {
8012            synchronized (this) {
8013                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8014            }
8015        } finally {
8016            Binder.restoreCallingIdentity(ident);
8017        }
8018        if (task != null) {
8019            startLockTaskMode(task);
8020        }
8021    }
8022
8023    @Override
8024    public void startLockTaskMode(IBinder token) {
8025        final TaskRecord task;
8026        long ident = Binder.clearCallingIdentity();
8027        try {
8028            synchronized (this) {
8029                final ActivityRecord r = ActivityRecord.forToken(token);
8030                if (r == null) {
8031                    return;
8032                }
8033                task = r.task;
8034            }
8035        } finally {
8036            Binder.restoreCallingIdentity(ident);
8037        }
8038        if (task != null) {
8039            startLockTaskMode(task);
8040        }
8041    }
8042
8043    @Override
8044    public void startLockTaskModeOnCurrent() throws RemoteException {
8045        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8046        ActivityRecord r = null;
8047        synchronized (this) {
8048            r = mStackSupervisor.topRunningActivityLocked();
8049        }
8050        startLockTaskMode(r.task);
8051    }
8052
8053    @Override
8054    public void stopLockTaskMode() {
8055        // Verify that the user matches the package of the intent for the TaskRecord
8056        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8057        // and stopLockTaskMode.
8058        final int callingUid = Binder.getCallingUid();
8059        if (callingUid != Process.SYSTEM_UID) {
8060            try {
8061                String pkg =
8062                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8063                int uid = mContext.getPackageManager().getPackageUid(pkg,
8064                        Binder.getCallingUserHandle().getIdentifier());
8065                if (uid != callingUid) {
8066                    throw new SecurityException("Invalid uid, expected " + uid);
8067                }
8068            } catch (NameNotFoundException e) {
8069                Log.d(TAG, "stopLockTaskMode " + e);
8070                return;
8071            }
8072        }
8073        long ident = Binder.clearCallingIdentity();
8074        try {
8075            Log.d(TAG, "stopLockTaskMode");
8076            // Stop lock task
8077            synchronized (this) {
8078                mStackSupervisor.setLockTaskModeLocked(null, false);
8079            }
8080        } finally {
8081            Binder.restoreCallingIdentity(ident);
8082        }
8083    }
8084
8085    @Override
8086    public void stopLockTaskModeOnCurrent() throws RemoteException {
8087        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8088        long ident = Binder.clearCallingIdentity();
8089        try {
8090            stopLockTaskMode();
8091        } finally {
8092            Binder.restoreCallingIdentity(ident);
8093        }
8094    }
8095
8096    @Override
8097    public boolean isInLockTaskMode() {
8098        synchronized (this) {
8099            return mStackSupervisor.isInLockTaskMode();
8100        }
8101    }
8102
8103    // =========================================================
8104    // CONTENT PROVIDERS
8105    // =========================================================
8106
8107    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8108        List<ProviderInfo> providers = null;
8109        try {
8110            providers = AppGlobals.getPackageManager().
8111                queryContentProviders(app.processName, app.uid,
8112                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8113        } catch (RemoteException ex) {
8114        }
8115        if (DEBUG_MU)
8116            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8117        int userId = app.userId;
8118        if (providers != null) {
8119            int N = providers.size();
8120            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8121            for (int i=0; i<N; i++) {
8122                ProviderInfo cpi =
8123                    (ProviderInfo)providers.get(i);
8124                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8125                        cpi.name, cpi.flags);
8126                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8127                    // This is a singleton provider, but a user besides the
8128                    // default user is asking to initialize a process it runs
8129                    // in...  well, no, it doesn't actually run in this process,
8130                    // it runs in the process of the default user.  Get rid of it.
8131                    providers.remove(i);
8132                    N--;
8133                    i--;
8134                    continue;
8135                }
8136
8137                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8138                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8139                if (cpr == null) {
8140                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8141                    mProviderMap.putProviderByClass(comp, cpr);
8142                }
8143                if (DEBUG_MU)
8144                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8145                app.pubProviders.put(cpi.name, cpr);
8146                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8147                    // Don't add this if it is a platform component that is marked
8148                    // to run in multiple processes, because this is actually
8149                    // part of the framework so doesn't make sense to track as a
8150                    // separate apk in the process.
8151                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8152                            mProcessStats);
8153                }
8154                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8155            }
8156        }
8157        return providers;
8158    }
8159
8160    /**
8161     * Check if {@link ProcessRecord} has a possible chance at accessing the
8162     * given {@link ProviderInfo}. Final permission checking is always done
8163     * in {@link ContentProvider}.
8164     */
8165    private final String checkContentProviderPermissionLocked(
8166            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8167        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8168        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8169        boolean checkedGrants = false;
8170        if (checkUser) {
8171            // Looking for cross-user grants before enforcing the typical cross-users permissions
8172            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8173            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8174                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8175                    return null;
8176                }
8177                checkedGrants = true;
8178            }
8179            userId = handleIncomingUser(callingPid, callingUid, userId,
8180                    false, ALLOW_NON_FULL,
8181                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8182            if (userId != tmpTargetUserId) {
8183                // When we actually went to determine the final targer user ID, this ended
8184                // up different than our initial check for the authority.  This is because
8185                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8186                // SELF.  So we need to re-check the grants again.
8187                checkedGrants = false;
8188            }
8189        }
8190        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8191                cpi.applicationInfo.uid, cpi.exported)
8192                == PackageManager.PERMISSION_GRANTED) {
8193            return null;
8194        }
8195        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8196                cpi.applicationInfo.uid, cpi.exported)
8197                == PackageManager.PERMISSION_GRANTED) {
8198            return null;
8199        }
8200
8201        PathPermission[] pps = cpi.pathPermissions;
8202        if (pps != null) {
8203            int i = pps.length;
8204            while (i > 0) {
8205                i--;
8206                PathPermission pp = pps[i];
8207                String pprperm = pp.getReadPermission();
8208                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8209                        cpi.applicationInfo.uid, cpi.exported)
8210                        == PackageManager.PERMISSION_GRANTED) {
8211                    return null;
8212                }
8213                String ppwperm = pp.getWritePermission();
8214                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8215                        cpi.applicationInfo.uid, cpi.exported)
8216                        == PackageManager.PERMISSION_GRANTED) {
8217                    return null;
8218                }
8219            }
8220        }
8221        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8222            return null;
8223        }
8224
8225        String msg;
8226        if (!cpi.exported) {
8227            msg = "Permission Denial: opening provider " + cpi.name
8228                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8229                    + ", uid=" + callingUid + ") that is not exported from uid "
8230                    + cpi.applicationInfo.uid;
8231        } else {
8232            msg = "Permission Denial: opening provider " + cpi.name
8233                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8234                    + ", uid=" + callingUid + ") requires "
8235                    + cpi.readPermission + " or " + cpi.writePermission;
8236        }
8237        Slog.w(TAG, msg);
8238        return msg;
8239    }
8240
8241    /**
8242     * Returns if the ContentProvider has granted a uri to callingUid
8243     */
8244    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8245        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8246        if (perms != null) {
8247            for (int i=perms.size()-1; i>=0; i--) {
8248                GrantUri grantUri = perms.keyAt(i);
8249                if (grantUri.sourceUserId == userId || !checkUser) {
8250                    if (matchesProvider(grantUri.uri, cpi)) {
8251                        return true;
8252                    }
8253                }
8254            }
8255        }
8256        return false;
8257    }
8258
8259    /**
8260     * Returns true if the uri authority is one of the authorities specified in the provider.
8261     */
8262    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8263        String uriAuth = uri.getAuthority();
8264        String cpiAuth = cpi.authority;
8265        if (cpiAuth.indexOf(';') == -1) {
8266            return cpiAuth.equals(uriAuth);
8267        }
8268        String[] cpiAuths = cpiAuth.split(";");
8269        int length = cpiAuths.length;
8270        for (int i = 0; i < length; i++) {
8271            if (cpiAuths[i].equals(uriAuth)) return true;
8272        }
8273        return false;
8274    }
8275
8276    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8277            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8278        if (r != null) {
8279            for (int i=0; i<r.conProviders.size(); i++) {
8280                ContentProviderConnection conn = r.conProviders.get(i);
8281                if (conn.provider == cpr) {
8282                    if (DEBUG_PROVIDER) Slog.v(TAG,
8283                            "Adding provider requested by "
8284                            + r.processName + " from process "
8285                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8286                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8287                    if (stable) {
8288                        conn.stableCount++;
8289                        conn.numStableIncs++;
8290                    } else {
8291                        conn.unstableCount++;
8292                        conn.numUnstableIncs++;
8293                    }
8294                    return conn;
8295                }
8296            }
8297            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8298            if (stable) {
8299                conn.stableCount = 1;
8300                conn.numStableIncs = 1;
8301            } else {
8302                conn.unstableCount = 1;
8303                conn.numUnstableIncs = 1;
8304            }
8305            cpr.connections.add(conn);
8306            r.conProviders.add(conn);
8307            return conn;
8308        }
8309        cpr.addExternalProcessHandleLocked(externalProcessToken);
8310        return null;
8311    }
8312
8313    boolean decProviderCountLocked(ContentProviderConnection conn,
8314            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8315        if (conn != null) {
8316            cpr = conn.provider;
8317            if (DEBUG_PROVIDER) Slog.v(TAG,
8318                    "Removing provider requested by "
8319                    + conn.client.processName + " from process "
8320                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8321                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8322            if (stable) {
8323                conn.stableCount--;
8324            } else {
8325                conn.unstableCount--;
8326            }
8327            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8328                cpr.connections.remove(conn);
8329                conn.client.conProviders.remove(conn);
8330                return true;
8331            }
8332            return false;
8333        }
8334        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8335        return false;
8336    }
8337
8338    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8339            String name, IBinder token, boolean stable, int userId) {
8340        ContentProviderRecord cpr;
8341        ContentProviderConnection conn = null;
8342        ProviderInfo cpi = null;
8343
8344        synchronized(this) {
8345            ProcessRecord r = null;
8346            if (caller != null) {
8347                r = getRecordForAppLocked(caller);
8348                if (r == null) {
8349                    throw new SecurityException(
8350                            "Unable to find app for caller " + caller
8351                          + " (pid=" + Binder.getCallingPid()
8352                          + ") when getting content provider " + name);
8353                }
8354            }
8355
8356            boolean checkCrossUser = true;
8357
8358            // First check if this content provider has been published...
8359            cpr = mProviderMap.getProviderByName(name, userId);
8360            // If that didn't work, check if it exists for user 0 and then
8361            // verify that it's a singleton provider before using it.
8362            if (cpr == null && userId != UserHandle.USER_OWNER) {
8363                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8364                if (cpr != null) {
8365                    cpi = cpr.info;
8366                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8367                            cpi.name, cpi.flags)
8368                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8369                        userId = UserHandle.USER_OWNER;
8370                        checkCrossUser = false;
8371                    } else {
8372                        cpr = null;
8373                        cpi = null;
8374                    }
8375                }
8376            }
8377
8378            boolean providerRunning = cpr != null;
8379            if (providerRunning) {
8380                cpi = cpr.info;
8381                String msg;
8382                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8383                        != null) {
8384                    throw new SecurityException(msg);
8385                }
8386
8387                if (r != null && cpr.canRunHere(r)) {
8388                    // This provider has been published or is in the process
8389                    // of being published...  but it is also allowed to run
8390                    // in the caller's process, so don't make a connection
8391                    // and just let the caller instantiate its own instance.
8392                    ContentProviderHolder holder = cpr.newHolder(null);
8393                    // don't give caller the provider object, it needs
8394                    // to make its own.
8395                    holder.provider = null;
8396                    return holder;
8397                }
8398
8399                final long origId = Binder.clearCallingIdentity();
8400
8401                // In this case the provider instance already exists, so we can
8402                // return it right away.
8403                conn = incProviderCountLocked(r, cpr, token, stable);
8404                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8405                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8406                        // If this is a perceptible app accessing the provider,
8407                        // make sure to count it as being accessed and thus
8408                        // back up on the LRU list.  This is good because
8409                        // content providers are often expensive to start.
8410                        updateLruProcessLocked(cpr.proc, false, null);
8411                    }
8412                }
8413
8414                if (cpr.proc != null) {
8415                    if (false) {
8416                        if (cpr.name.flattenToShortString().equals(
8417                                "com.android.providers.calendar/.CalendarProvider2")) {
8418                            Slog.v(TAG, "****************** KILLING "
8419                                + cpr.name.flattenToShortString());
8420                            Process.killProcess(cpr.proc.pid);
8421                        }
8422                    }
8423                    boolean success = updateOomAdjLocked(cpr.proc);
8424                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8425                    // NOTE: there is still a race here where a signal could be
8426                    // pending on the process even though we managed to update its
8427                    // adj level.  Not sure what to do about this, but at least
8428                    // the race is now smaller.
8429                    if (!success) {
8430                        // Uh oh...  it looks like the provider's process
8431                        // has been killed on us.  We need to wait for a new
8432                        // process to be started, and make sure its death
8433                        // doesn't kill our process.
8434                        Slog.i(TAG,
8435                                "Existing provider " + cpr.name.flattenToShortString()
8436                                + " is crashing; detaching " + r);
8437                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8438                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8439                        if (!lastRef) {
8440                            // This wasn't the last ref our process had on
8441                            // the provider...  we have now been killed, bail.
8442                            return null;
8443                        }
8444                        providerRunning = false;
8445                        conn = null;
8446                    }
8447                }
8448
8449                Binder.restoreCallingIdentity(origId);
8450            }
8451
8452            boolean singleton;
8453            if (!providerRunning) {
8454                try {
8455                    cpi = AppGlobals.getPackageManager().
8456                        resolveContentProvider(name,
8457                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8458                } catch (RemoteException ex) {
8459                }
8460                if (cpi == null) {
8461                    return null;
8462                }
8463                // If the provider is a singleton AND
8464                // (it's a call within the same user || the provider is a
8465                // privileged app)
8466                // Then allow connecting to the singleton provider
8467                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8468                        cpi.name, cpi.flags)
8469                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8470                if (singleton) {
8471                    userId = UserHandle.USER_OWNER;
8472                }
8473                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8474
8475                String msg;
8476                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8477                        != null) {
8478                    throw new SecurityException(msg);
8479                }
8480
8481                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8482                        && !cpi.processName.equals("system")) {
8483                    // If this content provider does not run in the system
8484                    // process, and the system is not yet ready to run other
8485                    // processes, then fail fast instead of hanging.
8486                    throw new IllegalArgumentException(
8487                            "Attempt to launch content provider before system ready");
8488                }
8489
8490                // Make sure that the user who owns this provider is started.  If not,
8491                // we don't want to allow it to run.
8492                if (mStartedUsers.get(userId) == null) {
8493                    Slog.w(TAG, "Unable to launch app "
8494                            + cpi.applicationInfo.packageName + "/"
8495                            + cpi.applicationInfo.uid + " for provider "
8496                            + name + ": user " + userId + " is stopped");
8497                    return null;
8498                }
8499
8500                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8501                cpr = mProviderMap.getProviderByClass(comp, userId);
8502                final boolean firstClass = cpr == null;
8503                if (firstClass) {
8504                    try {
8505                        ApplicationInfo ai =
8506                            AppGlobals.getPackageManager().
8507                                getApplicationInfo(
8508                                        cpi.applicationInfo.packageName,
8509                                        STOCK_PM_FLAGS, userId);
8510                        if (ai == null) {
8511                            Slog.w(TAG, "No package info for content provider "
8512                                    + cpi.name);
8513                            return null;
8514                        }
8515                        ai = getAppInfoForUser(ai, userId);
8516                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8517                    } catch (RemoteException ex) {
8518                        // pm is in same process, this will never happen.
8519                    }
8520                }
8521
8522                if (r != null && cpr.canRunHere(r)) {
8523                    // If this is a multiprocess provider, then just return its
8524                    // info and allow the caller to instantiate it.  Only do
8525                    // this if the provider is the same user as the caller's
8526                    // process, or can run as root (so can be in any process).
8527                    return cpr.newHolder(null);
8528                }
8529
8530                if (DEBUG_PROVIDER) {
8531                    RuntimeException e = new RuntimeException("here");
8532                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8533                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8534                }
8535
8536                // This is single process, and our app is now connecting to it.
8537                // See if we are already in the process of launching this
8538                // provider.
8539                final int N = mLaunchingProviders.size();
8540                int i;
8541                for (i=0; i<N; i++) {
8542                    if (mLaunchingProviders.get(i) == cpr) {
8543                        break;
8544                    }
8545                }
8546
8547                // If the provider is not already being launched, then get it
8548                // started.
8549                if (i >= N) {
8550                    final long origId = Binder.clearCallingIdentity();
8551
8552                    try {
8553                        // Content provider is now in use, its package can't be stopped.
8554                        try {
8555                            AppGlobals.getPackageManager().setPackageStoppedState(
8556                                    cpr.appInfo.packageName, false, userId);
8557                        } catch (RemoteException e) {
8558                        } catch (IllegalArgumentException e) {
8559                            Slog.w(TAG, "Failed trying to unstop package "
8560                                    + cpr.appInfo.packageName + ": " + e);
8561                        }
8562
8563                        // Use existing process if already started
8564                        ProcessRecord proc = getProcessRecordLocked(
8565                                cpi.processName, cpr.appInfo.uid, false);
8566                        if (proc != null && proc.thread != null) {
8567                            if (DEBUG_PROVIDER) {
8568                                Slog.d(TAG, "Installing in existing process " + proc);
8569                            }
8570                            proc.pubProviders.put(cpi.name, cpr);
8571                            try {
8572                                proc.thread.scheduleInstallProvider(cpi);
8573                            } catch (RemoteException e) {
8574                            }
8575                        } else {
8576                            proc = startProcessLocked(cpi.processName,
8577                                    cpr.appInfo, false, 0, "content provider",
8578                                    new ComponentName(cpi.applicationInfo.packageName,
8579                                            cpi.name), false, false, false);
8580                            if (proc == null) {
8581                                Slog.w(TAG, "Unable to launch app "
8582                                        + cpi.applicationInfo.packageName + "/"
8583                                        + cpi.applicationInfo.uid + " for provider "
8584                                        + name + ": process is bad");
8585                                return null;
8586                            }
8587                        }
8588                        cpr.launchingApp = proc;
8589                        mLaunchingProviders.add(cpr);
8590                    } finally {
8591                        Binder.restoreCallingIdentity(origId);
8592                    }
8593                }
8594
8595                // Make sure the provider is published (the same provider class
8596                // may be published under multiple names).
8597                if (firstClass) {
8598                    mProviderMap.putProviderByClass(comp, cpr);
8599                }
8600
8601                mProviderMap.putProviderByName(name, cpr);
8602                conn = incProviderCountLocked(r, cpr, token, stable);
8603                if (conn != null) {
8604                    conn.waiting = true;
8605                }
8606            }
8607        }
8608
8609        // Wait for the provider to be published...
8610        synchronized (cpr) {
8611            while (cpr.provider == null) {
8612                if (cpr.launchingApp == null) {
8613                    Slog.w(TAG, "Unable to launch app "
8614                            + cpi.applicationInfo.packageName + "/"
8615                            + cpi.applicationInfo.uid + " for provider "
8616                            + name + ": launching app became null");
8617                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8618                            UserHandle.getUserId(cpi.applicationInfo.uid),
8619                            cpi.applicationInfo.packageName,
8620                            cpi.applicationInfo.uid, name);
8621                    return null;
8622                }
8623                try {
8624                    if (DEBUG_MU) {
8625                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8626                                + cpr.launchingApp);
8627                    }
8628                    if (conn != null) {
8629                        conn.waiting = true;
8630                    }
8631                    cpr.wait();
8632                } catch (InterruptedException ex) {
8633                } finally {
8634                    if (conn != null) {
8635                        conn.waiting = false;
8636                    }
8637                }
8638            }
8639        }
8640        return cpr != null ? cpr.newHolder(conn) : null;
8641    }
8642
8643    @Override
8644    public final ContentProviderHolder getContentProvider(
8645            IApplicationThread caller, String name, int userId, boolean stable) {
8646        enforceNotIsolatedCaller("getContentProvider");
8647        if (caller == null) {
8648            String msg = "null IApplicationThread when getting content provider "
8649                    + name;
8650            Slog.w(TAG, msg);
8651            throw new SecurityException(msg);
8652        }
8653        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8654        // with cross-user grant.
8655        return getContentProviderImpl(caller, name, null, stable, userId);
8656    }
8657
8658    public ContentProviderHolder getContentProviderExternal(
8659            String name, int userId, IBinder token) {
8660        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8661            "Do not have permission in call getContentProviderExternal()");
8662        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8663                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8664        return getContentProviderExternalUnchecked(name, token, userId);
8665    }
8666
8667    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8668            IBinder token, int userId) {
8669        return getContentProviderImpl(null, name, token, true, userId);
8670    }
8671
8672    /**
8673     * Drop a content provider from a ProcessRecord's bookkeeping
8674     */
8675    public void removeContentProvider(IBinder connection, boolean stable) {
8676        enforceNotIsolatedCaller("removeContentProvider");
8677        long ident = Binder.clearCallingIdentity();
8678        try {
8679            synchronized (this) {
8680                ContentProviderConnection conn;
8681                try {
8682                    conn = (ContentProviderConnection)connection;
8683                } catch (ClassCastException e) {
8684                    String msg ="removeContentProvider: " + connection
8685                            + " not a ContentProviderConnection";
8686                    Slog.w(TAG, msg);
8687                    throw new IllegalArgumentException(msg);
8688                }
8689                if (conn == null) {
8690                    throw new NullPointerException("connection is null");
8691                }
8692                if (decProviderCountLocked(conn, null, null, stable)) {
8693                    updateOomAdjLocked();
8694                }
8695            }
8696        } finally {
8697            Binder.restoreCallingIdentity(ident);
8698        }
8699    }
8700
8701    public void removeContentProviderExternal(String name, IBinder token) {
8702        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8703            "Do not have permission in call removeContentProviderExternal()");
8704        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8705    }
8706
8707    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8708        synchronized (this) {
8709            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8710            if(cpr == null) {
8711                //remove from mProvidersByClass
8712                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8713                return;
8714            }
8715
8716            //update content provider record entry info
8717            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8718            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8719            if (localCpr.hasExternalProcessHandles()) {
8720                if (localCpr.removeExternalProcessHandleLocked(token)) {
8721                    updateOomAdjLocked();
8722                } else {
8723                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8724                            + " with no external reference for token: "
8725                            + token + ".");
8726                }
8727            } else {
8728                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8729                        + " with no external references.");
8730            }
8731        }
8732    }
8733
8734    public final void publishContentProviders(IApplicationThread caller,
8735            List<ContentProviderHolder> providers) {
8736        if (providers == null) {
8737            return;
8738        }
8739
8740        enforceNotIsolatedCaller("publishContentProviders");
8741        synchronized (this) {
8742            final ProcessRecord r = getRecordForAppLocked(caller);
8743            if (DEBUG_MU)
8744                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8745            if (r == null) {
8746                throw new SecurityException(
8747                        "Unable to find app for caller " + caller
8748                      + " (pid=" + Binder.getCallingPid()
8749                      + ") when publishing content providers");
8750            }
8751
8752            final long origId = Binder.clearCallingIdentity();
8753
8754            final int N = providers.size();
8755            for (int i=0; i<N; i++) {
8756                ContentProviderHolder src = providers.get(i);
8757                if (src == null || src.info == null || src.provider == null) {
8758                    continue;
8759                }
8760                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8761                if (DEBUG_MU)
8762                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8763                if (dst != null) {
8764                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8765                    mProviderMap.putProviderByClass(comp, dst);
8766                    String names[] = dst.info.authority.split(";");
8767                    for (int j = 0; j < names.length; j++) {
8768                        mProviderMap.putProviderByName(names[j], dst);
8769                    }
8770
8771                    int NL = mLaunchingProviders.size();
8772                    int j;
8773                    for (j=0; j<NL; j++) {
8774                        if (mLaunchingProviders.get(j) == dst) {
8775                            mLaunchingProviders.remove(j);
8776                            j--;
8777                            NL--;
8778                        }
8779                    }
8780                    synchronized (dst) {
8781                        dst.provider = src.provider;
8782                        dst.proc = r;
8783                        dst.notifyAll();
8784                    }
8785                    updateOomAdjLocked(r);
8786                }
8787            }
8788
8789            Binder.restoreCallingIdentity(origId);
8790        }
8791    }
8792
8793    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8794        ContentProviderConnection conn;
8795        try {
8796            conn = (ContentProviderConnection)connection;
8797        } catch (ClassCastException e) {
8798            String msg ="refContentProvider: " + connection
8799                    + " not a ContentProviderConnection";
8800            Slog.w(TAG, msg);
8801            throw new IllegalArgumentException(msg);
8802        }
8803        if (conn == null) {
8804            throw new NullPointerException("connection is null");
8805        }
8806
8807        synchronized (this) {
8808            if (stable > 0) {
8809                conn.numStableIncs += stable;
8810            }
8811            stable = conn.stableCount + stable;
8812            if (stable < 0) {
8813                throw new IllegalStateException("stableCount < 0: " + stable);
8814            }
8815
8816            if (unstable > 0) {
8817                conn.numUnstableIncs += unstable;
8818            }
8819            unstable = conn.unstableCount + unstable;
8820            if (unstable < 0) {
8821                throw new IllegalStateException("unstableCount < 0: " + unstable);
8822            }
8823
8824            if ((stable+unstable) <= 0) {
8825                throw new IllegalStateException("ref counts can't go to zero here: stable="
8826                        + stable + " unstable=" + unstable);
8827            }
8828            conn.stableCount = stable;
8829            conn.unstableCount = unstable;
8830            return !conn.dead;
8831        }
8832    }
8833
8834    public void unstableProviderDied(IBinder connection) {
8835        ContentProviderConnection conn;
8836        try {
8837            conn = (ContentProviderConnection)connection;
8838        } catch (ClassCastException e) {
8839            String msg ="refContentProvider: " + connection
8840                    + " not a ContentProviderConnection";
8841            Slog.w(TAG, msg);
8842            throw new IllegalArgumentException(msg);
8843        }
8844        if (conn == null) {
8845            throw new NullPointerException("connection is null");
8846        }
8847
8848        // Safely retrieve the content provider associated with the connection.
8849        IContentProvider provider;
8850        synchronized (this) {
8851            provider = conn.provider.provider;
8852        }
8853
8854        if (provider == null) {
8855            // Um, yeah, we're way ahead of you.
8856            return;
8857        }
8858
8859        // Make sure the caller is being honest with us.
8860        if (provider.asBinder().pingBinder()) {
8861            // Er, no, still looks good to us.
8862            synchronized (this) {
8863                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8864                        + " says " + conn + " died, but we don't agree");
8865                return;
8866            }
8867        }
8868
8869        // Well look at that!  It's dead!
8870        synchronized (this) {
8871            if (conn.provider.provider != provider) {
8872                // But something changed...  good enough.
8873                return;
8874            }
8875
8876            ProcessRecord proc = conn.provider.proc;
8877            if (proc == null || proc.thread == null) {
8878                // Seems like the process is already cleaned up.
8879                return;
8880            }
8881
8882            // As far as we're concerned, this is just like receiving a
8883            // death notification...  just a bit prematurely.
8884            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8885                    + ") early provider death");
8886            final long ident = Binder.clearCallingIdentity();
8887            try {
8888                appDiedLocked(proc, proc.pid, proc.thread);
8889            } finally {
8890                Binder.restoreCallingIdentity(ident);
8891            }
8892        }
8893    }
8894
8895    @Override
8896    public void appNotRespondingViaProvider(IBinder connection) {
8897        enforceCallingPermission(
8898                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8899
8900        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8901        if (conn == null) {
8902            Slog.w(TAG, "ContentProviderConnection is null");
8903            return;
8904        }
8905
8906        final ProcessRecord host = conn.provider.proc;
8907        if (host == null) {
8908            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8909            return;
8910        }
8911
8912        final long token = Binder.clearCallingIdentity();
8913        try {
8914            appNotResponding(host, null, null, false, "ContentProvider not responding");
8915        } finally {
8916            Binder.restoreCallingIdentity(token);
8917        }
8918    }
8919
8920    public final void installSystemProviders() {
8921        List<ProviderInfo> providers;
8922        synchronized (this) {
8923            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8924            providers = generateApplicationProvidersLocked(app);
8925            if (providers != null) {
8926                for (int i=providers.size()-1; i>=0; i--) {
8927                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8928                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8929                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8930                                + ": not system .apk");
8931                        providers.remove(i);
8932                    }
8933                }
8934            }
8935        }
8936        if (providers != null) {
8937            mSystemThread.installSystemProviders(providers);
8938        }
8939
8940        mCoreSettingsObserver = new CoreSettingsObserver(this);
8941
8942        //mUsageStatsService.monitorPackages();
8943    }
8944
8945    /**
8946     * Allows app to retrieve the MIME type of a URI without having permission
8947     * to access its content provider.
8948     *
8949     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8950     *
8951     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8952     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8953     */
8954    public String getProviderMimeType(Uri uri, int userId) {
8955        enforceNotIsolatedCaller("getProviderMimeType");
8956        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8957                userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null);
8958        final String name = uri.getAuthority();
8959        final long ident = Binder.clearCallingIdentity();
8960        ContentProviderHolder holder = null;
8961
8962        try {
8963            holder = getContentProviderExternalUnchecked(name, null, userId);
8964            if (holder != null) {
8965                return holder.provider.getType(uri);
8966            }
8967        } catch (RemoteException e) {
8968            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8969            return null;
8970        } finally {
8971            if (holder != null) {
8972                removeContentProviderExternalUnchecked(name, null, userId);
8973            }
8974            Binder.restoreCallingIdentity(ident);
8975        }
8976
8977        return null;
8978    }
8979
8980    // =========================================================
8981    // GLOBAL MANAGEMENT
8982    // =========================================================
8983
8984    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8985            boolean isolated, int isolatedUid) {
8986        String proc = customProcess != null ? customProcess : info.processName;
8987        BatteryStatsImpl.Uid.Proc ps = null;
8988        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8989        int uid = info.uid;
8990        if (isolated) {
8991            if (isolatedUid == 0) {
8992                int userId = UserHandle.getUserId(uid);
8993                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8994                while (true) {
8995                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8996                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8997                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8998                    }
8999                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9000                    mNextIsolatedProcessUid++;
9001                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9002                        // No process for this uid, use it.
9003                        break;
9004                    }
9005                    stepsLeft--;
9006                    if (stepsLeft <= 0) {
9007                        return null;
9008                    }
9009                }
9010            } else {
9011                // Special case for startIsolatedProcess (internal only), where
9012                // the uid of the isolated process is specified by the caller.
9013                uid = isolatedUid;
9014            }
9015        }
9016        return new ProcessRecord(stats, info, proc, uid);
9017    }
9018
9019    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9020            String abiOverride) {
9021        ProcessRecord app;
9022        if (!isolated) {
9023            app = getProcessRecordLocked(info.processName, info.uid, true);
9024        } else {
9025            app = null;
9026        }
9027
9028        if (app == null) {
9029            app = newProcessRecordLocked(info, null, isolated, 0);
9030            mProcessNames.put(info.processName, app.uid, app);
9031            if (isolated) {
9032                mIsolatedProcesses.put(app.uid, app);
9033            }
9034            updateLruProcessLocked(app, false, null);
9035            updateOomAdjLocked();
9036        }
9037
9038        // This package really, really can not be stopped.
9039        try {
9040            AppGlobals.getPackageManager().setPackageStoppedState(
9041                    info.packageName, false, UserHandle.getUserId(app.uid));
9042        } catch (RemoteException e) {
9043        } catch (IllegalArgumentException e) {
9044            Slog.w(TAG, "Failed trying to unstop package "
9045                    + info.packageName + ": " + e);
9046        }
9047
9048        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9049                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9050            app.persistent = true;
9051            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9052        }
9053        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9054            mPersistentStartingProcesses.add(app);
9055            startProcessLocked(app, "added application", app.processName, abiOverride,
9056                    null /* entryPoint */, null /* entryPointArgs */);
9057        }
9058
9059        return app;
9060    }
9061
9062    public void unhandledBack() {
9063        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9064                "unhandledBack()");
9065
9066        synchronized(this) {
9067            final long origId = Binder.clearCallingIdentity();
9068            try {
9069                getFocusedStack().unhandledBackLocked();
9070            } finally {
9071                Binder.restoreCallingIdentity(origId);
9072            }
9073        }
9074    }
9075
9076    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9077        enforceNotIsolatedCaller("openContentUri");
9078        final int userId = UserHandle.getCallingUserId();
9079        String name = uri.getAuthority();
9080        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9081        ParcelFileDescriptor pfd = null;
9082        if (cph != null) {
9083            // We record the binder invoker's uid in thread-local storage before
9084            // going to the content provider to open the file.  Later, in the code
9085            // that handles all permissions checks, we look for this uid and use
9086            // that rather than the Activity Manager's own uid.  The effect is that
9087            // we do the check against the caller's permissions even though it looks
9088            // to the content provider like the Activity Manager itself is making
9089            // the request.
9090            sCallerIdentity.set(new Identity(
9091                    Binder.getCallingPid(), Binder.getCallingUid()));
9092            try {
9093                pfd = cph.provider.openFile(null, uri, "r", null);
9094            } catch (FileNotFoundException e) {
9095                // do nothing; pfd will be returned null
9096            } finally {
9097                // Ensure that whatever happens, we clean up the identity state
9098                sCallerIdentity.remove();
9099            }
9100
9101            // We've got the fd now, so we're done with the provider.
9102            removeContentProviderExternalUnchecked(name, null, userId);
9103        } else {
9104            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9105        }
9106        return pfd;
9107    }
9108
9109    // Actually is sleeping or shutting down or whatever else in the future
9110    // is an inactive state.
9111    public boolean isSleepingOrShuttingDown() {
9112        return mSleeping || mShuttingDown;
9113    }
9114
9115    public boolean isSleeping() {
9116        return mSleeping;
9117    }
9118
9119    void goingToSleep() {
9120        synchronized(this) {
9121            mWentToSleep = true;
9122            updateEventDispatchingLocked();
9123            goToSleepIfNeededLocked();
9124        }
9125    }
9126
9127    void finishRunningVoiceLocked() {
9128        if (mRunningVoice) {
9129            mRunningVoice = false;
9130            goToSleepIfNeededLocked();
9131        }
9132    }
9133
9134    void goToSleepIfNeededLocked() {
9135        if (mWentToSleep && !mRunningVoice) {
9136            if (!mSleeping) {
9137                mSleeping = true;
9138                mStackSupervisor.goingToSleepLocked();
9139
9140                // Initialize the wake times of all processes.
9141                checkExcessivePowerUsageLocked(false);
9142                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9143                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9144                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9145            }
9146        }
9147    }
9148
9149    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9150        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9151            // Never persist the home stack.
9152            return;
9153        }
9154        mTaskPersister.wakeup(task, flush);
9155    }
9156
9157    @Override
9158    public boolean shutdown(int timeout) {
9159        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9160                != PackageManager.PERMISSION_GRANTED) {
9161            throw new SecurityException("Requires permission "
9162                    + android.Manifest.permission.SHUTDOWN);
9163        }
9164
9165        boolean timedout = false;
9166
9167        synchronized(this) {
9168            mShuttingDown = true;
9169            updateEventDispatchingLocked();
9170            timedout = mStackSupervisor.shutdownLocked(timeout);
9171        }
9172
9173        mAppOpsService.shutdown();
9174        if (mUsageStatsService != null) {
9175            mUsageStatsService.prepareShutdown();
9176        }
9177        mBatteryStatsService.shutdown();
9178        synchronized (this) {
9179            mProcessStats.shutdownLocked();
9180        }
9181        notifyTaskPersisterLocked(null, true);
9182
9183        return timedout;
9184    }
9185
9186    public final void activitySlept(IBinder token) {
9187        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9188
9189        final long origId = Binder.clearCallingIdentity();
9190
9191        synchronized (this) {
9192            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9193            if (r != null) {
9194                mStackSupervisor.activitySleptLocked(r);
9195            }
9196        }
9197
9198        Binder.restoreCallingIdentity(origId);
9199    }
9200
9201    void logLockScreen(String msg) {
9202        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9203                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9204                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9205                mStackSupervisor.mDismissKeyguardOnNextActivity);
9206    }
9207
9208    private void comeOutOfSleepIfNeededLocked() {
9209        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9210            if (mSleeping) {
9211                mSleeping = false;
9212                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9213            }
9214        }
9215    }
9216
9217    void wakingUp() {
9218        synchronized(this) {
9219            mWentToSleep = false;
9220            updateEventDispatchingLocked();
9221            comeOutOfSleepIfNeededLocked();
9222        }
9223    }
9224
9225    void startRunningVoiceLocked() {
9226        if (!mRunningVoice) {
9227            mRunningVoice = true;
9228            comeOutOfSleepIfNeededLocked();
9229        }
9230    }
9231
9232    private void updateEventDispatchingLocked() {
9233        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9234    }
9235
9236    public void setLockScreenShown(boolean shown) {
9237        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9238                != PackageManager.PERMISSION_GRANTED) {
9239            throw new SecurityException("Requires permission "
9240                    + android.Manifest.permission.DEVICE_POWER);
9241        }
9242
9243        synchronized(this) {
9244            long ident = Binder.clearCallingIdentity();
9245            try {
9246                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9247                mLockScreenShown = shown;
9248                comeOutOfSleepIfNeededLocked();
9249            } finally {
9250                Binder.restoreCallingIdentity(ident);
9251            }
9252        }
9253    }
9254
9255    @Override
9256    public void stopAppSwitches() {
9257        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9258                != PackageManager.PERMISSION_GRANTED) {
9259            throw new SecurityException("Requires permission "
9260                    + android.Manifest.permission.STOP_APP_SWITCHES);
9261        }
9262
9263        synchronized(this) {
9264            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9265                    + APP_SWITCH_DELAY_TIME;
9266            mDidAppSwitch = false;
9267            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9268            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9269            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9270        }
9271    }
9272
9273    public void resumeAppSwitches() {
9274        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9275                != PackageManager.PERMISSION_GRANTED) {
9276            throw new SecurityException("Requires permission "
9277                    + android.Manifest.permission.STOP_APP_SWITCHES);
9278        }
9279
9280        synchronized(this) {
9281            // Note that we don't execute any pending app switches... we will
9282            // let those wait until either the timeout, or the next start
9283            // activity request.
9284            mAppSwitchesAllowedTime = 0;
9285        }
9286    }
9287
9288    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9289            String name) {
9290        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9291            return true;
9292        }
9293
9294        final int perm = checkComponentPermission(
9295                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9296                callingUid, -1, true);
9297        if (perm == PackageManager.PERMISSION_GRANTED) {
9298            return true;
9299        }
9300
9301        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9302        return false;
9303    }
9304
9305    public void setDebugApp(String packageName, boolean waitForDebugger,
9306            boolean persistent) {
9307        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9308                "setDebugApp()");
9309
9310        long ident = Binder.clearCallingIdentity();
9311        try {
9312            // Note that this is not really thread safe if there are multiple
9313            // callers into it at the same time, but that's not a situation we
9314            // care about.
9315            if (persistent) {
9316                final ContentResolver resolver = mContext.getContentResolver();
9317                Settings.Global.putString(
9318                    resolver, Settings.Global.DEBUG_APP,
9319                    packageName);
9320                Settings.Global.putInt(
9321                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9322                    waitForDebugger ? 1 : 0);
9323            }
9324
9325            synchronized (this) {
9326                if (!persistent) {
9327                    mOrigDebugApp = mDebugApp;
9328                    mOrigWaitForDebugger = mWaitForDebugger;
9329                }
9330                mDebugApp = packageName;
9331                mWaitForDebugger = waitForDebugger;
9332                mDebugTransient = !persistent;
9333                if (packageName != null) {
9334                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9335                            false, UserHandle.USER_ALL, "set debug app");
9336                }
9337            }
9338        } finally {
9339            Binder.restoreCallingIdentity(ident);
9340        }
9341    }
9342
9343    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9344        synchronized (this) {
9345            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9346            if (!isDebuggable) {
9347                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9348                    throw new SecurityException("Process not debuggable: " + app.packageName);
9349                }
9350            }
9351
9352            mOpenGlTraceApp = processName;
9353        }
9354    }
9355
9356    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9357            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9358        synchronized (this) {
9359            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9360            if (!isDebuggable) {
9361                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9362                    throw new SecurityException("Process not debuggable: " + app.packageName);
9363                }
9364            }
9365            mProfileApp = processName;
9366            mProfileFile = profileFile;
9367            if (mProfileFd != null) {
9368                try {
9369                    mProfileFd.close();
9370                } catch (IOException e) {
9371                }
9372                mProfileFd = null;
9373            }
9374            mProfileFd = profileFd;
9375            mProfileType = 0;
9376            mAutoStopProfiler = autoStopProfiler;
9377        }
9378    }
9379
9380    @Override
9381    public void setAlwaysFinish(boolean enabled) {
9382        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9383                "setAlwaysFinish()");
9384
9385        Settings.Global.putInt(
9386                mContext.getContentResolver(),
9387                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9388
9389        synchronized (this) {
9390            mAlwaysFinishActivities = enabled;
9391        }
9392    }
9393
9394    @Override
9395    public void setActivityController(IActivityController controller) {
9396        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9397                "setActivityController()");
9398        synchronized (this) {
9399            mController = controller;
9400            Watchdog.getInstance().setActivityController(controller);
9401        }
9402    }
9403
9404    @Override
9405    public void setUserIsMonkey(boolean userIsMonkey) {
9406        synchronized (this) {
9407            synchronized (mPidsSelfLocked) {
9408                final int callingPid = Binder.getCallingPid();
9409                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9410                if (precessRecord == null) {
9411                    throw new SecurityException("Unknown process: " + callingPid);
9412                }
9413                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9414                    throw new SecurityException("Only an instrumentation process "
9415                            + "with a UiAutomation can call setUserIsMonkey");
9416                }
9417            }
9418            mUserIsMonkey = userIsMonkey;
9419        }
9420    }
9421
9422    @Override
9423    public boolean isUserAMonkey() {
9424        synchronized (this) {
9425            // If there is a controller also implies the user is a monkey.
9426            return (mUserIsMonkey || mController != null);
9427        }
9428    }
9429
9430    public void requestBugReport() {
9431        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9432        SystemProperties.set("ctl.start", "bugreport");
9433    }
9434
9435    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9436        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9437    }
9438
9439    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9440        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9441            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9442        }
9443        return KEY_DISPATCHING_TIMEOUT;
9444    }
9445
9446    @Override
9447    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9448        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9449                != PackageManager.PERMISSION_GRANTED) {
9450            throw new SecurityException("Requires permission "
9451                    + android.Manifest.permission.FILTER_EVENTS);
9452        }
9453        ProcessRecord proc;
9454        long timeout;
9455        synchronized (this) {
9456            synchronized (mPidsSelfLocked) {
9457                proc = mPidsSelfLocked.get(pid);
9458            }
9459            timeout = getInputDispatchingTimeoutLocked(proc);
9460        }
9461
9462        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9463            return -1;
9464        }
9465
9466        return timeout;
9467    }
9468
9469    /**
9470     * Handle input dispatching timeouts.
9471     * Returns whether input dispatching should be aborted or not.
9472     */
9473    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9474            final ActivityRecord activity, final ActivityRecord parent,
9475            final boolean aboveSystem, String reason) {
9476        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9477                != PackageManager.PERMISSION_GRANTED) {
9478            throw new SecurityException("Requires permission "
9479                    + android.Manifest.permission.FILTER_EVENTS);
9480        }
9481
9482        final String annotation;
9483        if (reason == null) {
9484            annotation = "Input dispatching timed out";
9485        } else {
9486            annotation = "Input dispatching timed out (" + reason + ")";
9487        }
9488
9489        if (proc != null) {
9490            synchronized (this) {
9491                if (proc.debugging) {
9492                    return false;
9493                }
9494
9495                if (mDidDexOpt) {
9496                    // Give more time since we were dexopting.
9497                    mDidDexOpt = false;
9498                    return false;
9499                }
9500
9501                if (proc.instrumentationClass != null) {
9502                    Bundle info = new Bundle();
9503                    info.putString("shortMsg", "keyDispatchingTimedOut");
9504                    info.putString("longMsg", annotation);
9505                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9506                    return true;
9507                }
9508            }
9509            mHandler.post(new Runnable() {
9510                @Override
9511                public void run() {
9512                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9513                }
9514            });
9515        }
9516
9517        return true;
9518    }
9519
9520    public Bundle getAssistContextExtras(int requestType) {
9521        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9522                "getAssistContextExtras()");
9523        PendingAssistExtras pae;
9524        Bundle extras = new Bundle();
9525        synchronized (this) {
9526            ActivityRecord activity = getFocusedStack().mResumedActivity;
9527            if (activity == null) {
9528                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9529                return null;
9530            }
9531            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9532            if (activity.app == null || activity.app.thread == null) {
9533                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9534                return extras;
9535            }
9536            if (activity.app.pid == Binder.getCallingPid()) {
9537                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9538                return extras;
9539            }
9540            pae = new PendingAssistExtras(activity);
9541            try {
9542                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9543                        requestType);
9544                mPendingAssistExtras.add(pae);
9545                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9546            } catch (RemoteException e) {
9547                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9548                return extras;
9549            }
9550        }
9551        synchronized (pae) {
9552            while (!pae.haveResult) {
9553                try {
9554                    pae.wait();
9555                } catch (InterruptedException e) {
9556                }
9557            }
9558            if (pae.result != null) {
9559                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9560            }
9561        }
9562        synchronized (this) {
9563            mPendingAssistExtras.remove(pae);
9564            mHandler.removeCallbacks(pae);
9565        }
9566        return extras;
9567    }
9568
9569    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9570        PendingAssistExtras pae = (PendingAssistExtras)token;
9571        synchronized (pae) {
9572            pae.result = extras;
9573            pae.haveResult = true;
9574            pae.notifyAll();
9575        }
9576    }
9577
9578    public void registerProcessObserver(IProcessObserver observer) {
9579        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9580                "registerProcessObserver()");
9581        synchronized (this) {
9582            mProcessObservers.register(observer);
9583        }
9584    }
9585
9586    @Override
9587    public void unregisterProcessObserver(IProcessObserver observer) {
9588        synchronized (this) {
9589            mProcessObservers.unregister(observer);
9590        }
9591    }
9592
9593    @Override
9594    public boolean convertFromTranslucent(IBinder token) {
9595        final long origId = Binder.clearCallingIdentity();
9596        try {
9597            synchronized (this) {
9598                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9599                if (r == null) {
9600                    return false;
9601                }
9602                if (r.changeWindowTranslucency(true)) {
9603                    mWindowManager.setAppFullscreen(token, true);
9604                    r.task.stack.releaseMediaResources();
9605                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9606                    return true;
9607                }
9608                return false;
9609            }
9610        } finally {
9611            Binder.restoreCallingIdentity(origId);
9612        }
9613    }
9614
9615    @Override
9616    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9617        final long origId = Binder.clearCallingIdentity();
9618        try {
9619            synchronized (this) {
9620                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9621                if (r == null) {
9622                    return false;
9623                }
9624                int index = r.task.mActivities.lastIndexOf(r);
9625                if (index > 0) {
9626                    ActivityRecord under = r.task.mActivities.get(index - 1);
9627                    under.returningOptions = options;
9628                }
9629                if (r.changeWindowTranslucency(false)) {
9630                    r.task.stack.convertToTranslucent(r);
9631                    mWindowManager.setAppFullscreen(token, false);
9632                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9633                    return true;
9634                } else {
9635                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9636                    return false;
9637                }
9638            }
9639        } finally {
9640            Binder.restoreCallingIdentity(origId);
9641        }
9642    }
9643
9644    @Override
9645    public boolean setMediaPlaying(IBinder token, boolean playing) {
9646        final long origId = Binder.clearCallingIdentity();
9647        try {
9648            synchronized (this) {
9649                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9650                if (r != null) {
9651                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9652                }
9653            }
9654            return false;
9655        } finally {
9656            Binder.restoreCallingIdentity(origId);
9657        }
9658    }
9659
9660    @Override
9661    public boolean isBackgroundMediaPlaying(IBinder token) {
9662        final long origId = Binder.clearCallingIdentity();
9663        try {
9664            synchronized (this) {
9665                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9666                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9667                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9668                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9669                return playing;
9670            }
9671        } finally {
9672            Binder.restoreCallingIdentity(origId);
9673        }
9674    }
9675
9676    @Override
9677    public ActivityOptions getActivityOptions(IBinder token) {
9678        final long origId = Binder.clearCallingIdentity();
9679        try {
9680            synchronized (this) {
9681                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9682                if (r != null) {
9683                    final ActivityOptions activityOptions = r.pendingOptions;
9684                    r.pendingOptions = null;
9685                    return activityOptions;
9686                }
9687                return null;
9688            }
9689        } finally {
9690            Binder.restoreCallingIdentity(origId);
9691        }
9692    }
9693
9694    @Override
9695    public void setImmersive(IBinder token, boolean immersive) {
9696        synchronized(this) {
9697            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9698            if (r == null) {
9699                throw new IllegalArgumentException();
9700            }
9701            r.immersive = immersive;
9702
9703            // update associated state if we're frontmost
9704            if (r == mFocusedActivity) {
9705                if (DEBUG_IMMERSIVE) {
9706                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9707                }
9708                applyUpdateLockStateLocked(r);
9709            }
9710        }
9711    }
9712
9713    @Override
9714    public boolean isImmersive(IBinder token) {
9715        synchronized (this) {
9716            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9717            if (r == null) {
9718                throw new IllegalArgumentException();
9719            }
9720            return r.immersive;
9721        }
9722    }
9723
9724    public boolean isTopActivityImmersive() {
9725        enforceNotIsolatedCaller("startActivity");
9726        synchronized (this) {
9727            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9728            return (r != null) ? r.immersive : false;
9729        }
9730    }
9731
9732    @Override
9733    public boolean isTopOfTask(IBinder token) {
9734        synchronized (this) {
9735            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9736            if (r == null) {
9737                throw new IllegalArgumentException();
9738            }
9739            return r.task.getTopActivity() == r;
9740        }
9741    }
9742
9743    public final void enterSafeMode() {
9744        synchronized(this) {
9745            // It only makes sense to do this before the system is ready
9746            // and started launching other packages.
9747            if (!mSystemReady) {
9748                try {
9749                    AppGlobals.getPackageManager().enterSafeMode();
9750                } catch (RemoteException e) {
9751                }
9752            }
9753
9754            mSafeMode = true;
9755        }
9756    }
9757
9758    public final void showSafeModeOverlay() {
9759        View v = LayoutInflater.from(mContext).inflate(
9760                com.android.internal.R.layout.safe_mode, null);
9761        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9762        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9763        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9764        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9765        lp.gravity = Gravity.BOTTOM | Gravity.START;
9766        lp.format = v.getBackground().getOpacity();
9767        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9768                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9769        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9770        ((WindowManager)mContext.getSystemService(
9771                Context.WINDOW_SERVICE)).addView(v, lp);
9772    }
9773
9774    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9775        if (!(sender instanceof PendingIntentRecord)) {
9776            return;
9777        }
9778        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9779        synchronized (stats) {
9780            if (mBatteryStatsService.isOnBattery()) {
9781                mBatteryStatsService.enforceCallingPermission();
9782                PendingIntentRecord rec = (PendingIntentRecord)sender;
9783                int MY_UID = Binder.getCallingUid();
9784                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9785                BatteryStatsImpl.Uid.Pkg pkg =
9786                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9787                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9788                pkg.incWakeupsLocked();
9789            }
9790        }
9791    }
9792
9793    public boolean killPids(int[] pids, String pReason, boolean secure) {
9794        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9795            throw new SecurityException("killPids only available to the system");
9796        }
9797        String reason = (pReason == null) ? "Unknown" : pReason;
9798        // XXX Note: don't acquire main activity lock here, because the window
9799        // manager calls in with its locks held.
9800
9801        boolean killed = false;
9802        synchronized (mPidsSelfLocked) {
9803            int[] types = new int[pids.length];
9804            int worstType = 0;
9805            for (int i=0; i<pids.length; i++) {
9806                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9807                if (proc != null) {
9808                    int type = proc.setAdj;
9809                    types[i] = type;
9810                    if (type > worstType) {
9811                        worstType = type;
9812                    }
9813                }
9814            }
9815
9816            // If the worst oom_adj is somewhere in the cached proc LRU range,
9817            // then constrain it so we will kill all cached procs.
9818            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9819                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9820                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9821            }
9822
9823            // If this is not a secure call, don't let it kill processes that
9824            // are important.
9825            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9826                worstType = ProcessList.SERVICE_ADJ;
9827            }
9828
9829            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9830            for (int i=0; i<pids.length; i++) {
9831                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9832                if (proc == null) {
9833                    continue;
9834                }
9835                int adj = proc.setAdj;
9836                if (adj >= worstType && !proc.killedByAm) {
9837                    killUnneededProcessLocked(proc, reason);
9838                    killed = true;
9839                }
9840            }
9841        }
9842        return killed;
9843    }
9844
9845    @Override
9846    public void killUid(int uid, String reason) {
9847        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9848            throw new SecurityException("killUid only available to the system");
9849        }
9850        synchronized (this) {
9851            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9852                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9853                    reason != null ? reason : "kill uid");
9854        }
9855    }
9856
9857    @Override
9858    public boolean killProcessesBelowForeground(String reason) {
9859        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9860            throw new SecurityException("killProcessesBelowForeground() only available to system");
9861        }
9862
9863        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9864    }
9865
9866    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9867        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9868            throw new SecurityException("killProcessesBelowAdj() only available to system");
9869        }
9870
9871        boolean killed = false;
9872        synchronized (mPidsSelfLocked) {
9873            final int size = mPidsSelfLocked.size();
9874            for (int i = 0; i < size; i++) {
9875                final int pid = mPidsSelfLocked.keyAt(i);
9876                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9877                if (proc == null) continue;
9878
9879                final int adj = proc.setAdj;
9880                if (adj > belowAdj && !proc.killedByAm) {
9881                    killUnneededProcessLocked(proc, reason);
9882                    killed = true;
9883                }
9884            }
9885        }
9886        return killed;
9887    }
9888
9889    @Override
9890    public void hang(final IBinder who, boolean allowRestart) {
9891        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9892                != PackageManager.PERMISSION_GRANTED) {
9893            throw new SecurityException("Requires permission "
9894                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9895        }
9896
9897        final IBinder.DeathRecipient death = new DeathRecipient() {
9898            @Override
9899            public void binderDied() {
9900                synchronized (this) {
9901                    notifyAll();
9902                }
9903            }
9904        };
9905
9906        try {
9907            who.linkToDeath(death, 0);
9908        } catch (RemoteException e) {
9909            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9910            return;
9911        }
9912
9913        synchronized (this) {
9914            Watchdog.getInstance().setAllowRestart(allowRestart);
9915            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9916            synchronized (death) {
9917                while (who.isBinderAlive()) {
9918                    try {
9919                        death.wait();
9920                    } catch (InterruptedException e) {
9921                    }
9922                }
9923            }
9924            Watchdog.getInstance().setAllowRestart(true);
9925        }
9926    }
9927
9928    @Override
9929    public void restart() {
9930        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9931                != PackageManager.PERMISSION_GRANTED) {
9932            throw new SecurityException("Requires permission "
9933                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9934        }
9935
9936        Log.i(TAG, "Sending shutdown broadcast...");
9937
9938        BroadcastReceiver br = new BroadcastReceiver() {
9939            @Override public void onReceive(Context context, Intent intent) {
9940                // Now the broadcast is done, finish up the low-level shutdown.
9941                Log.i(TAG, "Shutting down activity manager...");
9942                shutdown(10000);
9943                Log.i(TAG, "Shutdown complete, restarting!");
9944                Process.killProcess(Process.myPid());
9945                System.exit(10);
9946            }
9947        };
9948
9949        // First send the high-level shut down broadcast.
9950        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9951        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9952        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9953        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9954        mContext.sendOrderedBroadcastAsUser(intent,
9955                UserHandle.ALL, null, br, mHandler, 0, null, null);
9956        */
9957        br.onReceive(mContext, intent);
9958    }
9959
9960    private long getLowRamTimeSinceIdle(long now) {
9961        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9962    }
9963
9964    @Override
9965    public void performIdleMaintenance() {
9966        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9967                != PackageManager.PERMISSION_GRANTED) {
9968            throw new SecurityException("Requires permission "
9969                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9970        }
9971
9972        synchronized (this) {
9973            final long now = SystemClock.uptimeMillis();
9974            final long timeSinceLastIdle = now - mLastIdleTime;
9975            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9976            mLastIdleTime = now;
9977            mLowRamTimeSinceLastIdle = 0;
9978            if (mLowRamStartTime != 0) {
9979                mLowRamStartTime = now;
9980            }
9981
9982            StringBuilder sb = new StringBuilder(128);
9983            sb.append("Idle maintenance over ");
9984            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9985            sb.append(" low RAM for ");
9986            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9987            Slog.i(TAG, sb.toString());
9988
9989            // If at least 1/3 of our time since the last idle period has been spent
9990            // with RAM low, then we want to kill processes.
9991            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9992
9993            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9994                ProcessRecord proc = mLruProcesses.get(i);
9995                if (proc.notCachedSinceIdle) {
9996                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9997                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9998                        if (doKilling && proc.initialIdlePss != 0
9999                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10000                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
10001                                    + " from " + proc.initialIdlePss + ")");
10002                        }
10003                    }
10004                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10005                    proc.notCachedSinceIdle = true;
10006                    proc.initialIdlePss = 0;
10007                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10008                            isSleeping(), now);
10009                }
10010            }
10011
10012            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10013            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10014        }
10015    }
10016
10017    private void retrieveSettings() {
10018        final ContentResolver resolver = mContext.getContentResolver();
10019        String debugApp = Settings.Global.getString(
10020            resolver, Settings.Global.DEBUG_APP);
10021        boolean waitForDebugger = Settings.Global.getInt(
10022            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10023        boolean alwaysFinishActivities = Settings.Global.getInt(
10024            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10025        boolean forceRtl = Settings.Global.getInt(
10026                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10027        // Transfer any global setting for forcing RTL layout, into a System Property
10028        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10029
10030        Configuration configuration = new Configuration();
10031        Settings.System.getConfiguration(resolver, configuration);
10032        if (forceRtl) {
10033            // This will take care of setting the correct layout direction flags
10034            configuration.setLayoutDirection(configuration.locale);
10035        }
10036
10037        synchronized (this) {
10038            mDebugApp = mOrigDebugApp = debugApp;
10039            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10040            mAlwaysFinishActivities = alwaysFinishActivities;
10041            // This happens before any activities are started, so we can
10042            // change mConfiguration in-place.
10043            updateConfigurationLocked(configuration, null, false, true);
10044            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10045        }
10046    }
10047
10048    public boolean testIsSystemReady() {
10049        // no need to synchronize(this) just to read & return the value
10050        return mSystemReady;
10051    }
10052
10053    private static File getCalledPreBootReceiversFile() {
10054        File dataDir = Environment.getDataDirectory();
10055        File systemDir = new File(dataDir, "system");
10056        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10057        return fname;
10058    }
10059
10060    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10061        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10062        File file = getCalledPreBootReceiversFile();
10063        FileInputStream fis = null;
10064        try {
10065            fis = new FileInputStream(file);
10066            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10067            int fvers = dis.readInt();
10068            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10069                String vers = dis.readUTF();
10070                String codename = dis.readUTF();
10071                String build = dis.readUTF();
10072                if (android.os.Build.VERSION.RELEASE.equals(vers)
10073                        && android.os.Build.VERSION.CODENAME.equals(codename)
10074                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10075                    int num = dis.readInt();
10076                    while (num > 0) {
10077                        num--;
10078                        String pkg = dis.readUTF();
10079                        String cls = dis.readUTF();
10080                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10081                    }
10082                }
10083            }
10084        } catch (FileNotFoundException e) {
10085        } catch (IOException e) {
10086            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10087        } finally {
10088            if (fis != null) {
10089                try {
10090                    fis.close();
10091                } catch (IOException e) {
10092                }
10093            }
10094        }
10095        return lastDoneReceivers;
10096    }
10097
10098    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10099        File file = getCalledPreBootReceiversFile();
10100        FileOutputStream fos = null;
10101        DataOutputStream dos = null;
10102        try {
10103            fos = new FileOutputStream(file);
10104            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10105            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10106            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10107            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10108            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10109            dos.writeInt(list.size());
10110            for (int i=0; i<list.size(); i++) {
10111                dos.writeUTF(list.get(i).getPackageName());
10112                dos.writeUTF(list.get(i).getClassName());
10113            }
10114        } catch (IOException e) {
10115            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10116            file.delete();
10117        } finally {
10118            FileUtils.sync(fos);
10119            if (dos != null) {
10120                try {
10121                    dos.close();
10122                } catch (IOException e) {
10123                    // TODO Auto-generated catch block
10124                    e.printStackTrace();
10125                }
10126            }
10127        }
10128    }
10129
10130    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10131            ArrayList<ComponentName> doneReceivers, int userId) {
10132        boolean waitingUpdate = false;
10133        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10134        List<ResolveInfo> ris = null;
10135        try {
10136            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10137                    intent, null, 0, userId);
10138        } catch (RemoteException e) {
10139        }
10140        if (ris != null) {
10141            for (int i=ris.size()-1; i>=0; i--) {
10142                if ((ris.get(i).activityInfo.applicationInfo.flags
10143                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10144                    ris.remove(i);
10145                }
10146            }
10147            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10148
10149            // For User 0, load the version number. When delivering to a new user, deliver
10150            // to all receivers.
10151            if (userId == UserHandle.USER_OWNER) {
10152                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10153                for (int i=0; i<ris.size(); i++) {
10154                    ActivityInfo ai = ris.get(i).activityInfo;
10155                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10156                    if (lastDoneReceivers.contains(comp)) {
10157                        // We already did the pre boot receiver for this app with the current
10158                        // platform version, so don't do it again...
10159                        ris.remove(i);
10160                        i--;
10161                        // ...however, do keep it as one that has been done, so we don't
10162                        // forget about it when rewriting the file of last done receivers.
10163                        doneReceivers.add(comp);
10164                    }
10165                }
10166            }
10167
10168            // If primary user, send broadcast to all available users, else just to userId
10169            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10170                    : new int[] { userId };
10171            for (int i = 0; i < ris.size(); i++) {
10172                ActivityInfo ai = ris.get(i).activityInfo;
10173                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10174                doneReceivers.add(comp);
10175                intent.setComponent(comp);
10176                for (int j=0; j<users.length; j++) {
10177                    IIntentReceiver finisher = null;
10178                    // On last receiver and user, set up a completion callback
10179                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10180                        finisher = new IIntentReceiver.Stub() {
10181                            public void performReceive(Intent intent, int resultCode,
10182                                    String data, Bundle extras, boolean ordered,
10183                                    boolean sticky, int sendingUser) {
10184                                // The raw IIntentReceiver interface is called
10185                                // with the AM lock held, so redispatch to
10186                                // execute our code without the lock.
10187                                mHandler.post(onFinishCallback);
10188                            }
10189                        };
10190                    }
10191                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10192                            + " for user " + users[j]);
10193                    broadcastIntentLocked(null, null, intent, null, finisher,
10194                            0, null, null, null, AppOpsManager.OP_NONE,
10195                            true, false, MY_PID, Process.SYSTEM_UID,
10196                            users[j]);
10197                    if (finisher != null) {
10198                        waitingUpdate = true;
10199                    }
10200                }
10201            }
10202        }
10203
10204        return waitingUpdate;
10205    }
10206
10207    public void systemReady(final Runnable goingCallback) {
10208        synchronized(this) {
10209            if (mSystemReady) {
10210                // If we're done calling all the receivers, run the next "boot phase" passed in
10211                // by the SystemServer
10212                if (goingCallback != null) {
10213                    goingCallback.run();
10214                }
10215                return;
10216            }
10217
10218            // Make sure we have the current profile info, since it is needed for
10219            // security checks.
10220            updateCurrentProfileIdsLocked();
10221
10222            if (mRecentTasks == null) {
10223                mRecentTasks = mTaskPersister.restoreTasksLocked();
10224                if (!mRecentTasks.isEmpty()) {
10225                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10226                }
10227                mTaskPersister.startPersisting();
10228            }
10229
10230            // Check to see if there are any update receivers to run.
10231            if (!mDidUpdate) {
10232                if (mWaitingUpdate) {
10233                    return;
10234                }
10235                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10236                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10237                    public void run() {
10238                        synchronized (ActivityManagerService.this) {
10239                            mDidUpdate = true;
10240                        }
10241                        writeLastDonePreBootReceivers(doneReceivers);
10242                        showBootMessage(mContext.getText(
10243                                R.string.android_upgrading_complete),
10244                                false);
10245                        systemReady(goingCallback);
10246                    }
10247                }, doneReceivers, UserHandle.USER_OWNER);
10248
10249                if (mWaitingUpdate) {
10250                    return;
10251                }
10252                mDidUpdate = true;
10253            }
10254
10255            mAppOpsService.systemReady();
10256            mSystemReady = true;
10257        }
10258
10259        ArrayList<ProcessRecord> procsToKill = null;
10260        synchronized(mPidsSelfLocked) {
10261            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10262                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10263                if (!isAllowedWhileBooting(proc.info)){
10264                    if (procsToKill == null) {
10265                        procsToKill = new ArrayList<ProcessRecord>();
10266                    }
10267                    procsToKill.add(proc);
10268                }
10269            }
10270        }
10271
10272        synchronized(this) {
10273            if (procsToKill != null) {
10274                for (int i=procsToKill.size()-1; i>=0; i--) {
10275                    ProcessRecord proc = procsToKill.get(i);
10276                    Slog.i(TAG, "Removing system update proc: " + proc);
10277                    removeProcessLocked(proc, true, false, "system update done");
10278                }
10279            }
10280
10281            // Now that we have cleaned up any update processes, we
10282            // are ready to start launching real processes and know that
10283            // we won't trample on them any more.
10284            mProcessesReady = true;
10285        }
10286
10287        Slog.i(TAG, "System now ready");
10288        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10289            SystemClock.uptimeMillis());
10290
10291        synchronized(this) {
10292            // Make sure we have no pre-ready processes sitting around.
10293
10294            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10295                ResolveInfo ri = mContext.getPackageManager()
10296                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10297                                STOCK_PM_FLAGS);
10298                CharSequence errorMsg = null;
10299                if (ri != null) {
10300                    ActivityInfo ai = ri.activityInfo;
10301                    ApplicationInfo app = ai.applicationInfo;
10302                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10303                        mTopAction = Intent.ACTION_FACTORY_TEST;
10304                        mTopData = null;
10305                        mTopComponent = new ComponentName(app.packageName,
10306                                ai.name);
10307                    } else {
10308                        errorMsg = mContext.getResources().getText(
10309                                com.android.internal.R.string.factorytest_not_system);
10310                    }
10311                } else {
10312                    errorMsg = mContext.getResources().getText(
10313                            com.android.internal.R.string.factorytest_no_action);
10314                }
10315                if (errorMsg != null) {
10316                    mTopAction = null;
10317                    mTopData = null;
10318                    mTopComponent = null;
10319                    Message msg = Message.obtain();
10320                    msg.what = SHOW_FACTORY_ERROR_MSG;
10321                    msg.getData().putCharSequence("msg", errorMsg);
10322                    mHandler.sendMessage(msg);
10323                }
10324            }
10325        }
10326
10327        retrieveSettings();
10328
10329        synchronized (this) {
10330            readGrantedUriPermissionsLocked();
10331        }
10332
10333        if (goingCallback != null) goingCallback.run();
10334
10335        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10336                Integer.toString(mCurrentUserId), mCurrentUserId);
10337        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10338                Integer.toString(mCurrentUserId), mCurrentUserId);
10339        mSystemServiceManager.startUser(mCurrentUserId);
10340
10341        synchronized (this) {
10342            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10343                try {
10344                    List apps = AppGlobals.getPackageManager().
10345                        getPersistentApplications(STOCK_PM_FLAGS);
10346                    if (apps != null) {
10347                        int N = apps.size();
10348                        int i;
10349                        for (i=0; i<N; i++) {
10350                            ApplicationInfo info
10351                                = (ApplicationInfo)apps.get(i);
10352                            if (info != null &&
10353                                    !info.packageName.equals("android")) {
10354                                addAppLocked(info, false, null /* ABI override */);
10355                            }
10356                        }
10357                    }
10358                } catch (RemoteException ex) {
10359                    // pm is in same process, this will never happen.
10360                }
10361            }
10362
10363            // Start up initial activity.
10364            mBooting = true;
10365
10366            try {
10367                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10368                    Message msg = Message.obtain();
10369                    msg.what = SHOW_UID_ERROR_MSG;
10370                    mHandler.sendMessage(msg);
10371                }
10372            } catch (RemoteException e) {
10373            }
10374
10375            long ident = Binder.clearCallingIdentity();
10376            try {
10377                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10378                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10379                        | Intent.FLAG_RECEIVER_FOREGROUND);
10380                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10381                broadcastIntentLocked(null, null, intent,
10382                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10383                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10384                intent = new Intent(Intent.ACTION_USER_STARTING);
10385                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10386                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10387                broadcastIntentLocked(null, null, intent,
10388                        null, new IIntentReceiver.Stub() {
10389                            @Override
10390                            public void performReceive(Intent intent, int resultCode, String data,
10391                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10392                                    throws RemoteException {
10393                            }
10394                        }, 0, null, null,
10395                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10396                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10397            } catch (Throwable t) {
10398                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10399            } finally {
10400                Binder.restoreCallingIdentity(ident);
10401            }
10402            mStackSupervisor.resumeTopActivitiesLocked();
10403            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10404        }
10405    }
10406
10407    private boolean makeAppCrashingLocked(ProcessRecord app,
10408            String shortMsg, String longMsg, String stackTrace) {
10409        app.crashing = true;
10410        app.crashingReport = generateProcessError(app,
10411                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10412        startAppProblemLocked(app);
10413        app.stopFreezingAllLocked();
10414        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10415    }
10416
10417    private void makeAppNotRespondingLocked(ProcessRecord app,
10418            String activity, String shortMsg, String longMsg) {
10419        app.notResponding = true;
10420        app.notRespondingReport = generateProcessError(app,
10421                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10422                activity, shortMsg, longMsg, null);
10423        startAppProblemLocked(app);
10424        app.stopFreezingAllLocked();
10425    }
10426
10427    /**
10428     * Generate a process error record, suitable for attachment to a ProcessRecord.
10429     *
10430     * @param app The ProcessRecord in which the error occurred.
10431     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10432     *                      ActivityManager.AppErrorStateInfo
10433     * @param activity The activity associated with the crash, if known.
10434     * @param shortMsg Short message describing the crash.
10435     * @param longMsg Long message describing the crash.
10436     * @param stackTrace Full crash stack trace, may be null.
10437     *
10438     * @return Returns a fully-formed AppErrorStateInfo record.
10439     */
10440    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10441            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10442        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10443
10444        report.condition = condition;
10445        report.processName = app.processName;
10446        report.pid = app.pid;
10447        report.uid = app.info.uid;
10448        report.tag = activity;
10449        report.shortMsg = shortMsg;
10450        report.longMsg = longMsg;
10451        report.stackTrace = stackTrace;
10452
10453        return report;
10454    }
10455
10456    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10457        synchronized (this) {
10458            app.crashing = false;
10459            app.crashingReport = null;
10460            app.notResponding = false;
10461            app.notRespondingReport = null;
10462            if (app.anrDialog == fromDialog) {
10463                app.anrDialog = null;
10464            }
10465            if (app.waitDialog == fromDialog) {
10466                app.waitDialog = null;
10467            }
10468            if (app.pid > 0 && app.pid != MY_PID) {
10469                handleAppCrashLocked(app, null, null, null);
10470                killUnneededProcessLocked(app, "user request after error");
10471            }
10472        }
10473    }
10474
10475    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10476            String stackTrace) {
10477        long now = SystemClock.uptimeMillis();
10478
10479        Long crashTime;
10480        if (!app.isolated) {
10481            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10482        } else {
10483            crashTime = null;
10484        }
10485        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10486            // This process loses!
10487            Slog.w(TAG, "Process " + app.info.processName
10488                    + " has crashed too many times: killing!");
10489            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10490                    app.userId, app.info.processName, app.uid);
10491            mStackSupervisor.handleAppCrashLocked(app);
10492            if (!app.persistent) {
10493                // We don't want to start this process again until the user
10494                // explicitly does so...  but for persistent process, we really
10495                // need to keep it running.  If a persistent process is actually
10496                // repeatedly crashing, then badness for everyone.
10497                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10498                        app.info.processName);
10499                if (!app.isolated) {
10500                    // XXX We don't have a way to mark isolated processes
10501                    // as bad, since they don't have a peristent identity.
10502                    mBadProcesses.put(app.info.processName, app.uid,
10503                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10504                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10505                }
10506                app.bad = true;
10507                app.removed = true;
10508                // Don't let services in this process be restarted and potentially
10509                // annoy the user repeatedly.  Unless it is persistent, since those
10510                // processes run critical code.
10511                removeProcessLocked(app, false, false, "crash");
10512                mStackSupervisor.resumeTopActivitiesLocked();
10513                return false;
10514            }
10515            mStackSupervisor.resumeTopActivitiesLocked();
10516        } else {
10517            mStackSupervisor.finishTopRunningActivityLocked(app);
10518        }
10519
10520        // Bump up the crash count of any services currently running in the proc.
10521        for (int i=app.services.size()-1; i>=0; i--) {
10522            // Any services running in the application need to be placed
10523            // back in the pending list.
10524            ServiceRecord sr = app.services.valueAt(i);
10525            sr.crashCount++;
10526        }
10527
10528        // If the crashing process is what we consider to be the "home process" and it has been
10529        // replaced by a third-party app, clear the package preferred activities from packages
10530        // with a home activity running in the process to prevent a repeatedly crashing app
10531        // from blocking the user to manually clear the list.
10532        final ArrayList<ActivityRecord> activities = app.activities;
10533        if (app == mHomeProcess && activities.size() > 0
10534                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10535            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10536                final ActivityRecord r = activities.get(activityNdx);
10537                if (r.isHomeActivity()) {
10538                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10539                    try {
10540                        ActivityThread.getPackageManager()
10541                                .clearPackagePreferredActivities(r.packageName);
10542                    } catch (RemoteException c) {
10543                        // pm is in same process, this will never happen.
10544                    }
10545                }
10546            }
10547        }
10548
10549        if (!app.isolated) {
10550            // XXX Can't keep track of crash times for isolated processes,
10551            // because they don't have a perisistent identity.
10552            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10553        }
10554
10555        if (app.crashHandler != null) mHandler.post(app.crashHandler);
10556        return true;
10557    }
10558
10559    void startAppProblemLocked(ProcessRecord app) {
10560        if (app.userId == mCurrentUserId) {
10561            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10562                    mContext, app.info.packageName, app.info.flags);
10563        } else {
10564            // If this app is not running under the current user, then we
10565            // can't give it a report button because that would require
10566            // launching the report UI under a different user.
10567            app.errorReportReceiver = null;
10568        }
10569        skipCurrentReceiverLocked(app);
10570    }
10571
10572    void skipCurrentReceiverLocked(ProcessRecord app) {
10573        for (BroadcastQueue queue : mBroadcastQueues) {
10574            queue.skipCurrentReceiverLocked(app);
10575        }
10576    }
10577
10578    /**
10579     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10580     * The application process will exit immediately after this call returns.
10581     * @param app object of the crashing app, null for the system server
10582     * @param crashInfo describing the exception
10583     */
10584    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10585        ProcessRecord r = findAppProcess(app, "Crash");
10586        final String processName = app == null ? "system_server"
10587                : (r == null ? "unknown" : r.processName);
10588
10589        handleApplicationCrashInner("crash", r, processName, crashInfo);
10590    }
10591
10592    /* Native crash reporting uses this inner version because it needs to be somewhat
10593     * decoupled from the AM-managed cleanup lifecycle
10594     */
10595    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10596            ApplicationErrorReport.CrashInfo crashInfo) {
10597        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10598                UserHandle.getUserId(Binder.getCallingUid()), processName,
10599                r == null ? -1 : r.info.flags,
10600                crashInfo.exceptionClassName,
10601                crashInfo.exceptionMessage,
10602                crashInfo.throwFileName,
10603                crashInfo.throwLineNumber);
10604
10605        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10606
10607        crashApplication(r, crashInfo);
10608    }
10609
10610    public void handleApplicationStrictModeViolation(
10611            IBinder app,
10612            int violationMask,
10613            StrictMode.ViolationInfo info) {
10614        ProcessRecord r = findAppProcess(app, "StrictMode");
10615        if (r == null) {
10616            return;
10617        }
10618
10619        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10620            Integer stackFingerprint = info.hashCode();
10621            boolean logIt = true;
10622            synchronized (mAlreadyLoggedViolatedStacks) {
10623                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10624                    logIt = false;
10625                    // TODO: sub-sample into EventLog for these, with
10626                    // the info.durationMillis?  Then we'd get
10627                    // the relative pain numbers, without logging all
10628                    // the stack traces repeatedly.  We'd want to do
10629                    // likewise in the client code, which also does
10630                    // dup suppression, before the Binder call.
10631                } else {
10632                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10633                        mAlreadyLoggedViolatedStacks.clear();
10634                    }
10635                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10636                }
10637            }
10638            if (logIt) {
10639                logStrictModeViolationToDropBox(r, info);
10640            }
10641        }
10642
10643        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10644            AppErrorResult result = new AppErrorResult();
10645            synchronized (this) {
10646                final long origId = Binder.clearCallingIdentity();
10647
10648                Message msg = Message.obtain();
10649                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10650                HashMap<String, Object> data = new HashMap<String, Object>();
10651                data.put("result", result);
10652                data.put("app", r);
10653                data.put("violationMask", violationMask);
10654                data.put("info", info);
10655                msg.obj = data;
10656                mHandler.sendMessage(msg);
10657
10658                Binder.restoreCallingIdentity(origId);
10659            }
10660            int res = result.get();
10661            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10662        }
10663    }
10664
10665    // Depending on the policy in effect, there could be a bunch of
10666    // these in quick succession so we try to batch these together to
10667    // minimize disk writes, number of dropbox entries, and maximize
10668    // compression, by having more fewer, larger records.
10669    private void logStrictModeViolationToDropBox(
10670            ProcessRecord process,
10671            StrictMode.ViolationInfo info) {
10672        if (info == null) {
10673            return;
10674        }
10675        final boolean isSystemApp = process == null ||
10676                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10677                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10678        final String processName = process == null ? "unknown" : process.processName;
10679        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10680        final DropBoxManager dbox = (DropBoxManager)
10681                mContext.getSystemService(Context.DROPBOX_SERVICE);
10682
10683        // Exit early if the dropbox isn't configured to accept this report type.
10684        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10685
10686        boolean bufferWasEmpty;
10687        boolean needsFlush;
10688        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10689        synchronized (sb) {
10690            bufferWasEmpty = sb.length() == 0;
10691            appendDropBoxProcessHeaders(process, processName, sb);
10692            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10693            sb.append("System-App: ").append(isSystemApp).append("\n");
10694            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10695            if (info.violationNumThisLoop != 0) {
10696                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10697            }
10698            if (info.numAnimationsRunning != 0) {
10699                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10700            }
10701            if (info.broadcastIntentAction != null) {
10702                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10703            }
10704            if (info.durationMillis != -1) {
10705                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10706            }
10707            if (info.numInstances != -1) {
10708                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10709            }
10710            if (info.tags != null) {
10711                for (String tag : info.tags) {
10712                    sb.append("Span-Tag: ").append(tag).append("\n");
10713                }
10714            }
10715            sb.append("\n");
10716            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10717                sb.append(info.crashInfo.stackTrace);
10718            }
10719            sb.append("\n");
10720
10721            // Only buffer up to ~64k.  Various logging bits truncate
10722            // things at 128k.
10723            needsFlush = (sb.length() > 64 * 1024);
10724        }
10725
10726        // Flush immediately if the buffer's grown too large, or this
10727        // is a non-system app.  Non-system apps are isolated with a
10728        // different tag & policy and not batched.
10729        //
10730        // Batching is useful during internal testing with
10731        // StrictMode settings turned up high.  Without batching,
10732        // thousands of separate files could be created on boot.
10733        if (!isSystemApp || needsFlush) {
10734            new Thread("Error dump: " + dropboxTag) {
10735                @Override
10736                public void run() {
10737                    String report;
10738                    synchronized (sb) {
10739                        report = sb.toString();
10740                        sb.delete(0, sb.length());
10741                        sb.trimToSize();
10742                    }
10743                    if (report.length() != 0) {
10744                        dbox.addText(dropboxTag, report);
10745                    }
10746                }
10747            }.start();
10748            return;
10749        }
10750
10751        // System app batching:
10752        if (!bufferWasEmpty) {
10753            // An existing dropbox-writing thread is outstanding, so
10754            // we don't need to start it up.  The existing thread will
10755            // catch the buffer appends we just did.
10756            return;
10757        }
10758
10759        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10760        // (After this point, we shouldn't access AMS internal data structures.)
10761        new Thread("Error dump: " + dropboxTag) {
10762            @Override
10763            public void run() {
10764                // 5 second sleep to let stacks arrive and be batched together
10765                try {
10766                    Thread.sleep(5000);  // 5 seconds
10767                } catch (InterruptedException e) {}
10768
10769                String errorReport;
10770                synchronized (mStrictModeBuffer) {
10771                    errorReport = mStrictModeBuffer.toString();
10772                    if (errorReport.length() == 0) {
10773                        return;
10774                    }
10775                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10776                    mStrictModeBuffer.trimToSize();
10777                }
10778                dbox.addText(dropboxTag, errorReport);
10779            }
10780        }.start();
10781    }
10782
10783    /**
10784     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10785     * @param app object of the crashing app, null for the system server
10786     * @param tag reported by the caller
10787     * @param crashInfo describing the context of the error
10788     * @return true if the process should exit immediately (WTF is fatal)
10789     */
10790    public boolean handleApplicationWtf(IBinder app, String tag,
10791            ApplicationErrorReport.CrashInfo crashInfo) {
10792        ProcessRecord r = findAppProcess(app, "WTF");
10793        final String processName = app == null ? "system_server"
10794                : (r == null ? "unknown" : r.processName);
10795
10796        EventLog.writeEvent(EventLogTags.AM_WTF,
10797                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10798                processName,
10799                r == null ? -1 : r.info.flags,
10800                tag, crashInfo.exceptionMessage);
10801
10802        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10803
10804        if (r != null && r.pid != Process.myPid() &&
10805                Settings.Global.getInt(mContext.getContentResolver(),
10806                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10807            crashApplication(r, crashInfo);
10808            return true;
10809        } else {
10810            return false;
10811        }
10812    }
10813
10814    /**
10815     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10816     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10817     */
10818    private ProcessRecord findAppProcess(IBinder app, String reason) {
10819        if (app == null) {
10820            return null;
10821        }
10822
10823        synchronized (this) {
10824            final int NP = mProcessNames.getMap().size();
10825            for (int ip=0; ip<NP; ip++) {
10826                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10827                final int NA = apps.size();
10828                for (int ia=0; ia<NA; ia++) {
10829                    ProcessRecord p = apps.valueAt(ia);
10830                    if (p.thread != null && p.thread.asBinder() == app) {
10831                        return p;
10832                    }
10833                }
10834            }
10835
10836            Slog.w(TAG, "Can't find mystery application for " + reason
10837                    + " from pid=" + Binder.getCallingPid()
10838                    + " uid=" + Binder.getCallingUid() + ": " + app);
10839            return null;
10840        }
10841    }
10842
10843    /**
10844     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10845     * to append various headers to the dropbox log text.
10846     */
10847    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10848            StringBuilder sb) {
10849        // Watchdog thread ends up invoking this function (with
10850        // a null ProcessRecord) to add the stack file to dropbox.
10851        // Do not acquire a lock on this (am) in such cases, as it
10852        // could cause a potential deadlock, if and when watchdog
10853        // is invoked due to unavailability of lock on am and it
10854        // would prevent watchdog from killing system_server.
10855        if (process == null) {
10856            sb.append("Process: ").append(processName).append("\n");
10857            return;
10858        }
10859        // Note: ProcessRecord 'process' is guarded by the service
10860        // instance.  (notably process.pkgList, which could otherwise change
10861        // concurrently during execution of this method)
10862        synchronized (this) {
10863            sb.append("Process: ").append(processName).append("\n");
10864            int flags = process.info.flags;
10865            IPackageManager pm = AppGlobals.getPackageManager();
10866            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10867            for (int ip=0; ip<process.pkgList.size(); ip++) {
10868                String pkg = process.pkgList.keyAt(ip);
10869                sb.append("Package: ").append(pkg);
10870                try {
10871                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10872                    if (pi != null) {
10873                        sb.append(" v").append(pi.versionCode);
10874                        if (pi.versionName != null) {
10875                            sb.append(" (").append(pi.versionName).append(")");
10876                        }
10877                    }
10878                } catch (RemoteException e) {
10879                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10880                }
10881                sb.append("\n");
10882            }
10883        }
10884    }
10885
10886    private static String processClass(ProcessRecord process) {
10887        if (process == null || process.pid == MY_PID) {
10888            return "system_server";
10889        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10890            return "system_app";
10891        } else {
10892            return "data_app";
10893        }
10894    }
10895
10896    /**
10897     * Write a description of an error (crash, WTF, ANR) to the drop box.
10898     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10899     * @param process which caused the error, null means the system server
10900     * @param activity which triggered the error, null if unknown
10901     * @param parent activity related to the error, null if unknown
10902     * @param subject line related to the error, null if absent
10903     * @param report in long form describing the error, null if absent
10904     * @param logFile to include in the report, null if none
10905     * @param crashInfo giving an application stack trace, null if absent
10906     */
10907    public void addErrorToDropBox(String eventType,
10908            ProcessRecord process, String processName, ActivityRecord activity,
10909            ActivityRecord parent, String subject,
10910            final String report, final File logFile,
10911            final ApplicationErrorReport.CrashInfo crashInfo) {
10912        // NOTE -- this must never acquire the ActivityManagerService lock,
10913        // otherwise the watchdog may be prevented from resetting the system.
10914
10915        final String dropboxTag = processClass(process) + "_" + eventType;
10916        final DropBoxManager dbox = (DropBoxManager)
10917                mContext.getSystemService(Context.DROPBOX_SERVICE);
10918
10919        // Exit early if the dropbox isn't configured to accept this report type.
10920        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10921
10922        final StringBuilder sb = new StringBuilder(1024);
10923        appendDropBoxProcessHeaders(process, processName, sb);
10924        if (activity != null) {
10925            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10926        }
10927        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10928            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10929        }
10930        if (parent != null && parent != activity) {
10931            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10932        }
10933        if (subject != null) {
10934            sb.append("Subject: ").append(subject).append("\n");
10935        }
10936        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10937        if (Debug.isDebuggerConnected()) {
10938            sb.append("Debugger: Connected\n");
10939        }
10940        sb.append("\n");
10941
10942        // Do the rest in a worker thread to avoid blocking the caller on I/O
10943        // (After this point, we shouldn't access AMS internal data structures.)
10944        Thread worker = new Thread("Error dump: " + dropboxTag) {
10945            @Override
10946            public void run() {
10947                if (report != null) {
10948                    sb.append(report);
10949                }
10950                if (logFile != null) {
10951                    try {
10952                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10953                                    "\n\n[[TRUNCATED]]"));
10954                    } catch (IOException e) {
10955                        Slog.e(TAG, "Error reading " + logFile, e);
10956                    }
10957                }
10958                if (crashInfo != null && crashInfo.stackTrace != null) {
10959                    sb.append(crashInfo.stackTrace);
10960                }
10961
10962                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10963                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10964                if (lines > 0) {
10965                    sb.append("\n");
10966
10967                    // Merge several logcat streams, and take the last N lines
10968                    InputStreamReader input = null;
10969                    try {
10970                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10971                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10972                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10973
10974                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10975                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10976                        input = new InputStreamReader(logcat.getInputStream());
10977
10978                        int num;
10979                        char[] buf = new char[8192];
10980                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10981                    } catch (IOException e) {
10982                        Slog.e(TAG, "Error running logcat", e);
10983                    } finally {
10984                        if (input != null) try { input.close(); } catch (IOException e) {}
10985                    }
10986                }
10987
10988                dbox.addText(dropboxTag, sb.toString());
10989            }
10990        };
10991
10992        if (process == null) {
10993            // If process is null, we are being called from some internal code
10994            // and may be about to die -- run this synchronously.
10995            worker.run();
10996        } else {
10997            worker.start();
10998        }
10999    }
11000
11001    /**
11002     * Bring up the "unexpected error" dialog box for a crashing app.
11003     * Deal with edge cases (intercepts from instrumented applications,
11004     * ActivityController, error intent receivers, that sort of thing).
11005     * @param r the application crashing
11006     * @param crashInfo describing the failure
11007     */
11008    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11009        long timeMillis = System.currentTimeMillis();
11010        String shortMsg = crashInfo.exceptionClassName;
11011        String longMsg = crashInfo.exceptionMessage;
11012        String stackTrace = crashInfo.stackTrace;
11013        if (shortMsg != null && longMsg != null) {
11014            longMsg = shortMsg + ": " + longMsg;
11015        } else if (shortMsg != null) {
11016            longMsg = shortMsg;
11017        }
11018
11019        AppErrorResult result = new AppErrorResult();
11020        synchronized (this) {
11021            if (mController != null) {
11022                try {
11023                    String name = r != null ? r.processName : null;
11024                    int pid = r != null ? r.pid : Binder.getCallingPid();
11025                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11026                    if (!mController.appCrashed(name, pid,
11027                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11028                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11029                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11030                            Slog.w(TAG, "Skip killing native crashed app " + name
11031                                    + "(" + pid + ") during testing");
11032                        } else {
11033                            Slog.w(TAG, "Force-killing crashed app " + name
11034                                    + " at watcher's request");
11035                            Process.killProcess(pid);
11036                            if (r != null) {
11037                                Process.killProcessGroup(uid, pid);
11038                            }
11039                        }
11040                        return;
11041                    }
11042                } catch (RemoteException e) {
11043                    mController = null;
11044                    Watchdog.getInstance().setActivityController(null);
11045                }
11046            }
11047
11048            final long origId = Binder.clearCallingIdentity();
11049
11050            // If this process is running instrumentation, finish it.
11051            if (r != null && r.instrumentationClass != null) {
11052                Slog.w(TAG, "Error in app " + r.processName
11053                      + " running instrumentation " + r.instrumentationClass + ":");
11054                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11055                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11056                Bundle info = new Bundle();
11057                info.putString("shortMsg", shortMsg);
11058                info.putString("longMsg", longMsg);
11059                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11060                Binder.restoreCallingIdentity(origId);
11061                return;
11062            }
11063
11064            // If we can't identify the process or it's already exceeded its crash quota,
11065            // quit right away without showing a crash dialog.
11066            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11067                Binder.restoreCallingIdentity(origId);
11068                return;
11069            }
11070
11071            Message msg = Message.obtain();
11072            msg.what = SHOW_ERROR_MSG;
11073            HashMap data = new HashMap();
11074            data.put("result", result);
11075            data.put("app", r);
11076            msg.obj = data;
11077            mHandler.sendMessage(msg);
11078
11079            Binder.restoreCallingIdentity(origId);
11080        }
11081
11082        int res = result.get();
11083
11084        Intent appErrorIntent = null;
11085        synchronized (this) {
11086            if (r != null && !r.isolated) {
11087                // XXX Can't keep track of crash time for isolated processes,
11088                // since they don't have a persistent identity.
11089                mProcessCrashTimes.put(r.info.processName, r.uid,
11090                        SystemClock.uptimeMillis());
11091            }
11092            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11093                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11094            }
11095        }
11096
11097        if (appErrorIntent != null) {
11098            try {
11099                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11100            } catch (ActivityNotFoundException e) {
11101                Slog.w(TAG, "bug report receiver dissappeared", e);
11102            }
11103        }
11104    }
11105
11106    Intent createAppErrorIntentLocked(ProcessRecord r,
11107            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11108        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11109        if (report == null) {
11110            return null;
11111        }
11112        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11113        result.setComponent(r.errorReportReceiver);
11114        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11115        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11116        return result;
11117    }
11118
11119    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11120            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11121        if (r.errorReportReceiver == null) {
11122            return null;
11123        }
11124
11125        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11126            return null;
11127        }
11128
11129        ApplicationErrorReport report = new ApplicationErrorReport();
11130        report.packageName = r.info.packageName;
11131        report.installerPackageName = r.errorReportReceiver.getPackageName();
11132        report.processName = r.processName;
11133        report.time = timeMillis;
11134        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11135
11136        if (r.crashing || r.forceCrashReport) {
11137            report.type = ApplicationErrorReport.TYPE_CRASH;
11138            report.crashInfo = crashInfo;
11139        } else if (r.notResponding) {
11140            report.type = ApplicationErrorReport.TYPE_ANR;
11141            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11142
11143            report.anrInfo.activity = r.notRespondingReport.tag;
11144            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11145            report.anrInfo.info = r.notRespondingReport.longMsg;
11146        }
11147
11148        return report;
11149    }
11150
11151    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11152        enforceNotIsolatedCaller("getProcessesInErrorState");
11153        // assume our apps are happy - lazy create the list
11154        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11155
11156        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11157                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11158        int userId = UserHandle.getUserId(Binder.getCallingUid());
11159
11160        synchronized (this) {
11161
11162            // iterate across all processes
11163            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11164                ProcessRecord app = mLruProcesses.get(i);
11165                if (!allUsers && app.userId != userId) {
11166                    continue;
11167                }
11168                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11169                    // This one's in trouble, so we'll generate a report for it
11170                    // crashes are higher priority (in case there's a crash *and* an anr)
11171                    ActivityManager.ProcessErrorStateInfo report = null;
11172                    if (app.crashing) {
11173                        report = app.crashingReport;
11174                    } else if (app.notResponding) {
11175                        report = app.notRespondingReport;
11176                    }
11177
11178                    if (report != null) {
11179                        if (errList == null) {
11180                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11181                        }
11182                        errList.add(report);
11183                    } else {
11184                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11185                                " crashing = " + app.crashing +
11186                                " notResponding = " + app.notResponding);
11187                    }
11188                }
11189            }
11190        }
11191
11192        return errList;
11193    }
11194
11195    static int procStateToImportance(int procState, int memAdj,
11196            ActivityManager.RunningAppProcessInfo currApp) {
11197        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11198        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11199            currApp.lru = memAdj;
11200        } else {
11201            currApp.lru = 0;
11202        }
11203        return imp;
11204    }
11205
11206    private void fillInProcMemInfo(ProcessRecord app,
11207            ActivityManager.RunningAppProcessInfo outInfo) {
11208        outInfo.pid = app.pid;
11209        outInfo.uid = app.info.uid;
11210        if (mHeavyWeightProcess == app) {
11211            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11212        }
11213        if (app.persistent) {
11214            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11215        }
11216        if (app.activities.size() > 0) {
11217            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11218        }
11219        outInfo.lastTrimLevel = app.trimMemoryLevel;
11220        int adj = app.curAdj;
11221        int procState = app.curProcState;
11222        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11223        outInfo.importanceReasonCode = app.adjTypeCode;
11224        outInfo.processState = app.curProcState;
11225    }
11226
11227    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11228        enforceNotIsolatedCaller("getRunningAppProcesses");
11229        // Lazy instantiation of list
11230        List<ActivityManager.RunningAppProcessInfo> runList = null;
11231        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11232                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11233        int userId = UserHandle.getUserId(Binder.getCallingUid());
11234        synchronized (this) {
11235            // Iterate across all processes
11236            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11237                ProcessRecord app = mLruProcesses.get(i);
11238                if (!allUsers && app.userId != userId) {
11239                    continue;
11240                }
11241                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11242                    // Generate process state info for running application
11243                    ActivityManager.RunningAppProcessInfo currApp =
11244                        new ActivityManager.RunningAppProcessInfo(app.processName,
11245                                app.pid, app.getPackageList());
11246                    fillInProcMemInfo(app, currApp);
11247                    if (app.adjSource instanceof ProcessRecord) {
11248                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11249                        currApp.importanceReasonImportance =
11250                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11251                                        app.adjSourceProcState);
11252                    } else if (app.adjSource instanceof ActivityRecord) {
11253                        ActivityRecord r = (ActivityRecord)app.adjSource;
11254                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11255                    }
11256                    if (app.adjTarget instanceof ComponentName) {
11257                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11258                    }
11259                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11260                    //        + " lru=" + currApp.lru);
11261                    if (runList == null) {
11262                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11263                    }
11264                    runList.add(currApp);
11265                }
11266            }
11267        }
11268        return runList;
11269    }
11270
11271    public List<ApplicationInfo> getRunningExternalApplications() {
11272        enforceNotIsolatedCaller("getRunningExternalApplications");
11273        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11274        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11275        if (runningApps != null && runningApps.size() > 0) {
11276            Set<String> extList = new HashSet<String>();
11277            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11278                if (app.pkgList != null) {
11279                    for (String pkg : app.pkgList) {
11280                        extList.add(pkg);
11281                    }
11282                }
11283            }
11284            IPackageManager pm = AppGlobals.getPackageManager();
11285            for (String pkg : extList) {
11286                try {
11287                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11288                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11289                        retList.add(info);
11290                    }
11291                } catch (RemoteException e) {
11292                }
11293            }
11294        }
11295        return retList;
11296    }
11297
11298    @Override
11299    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11300        enforceNotIsolatedCaller("getMyMemoryState");
11301        synchronized (this) {
11302            ProcessRecord proc;
11303            synchronized (mPidsSelfLocked) {
11304                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11305            }
11306            fillInProcMemInfo(proc, outInfo);
11307        }
11308    }
11309
11310    @Override
11311    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11312        if (checkCallingPermission(android.Manifest.permission.DUMP)
11313                != PackageManager.PERMISSION_GRANTED) {
11314            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11315                    + Binder.getCallingPid()
11316                    + ", uid=" + Binder.getCallingUid()
11317                    + " without permission "
11318                    + android.Manifest.permission.DUMP);
11319            return;
11320        }
11321
11322        boolean dumpAll = false;
11323        boolean dumpClient = false;
11324        String dumpPackage = null;
11325
11326        int opti = 0;
11327        while (opti < args.length) {
11328            String opt = args[opti];
11329            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11330                break;
11331            }
11332            opti++;
11333            if ("-a".equals(opt)) {
11334                dumpAll = true;
11335            } else if ("-c".equals(opt)) {
11336                dumpClient = true;
11337            } else if ("-h".equals(opt)) {
11338                pw.println("Activity manager dump options:");
11339                pw.println("  [-a] [-c] [-h] [cmd] ...");
11340                pw.println("  cmd may be one of:");
11341                pw.println("    a[ctivities]: activity stack state");
11342                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11343                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11344                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11345                pw.println("    o[om]: out of memory management");
11346                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11347                pw.println("    provider [COMP_SPEC]: provider client-side state");
11348                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11349                pw.println("    service [COMP_SPEC]: service client-side state");
11350                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11351                pw.println("    all: dump all activities");
11352                pw.println("    top: dump the top activity");
11353                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11354                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11355                pw.println("    a partial substring in a component name, a");
11356                pw.println("    hex object identifier.");
11357                pw.println("  -a: include all available server state.");
11358                pw.println("  -c: include client state.");
11359                return;
11360            } else {
11361                pw.println("Unknown argument: " + opt + "; use -h for help");
11362            }
11363        }
11364
11365        long origId = Binder.clearCallingIdentity();
11366        boolean more = false;
11367        // Is the caller requesting to dump a particular piece of data?
11368        if (opti < args.length) {
11369            String cmd = args[opti];
11370            opti++;
11371            if ("activities".equals(cmd) || "a".equals(cmd)) {
11372                synchronized (this) {
11373                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11374                }
11375            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11376                String[] newArgs;
11377                String name;
11378                if (opti >= args.length) {
11379                    name = null;
11380                    newArgs = EMPTY_STRING_ARRAY;
11381                } else {
11382                    name = args[opti];
11383                    opti++;
11384                    newArgs = new String[args.length - opti];
11385                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11386                            args.length - opti);
11387                }
11388                synchronized (this) {
11389                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11390                }
11391            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11392                String[] newArgs;
11393                String name;
11394                if (opti >= args.length) {
11395                    name = null;
11396                    newArgs = EMPTY_STRING_ARRAY;
11397                } else {
11398                    name = args[opti];
11399                    opti++;
11400                    newArgs = new String[args.length - opti];
11401                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11402                            args.length - opti);
11403                }
11404                synchronized (this) {
11405                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11406                }
11407            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11408                String[] newArgs;
11409                String name;
11410                if (opti >= args.length) {
11411                    name = null;
11412                    newArgs = EMPTY_STRING_ARRAY;
11413                } else {
11414                    name = args[opti];
11415                    opti++;
11416                    newArgs = new String[args.length - opti];
11417                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11418                            args.length - opti);
11419                }
11420                synchronized (this) {
11421                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11422                }
11423            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11424                synchronized (this) {
11425                    dumpOomLocked(fd, pw, args, opti, true);
11426                }
11427            } else if ("provider".equals(cmd)) {
11428                String[] newArgs;
11429                String name;
11430                if (opti >= args.length) {
11431                    name = null;
11432                    newArgs = EMPTY_STRING_ARRAY;
11433                } else {
11434                    name = args[opti];
11435                    opti++;
11436                    newArgs = new String[args.length - opti];
11437                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11438                }
11439                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11440                    pw.println("No providers match: " + name);
11441                    pw.println("Use -h for help.");
11442                }
11443            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11444                synchronized (this) {
11445                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11446                }
11447            } else if ("service".equals(cmd)) {
11448                String[] newArgs;
11449                String name;
11450                if (opti >= args.length) {
11451                    name = null;
11452                    newArgs = EMPTY_STRING_ARRAY;
11453                } else {
11454                    name = args[opti];
11455                    opti++;
11456                    newArgs = new String[args.length - opti];
11457                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11458                            args.length - opti);
11459                }
11460                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11461                    pw.println("No services match: " + name);
11462                    pw.println("Use -h for help.");
11463                }
11464            } else if ("package".equals(cmd)) {
11465                String[] newArgs;
11466                if (opti >= args.length) {
11467                    pw.println("package: no package name specified");
11468                    pw.println("Use -h for help.");
11469                } else {
11470                    dumpPackage = args[opti];
11471                    opti++;
11472                    newArgs = new String[args.length - opti];
11473                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11474                            args.length - opti);
11475                    args = newArgs;
11476                    opti = 0;
11477                    more = true;
11478                }
11479            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11480                synchronized (this) {
11481                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11482                }
11483            } else {
11484                // Dumping a single activity?
11485                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11486                    pw.println("Bad activity command, or no activities match: " + cmd);
11487                    pw.println("Use -h for help.");
11488                }
11489            }
11490            if (!more) {
11491                Binder.restoreCallingIdentity(origId);
11492                return;
11493            }
11494        }
11495
11496        // No piece of data specified, dump everything.
11497        synchronized (this) {
11498            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11499            pw.println();
11500            if (dumpAll) {
11501                pw.println("-------------------------------------------------------------------------------");
11502            }
11503            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11504            pw.println();
11505            if (dumpAll) {
11506                pw.println("-------------------------------------------------------------------------------");
11507            }
11508            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11509            pw.println();
11510            if (dumpAll) {
11511                pw.println("-------------------------------------------------------------------------------");
11512            }
11513            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11514            pw.println();
11515            if (dumpAll) {
11516                pw.println("-------------------------------------------------------------------------------");
11517            }
11518            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11519            pw.println();
11520            if (dumpAll) {
11521                pw.println("-------------------------------------------------------------------------------");
11522            }
11523            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11524        }
11525        Binder.restoreCallingIdentity(origId);
11526    }
11527
11528    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11529            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11530        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11531
11532        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11533                dumpPackage);
11534        boolean needSep = printedAnything;
11535
11536        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11537                dumpPackage, needSep, "  mFocusedActivity: ");
11538        if (printed) {
11539            printedAnything = true;
11540            needSep = false;
11541        }
11542
11543        if (dumpPackage == null) {
11544            if (needSep) {
11545                pw.println();
11546            }
11547            needSep = true;
11548            printedAnything = true;
11549            mStackSupervisor.dump(pw, "  ");
11550        }
11551
11552        if (mRecentTasks.size() > 0) {
11553            boolean printedHeader = false;
11554
11555            final int N = mRecentTasks.size();
11556            for (int i=0; i<N; i++) {
11557                TaskRecord tr = mRecentTasks.get(i);
11558                if (dumpPackage != null) {
11559                    if (tr.realActivity == null ||
11560                            !dumpPackage.equals(tr.realActivity)) {
11561                        continue;
11562                    }
11563                }
11564                if (!printedHeader) {
11565                    if (needSep) {
11566                        pw.println();
11567                    }
11568                    pw.println("  Recent tasks:");
11569                    printedHeader = true;
11570                    printedAnything = true;
11571                }
11572                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11573                        pw.println(tr);
11574                if (dumpAll) {
11575                    mRecentTasks.get(i).dump(pw, "    ");
11576                }
11577            }
11578        }
11579
11580        if (!printedAnything) {
11581            pw.println("  (nothing)");
11582        }
11583    }
11584
11585    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11586            int opti, boolean dumpAll, String dumpPackage) {
11587        boolean needSep = false;
11588        boolean printedAnything = false;
11589        int numPers = 0;
11590
11591        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11592
11593        if (dumpAll) {
11594            final int NP = mProcessNames.getMap().size();
11595            for (int ip=0; ip<NP; ip++) {
11596                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11597                final int NA = procs.size();
11598                for (int ia=0; ia<NA; ia++) {
11599                    ProcessRecord r = procs.valueAt(ia);
11600                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11601                        continue;
11602                    }
11603                    if (!needSep) {
11604                        pw.println("  All known processes:");
11605                        needSep = true;
11606                        printedAnything = true;
11607                    }
11608                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11609                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11610                        pw.print(" "); pw.println(r);
11611                    r.dump(pw, "    ");
11612                    if (r.persistent) {
11613                        numPers++;
11614                    }
11615                }
11616            }
11617        }
11618
11619        if (mIsolatedProcesses.size() > 0) {
11620            boolean printed = false;
11621            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11622                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11623                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11624                    continue;
11625                }
11626                if (!printed) {
11627                    if (needSep) {
11628                        pw.println();
11629                    }
11630                    pw.println("  Isolated process list (sorted by uid):");
11631                    printedAnything = true;
11632                    printed = true;
11633                    needSep = true;
11634                }
11635                pw.println(String.format("%sIsolated #%2d: %s",
11636                        "    ", i, r.toString()));
11637            }
11638        }
11639
11640        if (mLruProcesses.size() > 0) {
11641            if (needSep) {
11642                pw.println();
11643            }
11644            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11645                    pw.print(" total, non-act at ");
11646                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11647                    pw.print(", non-svc at ");
11648                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11649                    pw.println("):");
11650            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11651            needSep = true;
11652            printedAnything = true;
11653        }
11654
11655        if (dumpAll || dumpPackage != null) {
11656            synchronized (mPidsSelfLocked) {
11657                boolean printed = false;
11658                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11659                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11660                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11661                        continue;
11662                    }
11663                    if (!printed) {
11664                        if (needSep) pw.println();
11665                        needSep = true;
11666                        pw.println("  PID mappings:");
11667                        printed = true;
11668                        printedAnything = true;
11669                    }
11670                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11671                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11672                }
11673            }
11674        }
11675
11676        if (mForegroundProcesses.size() > 0) {
11677            synchronized (mPidsSelfLocked) {
11678                boolean printed = false;
11679                for (int i=0; i<mForegroundProcesses.size(); i++) {
11680                    ProcessRecord r = mPidsSelfLocked.get(
11681                            mForegroundProcesses.valueAt(i).pid);
11682                    if (dumpPackage != null && (r == null
11683                            || !r.pkgList.containsKey(dumpPackage))) {
11684                        continue;
11685                    }
11686                    if (!printed) {
11687                        if (needSep) pw.println();
11688                        needSep = true;
11689                        pw.println("  Foreground Processes:");
11690                        printed = true;
11691                        printedAnything = true;
11692                    }
11693                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11694                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11695                }
11696            }
11697        }
11698
11699        if (mPersistentStartingProcesses.size() > 0) {
11700            if (needSep) pw.println();
11701            needSep = true;
11702            printedAnything = true;
11703            pw.println("  Persisent processes that are starting:");
11704            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11705                    "Starting Norm", "Restarting PERS", dumpPackage);
11706        }
11707
11708        if (mRemovedProcesses.size() > 0) {
11709            if (needSep) pw.println();
11710            needSep = true;
11711            printedAnything = true;
11712            pw.println("  Processes that are being removed:");
11713            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11714                    "Removed Norm", "Removed PERS", dumpPackage);
11715        }
11716
11717        if (mProcessesOnHold.size() > 0) {
11718            if (needSep) pw.println();
11719            needSep = true;
11720            printedAnything = true;
11721            pw.println("  Processes that are on old until the system is ready:");
11722            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11723                    "OnHold Norm", "OnHold PERS", dumpPackage);
11724        }
11725
11726        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11727
11728        if (mProcessCrashTimes.getMap().size() > 0) {
11729            boolean printed = false;
11730            long now = SystemClock.uptimeMillis();
11731            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11732            final int NP = pmap.size();
11733            for (int ip=0; ip<NP; ip++) {
11734                String pname = pmap.keyAt(ip);
11735                SparseArray<Long> uids = pmap.valueAt(ip);
11736                final int N = uids.size();
11737                for (int i=0; i<N; i++) {
11738                    int puid = uids.keyAt(i);
11739                    ProcessRecord r = mProcessNames.get(pname, puid);
11740                    if (dumpPackage != null && (r == null
11741                            || !r.pkgList.containsKey(dumpPackage))) {
11742                        continue;
11743                    }
11744                    if (!printed) {
11745                        if (needSep) pw.println();
11746                        needSep = true;
11747                        pw.println("  Time since processes crashed:");
11748                        printed = true;
11749                        printedAnything = true;
11750                    }
11751                    pw.print("    Process "); pw.print(pname);
11752                            pw.print(" uid "); pw.print(puid);
11753                            pw.print(": last crashed ");
11754                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11755                            pw.println(" ago");
11756                }
11757            }
11758        }
11759
11760        if (mBadProcesses.getMap().size() > 0) {
11761            boolean printed = false;
11762            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11763            final int NP = pmap.size();
11764            for (int ip=0; ip<NP; ip++) {
11765                String pname = pmap.keyAt(ip);
11766                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11767                final int N = uids.size();
11768                for (int i=0; i<N; i++) {
11769                    int puid = uids.keyAt(i);
11770                    ProcessRecord r = mProcessNames.get(pname, puid);
11771                    if (dumpPackage != null && (r == null
11772                            || !r.pkgList.containsKey(dumpPackage))) {
11773                        continue;
11774                    }
11775                    if (!printed) {
11776                        if (needSep) pw.println();
11777                        needSep = true;
11778                        pw.println("  Bad processes:");
11779                        printedAnything = true;
11780                    }
11781                    BadProcessInfo info = uids.valueAt(i);
11782                    pw.print("    Bad process "); pw.print(pname);
11783                            pw.print(" uid "); pw.print(puid);
11784                            pw.print(": crashed at time "); pw.println(info.time);
11785                    if (info.shortMsg != null) {
11786                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11787                    }
11788                    if (info.longMsg != null) {
11789                        pw.print("      Long msg: "); pw.println(info.longMsg);
11790                    }
11791                    if (info.stack != null) {
11792                        pw.println("      Stack:");
11793                        int lastPos = 0;
11794                        for (int pos=0; pos<info.stack.length(); pos++) {
11795                            if (info.stack.charAt(pos) == '\n') {
11796                                pw.print("        ");
11797                                pw.write(info.stack, lastPos, pos-lastPos);
11798                                pw.println();
11799                                lastPos = pos+1;
11800                            }
11801                        }
11802                        if (lastPos < info.stack.length()) {
11803                            pw.print("        ");
11804                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11805                            pw.println();
11806                        }
11807                    }
11808                }
11809            }
11810        }
11811
11812        if (dumpPackage == null) {
11813            pw.println();
11814            needSep = false;
11815            pw.println("  mStartedUsers:");
11816            for (int i=0; i<mStartedUsers.size(); i++) {
11817                UserStartedState uss = mStartedUsers.valueAt(i);
11818                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11819                        pw.print(": "); uss.dump("", pw);
11820            }
11821            pw.print("  mStartedUserArray: [");
11822            for (int i=0; i<mStartedUserArray.length; i++) {
11823                if (i > 0) pw.print(", ");
11824                pw.print(mStartedUserArray[i]);
11825            }
11826            pw.println("]");
11827            pw.print("  mUserLru: [");
11828            for (int i=0; i<mUserLru.size(); i++) {
11829                if (i > 0) pw.print(", ");
11830                pw.print(mUserLru.get(i));
11831            }
11832            pw.println("]");
11833            if (dumpAll) {
11834                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11835            }
11836            synchronized (mUserProfileGroupIdsSelfLocked) {
11837                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11838                    pw.println("  mUserProfileGroupIds:");
11839                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11840                        pw.print("    User #");
11841                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11842                        pw.print(" -> profile #");
11843                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11844                    }
11845                }
11846            }
11847        }
11848        if (mHomeProcess != null && (dumpPackage == null
11849                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11850            if (needSep) {
11851                pw.println();
11852                needSep = false;
11853            }
11854            pw.println("  mHomeProcess: " + mHomeProcess);
11855        }
11856        if (mPreviousProcess != null && (dumpPackage == null
11857                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11858            if (needSep) {
11859                pw.println();
11860                needSep = false;
11861            }
11862            pw.println("  mPreviousProcess: " + mPreviousProcess);
11863        }
11864        if (dumpAll) {
11865            StringBuilder sb = new StringBuilder(128);
11866            sb.append("  mPreviousProcessVisibleTime: ");
11867            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11868            pw.println(sb);
11869        }
11870        if (mHeavyWeightProcess != null && (dumpPackage == null
11871                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11872            if (needSep) {
11873                pw.println();
11874                needSep = false;
11875            }
11876            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11877        }
11878        if (dumpPackage == null) {
11879            pw.println("  mConfiguration: " + mConfiguration);
11880        }
11881        if (dumpAll) {
11882            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11883            if (mCompatModePackages.getPackages().size() > 0) {
11884                boolean printed = false;
11885                for (Map.Entry<String, Integer> entry
11886                        : mCompatModePackages.getPackages().entrySet()) {
11887                    String pkg = entry.getKey();
11888                    int mode = entry.getValue();
11889                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11890                        continue;
11891                    }
11892                    if (!printed) {
11893                        pw.println("  mScreenCompatPackages:");
11894                        printed = true;
11895                    }
11896                    pw.print("    "); pw.print(pkg); pw.print(": ");
11897                            pw.print(mode); pw.println();
11898                }
11899            }
11900        }
11901        if (dumpPackage == null) {
11902            if (mSleeping || mWentToSleep || mLockScreenShown) {
11903                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11904                        + " mLockScreenShown " + mLockScreenShown);
11905            }
11906            if (mShuttingDown || mRunningVoice) {
11907                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11908            }
11909        }
11910        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11911                || mOrigWaitForDebugger) {
11912            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11913                    || dumpPackage.equals(mOrigDebugApp)) {
11914                if (needSep) {
11915                    pw.println();
11916                    needSep = false;
11917                }
11918                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11919                        + " mDebugTransient=" + mDebugTransient
11920                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11921            }
11922        }
11923        if (mOpenGlTraceApp != null) {
11924            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11925                if (needSep) {
11926                    pw.println();
11927                    needSep = false;
11928                }
11929                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11930            }
11931        }
11932        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11933                || mProfileFd != null) {
11934            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11935                if (needSep) {
11936                    pw.println();
11937                    needSep = false;
11938                }
11939                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11940                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11941                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11942                        + mAutoStopProfiler);
11943            }
11944        }
11945        if (dumpPackage == null) {
11946            if (mAlwaysFinishActivities || mController != null) {
11947                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11948                        + " mController=" + mController);
11949            }
11950            if (dumpAll) {
11951                pw.println("  Total persistent processes: " + numPers);
11952                pw.println("  mProcessesReady=" + mProcessesReady
11953                        + " mSystemReady=" + mSystemReady);
11954                pw.println("  mBooting=" + mBooting
11955                        + " mBooted=" + mBooted
11956                        + " mFactoryTest=" + mFactoryTest);
11957                pw.print("  mLastPowerCheckRealtime=");
11958                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11959                        pw.println("");
11960                pw.print("  mLastPowerCheckUptime=");
11961                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11962                        pw.println("");
11963                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11964                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11965                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11966                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11967                        + " (" + mLruProcesses.size() + " total)"
11968                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11969                        + " mNumServiceProcs=" + mNumServiceProcs
11970                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11971                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11972                        + " mLastMemoryLevel" + mLastMemoryLevel
11973                        + " mLastNumProcesses" + mLastNumProcesses);
11974                long now = SystemClock.uptimeMillis();
11975                pw.print("  mLastIdleTime=");
11976                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11977                        pw.print(" mLowRamSinceLastIdle=");
11978                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11979                        pw.println();
11980            }
11981        }
11982
11983        if (!printedAnything) {
11984            pw.println("  (nothing)");
11985        }
11986    }
11987
11988    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11989            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11990        if (mProcessesToGc.size() > 0) {
11991            boolean printed = false;
11992            long now = SystemClock.uptimeMillis();
11993            for (int i=0; i<mProcessesToGc.size(); i++) {
11994                ProcessRecord proc = mProcessesToGc.get(i);
11995                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11996                    continue;
11997                }
11998                if (!printed) {
11999                    if (needSep) pw.println();
12000                    needSep = true;
12001                    pw.println("  Processes that are waiting to GC:");
12002                    printed = true;
12003                }
12004                pw.print("    Process "); pw.println(proc);
12005                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12006                        pw.print(", last gced=");
12007                        pw.print(now-proc.lastRequestedGc);
12008                        pw.print(" ms ago, last lowMem=");
12009                        pw.print(now-proc.lastLowMemory);
12010                        pw.println(" ms ago");
12011
12012            }
12013        }
12014        return needSep;
12015    }
12016
12017    void printOomLevel(PrintWriter pw, String name, int adj) {
12018        pw.print("    ");
12019        if (adj >= 0) {
12020            pw.print(' ');
12021            if (adj < 10) pw.print(' ');
12022        } else {
12023            if (adj > -10) pw.print(' ');
12024        }
12025        pw.print(adj);
12026        pw.print(": ");
12027        pw.print(name);
12028        pw.print(" (");
12029        pw.print(mProcessList.getMemLevel(adj)/1024);
12030        pw.println(" kB)");
12031    }
12032
12033    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12034            int opti, boolean dumpAll) {
12035        boolean needSep = false;
12036
12037        if (mLruProcesses.size() > 0) {
12038            if (needSep) pw.println();
12039            needSep = true;
12040            pw.println("  OOM levels:");
12041            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12042            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12043            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12044            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12045            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12046            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12047            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12048            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12049            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12050            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12051            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12052            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12053            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12054
12055            if (needSep) pw.println();
12056            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12057                    pw.print(" total, non-act at ");
12058                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12059                    pw.print(", non-svc at ");
12060                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12061                    pw.println("):");
12062            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12063            needSep = true;
12064        }
12065
12066        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12067
12068        pw.println();
12069        pw.println("  mHomeProcess: " + mHomeProcess);
12070        pw.println("  mPreviousProcess: " + mPreviousProcess);
12071        if (mHeavyWeightProcess != null) {
12072            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12073        }
12074
12075        return true;
12076    }
12077
12078    /**
12079     * There are three ways to call this:
12080     *  - no provider specified: dump all the providers
12081     *  - a flattened component name that matched an existing provider was specified as the
12082     *    first arg: dump that one provider
12083     *  - the first arg isn't the flattened component name of an existing provider:
12084     *    dump all providers whose component contains the first arg as a substring
12085     */
12086    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12087            int opti, boolean dumpAll) {
12088        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12089    }
12090
12091    static class ItemMatcher {
12092        ArrayList<ComponentName> components;
12093        ArrayList<String> strings;
12094        ArrayList<Integer> objects;
12095        boolean all;
12096
12097        ItemMatcher() {
12098            all = true;
12099        }
12100
12101        void build(String name) {
12102            ComponentName componentName = ComponentName.unflattenFromString(name);
12103            if (componentName != null) {
12104                if (components == null) {
12105                    components = new ArrayList<ComponentName>();
12106                }
12107                components.add(componentName);
12108                all = false;
12109            } else {
12110                int objectId = 0;
12111                // Not a '/' separated full component name; maybe an object ID?
12112                try {
12113                    objectId = Integer.parseInt(name, 16);
12114                    if (objects == null) {
12115                        objects = new ArrayList<Integer>();
12116                    }
12117                    objects.add(objectId);
12118                    all = false;
12119                } catch (RuntimeException e) {
12120                    // Not an integer; just do string match.
12121                    if (strings == null) {
12122                        strings = new ArrayList<String>();
12123                    }
12124                    strings.add(name);
12125                    all = false;
12126                }
12127            }
12128        }
12129
12130        int build(String[] args, int opti) {
12131            for (; opti<args.length; opti++) {
12132                String name = args[opti];
12133                if ("--".equals(name)) {
12134                    return opti+1;
12135                }
12136                build(name);
12137            }
12138            return opti;
12139        }
12140
12141        boolean match(Object object, ComponentName comp) {
12142            if (all) {
12143                return true;
12144            }
12145            if (components != null) {
12146                for (int i=0; i<components.size(); i++) {
12147                    if (components.get(i).equals(comp)) {
12148                        return true;
12149                    }
12150                }
12151            }
12152            if (objects != null) {
12153                for (int i=0; i<objects.size(); i++) {
12154                    if (System.identityHashCode(object) == objects.get(i)) {
12155                        return true;
12156                    }
12157                }
12158            }
12159            if (strings != null) {
12160                String flat = comp.flattenToString();
12161                for (int i=0; i<strings.size(); i++) {
12162                    if (flat.contains(strings.get(i))) {
12163                        return true;
12164                    }
12165                }
12166            }
12167            return false;
12168        }
12169    }
12170
12171    /**
12172     * There are three things that cmd can be:
12173     *  - a flattened component name that matches an existing activity
12174     *  - the cmd arg isn't the flattened component name of an existing activity:
12175     *    dump all activity whose component contains the cmd as a substring
12176     *  - A hex number of the ActivityRecord object instance.
12177     */
12178    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12179            int opti, boolean dumpAll) {
12180        ArrayList<ActivityRecord> activities;
12181
12182        synchronized (this) {
12183            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12184        }
12185
12186        if (activities.size() <= 0) {
12187            return false;
12188        }
12189
12190        String[] newArgs = new String[args.length - opti];
12191        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12192
12193        TaskRecord lastTask = null;
12194        boolean needSep = false;
12195        for (int i=activities.size()-1; i>=0; i--) {
12196            ActivityRecord r = activities.get(i);
12197            if (needSep) {
12198                pw.println();
12199            }
12200            needSep = true;
12201            synchronized (this) {
12202                if (lastTask != r.task) {
12203                    lastTask = r.task;
12204                    pw.print("TASK "); pw.print(lastTask.affinity);
12205                            pw.print(" id="); pw.println(lastTask.taskId);
12206                    if (dumpAll) {
12207                        lastTask.dump(pw, "  ");
12208                    }
12209                }
12210            }
12211            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12212        }
12213        return true;
12214    }
12215
12216    /**
12217     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12218     * there is a thread associated with the activity.
12219     */
12220    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12221            final ActivityRecord r, String[] args, boolean dumpAll) {
12222        String innerPrefix = prefix + "  ";
12223        synchronized (this) {
12224            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12225                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12226                    pw.print(" pid=");
12227                    if (r.app != null) pw.println(r.app.pid);
12228                    else pw.println("(not running)");
12229            if (dumpAll) {
12230                r.dump(pw, innerPrefix);
12231            }
12232        }
12233        if (r.app != null && r.app.thread != null) {
12234            // flush anything that is already in the PrintWriter since the thread is going
12235            // to write to the file descriptor directly
12236            pw.flush();
12237            try {
12238                TransferPipe tp = new TransferPipe();
12239                try {
12240                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12241                            r.appToken, innerPrefix, args);
12242                    tp.go(fd);
12243                } finally {
12244                    tp.kill();
12245                }
12246            } catch (IOException e) {
12247                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12248            } catch (RemoteException e) {
12249                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12250            }
12251        }
12252    }
12253
12254    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12255            int opti, boolean dumpAll, String dumpPackage) {
12256        boolean needSep = false;
12257        boolean onlyHistory = false;
12258        boolean printedAnything = false;
12259
12260        if ("history".equals(dumpPackage)) {
12261            if (opti < args.length && "-s".equals(args[opti])) {
12262                dumpAll = false;
12263            }
12264            onlyHistory = true;
12265            dumpPackage = null;
12266        }
12267
12268        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12269        if (!onlyHistory && dumpAll) {
12270            if (mRegisteredReceivers.size() > 0) {
12271                boolean printed = false;
12272                Iterator it = mRegisteredReceivers.values().iterator();
12273                while (it.hasNext()) {
12274                    ReceiverList r = (ReceiverList)it.next();
12275                    if (dumpPackage != null && (r.app == null ||
12276                            !dumpPackage.equals(r.app.info.packageName))) {
12277                        continue;
12278                    }
12279                    if (!printed) {
12280                        pw.println("  Registered Receivers:");
12281                        needSep = true;
12282                        printed = true;
12283                        printedAnything = true;
12284                    }
12285                    pw.print("  * "); pw.println(r);
12286                    r.dump(pw, "    ");
12287                }
12288            }
12289
12290            if (mReceiverResolver.dump(pw, needSep ?
12291                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12292                    "    ", dumpPackage, false)) {
12293                needSep = true;
12294                printedAnything = true;
12295            }
12296        }
12297
12298        for (BroadcastQueue q : mBroadcastQueues) {
12299            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12300            printedAnything |= needSep;
12301        }
12302
12303        needSep = true;
12304
12305        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12306            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12307                if (needSep) {
12308                    pw.println();
12309                }
12310                needSep = true;
12311                printedAnything = true;
12312                pw.print("  Sticky broadcasts for user ");
12313                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12314                StringBuilder sb = new StringBuilder(128);
12315                for (Map.Entry<String, ArrayList<Intent>> ent
12316                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12317                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12318                    if (dumpAll) {
12319                        pw.println(":");
12320                        ArrayList<Intent> intents = ent.getValue();
12321                        final int N = intents.size();
12322                        for (int i=0; i<N; i++) {
12323                            sb.setLength(0);
12324                            sb.append("    Intent: ");
12325                            intents.get(i).toShortString(sb, false, true, false, false);
12326                            pw.println(sb.toString());
12327                            Bundle bundle = intents.get(i).getExtras();
12328                            if (bundle != null) {
12329                                pw.print("      ");
12330                                pw.println(bundle.toString());
12331                            }
12332                        }
12333                    } else {
12334                        pw.println("");
12335                    }
12336                }
12337            }
12338        }
12339
12340        if (!onlyHistory && dumpAll) {
12341            pw.println();
12342            for (BroadcastQueue queue : mBroadcastQueues) {
12343                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12344                        + queue.mBroadcastsScheduled);
12345            }
12346            pw.println("  mHandler:");
12347            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12348            needSep = true;
12349            printedAnything = true;
12350        }
12351
12352        if (!printedAnything) {
12353            pw.println("  (nothing)");
12354        }
12355    }
12356
12357    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12358            int opti, boolean dumpAll, String dumpPackage) {
12359        boolean needSep;
12360        boolean printedAnything = false;
12361
12362        ItemMatcher matcher = new ItemMatcher();
12363        matcher.build(args, opti);
12364
12365        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12366
12367        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12368        printedAnything |= needSep;
12369
12370        if (mLaunchingProviders.size() > 0) {
12371            boolean printed = false;
12372            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12373                ContentProviderRecord r = mLaunchingProviders.get(i);
12374                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12375                    continue;
12376                }
12377                if (!printed) {
12378                    if (needSep) pw.println();
12379                    needSep = true;
12380                    pw.println("  Launching content providers:");
12381                    printed = true;
12382                    printedAnything = true;
12383                }
12384                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12385                        pw.println(r);
12386            }
12387        }
12388
12389        if (mGrantedUriPermissions.size() > 0) {
12390            boolean printed = false;
12391            int dumpUid = -2;
12392            if (dumpPackage != null) {
12393                try {
12394                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12395                } catch (NameNotFoundException e) {
12396                    dumpUid = -1;
12397                }
12398            }
12399            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12400                int uid = mGrantedUriPermissions.keyAt(i);
12401                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12402                    continue;
12403                }
12404                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12405                if (!printed) {
12406                    if (needSep) pw.println();
12407                    needSep = true;
12408                    pw.println("  Granted Uri Permissions:");
12409                    printed = true;
12410                    printedAnything = true;
12411                }
12412                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12413                for (UriPermission perm : perms.values()) {
12414                    pw.print("    "); pw.println(perm);
12415                    if (dumpAll) {
12416                        perm.dump(pw, "      ");
12417                    }
12418                }
12419            }
12420        }
12421
12422        if (!printedAnything) {
12423            pw.println("  (nothing)");
12424        }
12425    }
12426
12427    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12428            int opti, boolean dumpAll, String dumpPackage) {
12429        boolean printed = false;
12430
12431        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12432
12433        if (mIntentSenderRecords.size() > 0) {
12434            Iterator<WeakReference<PendingIntentRecord>> it
12435                    = mIntentSenderRecords.values().iterator();
12436            while (it.hasNext()) {
12437                WeakReference<PendingIntentRecord> ref = it.next();
12438                PendingIntentRecord rec = ref != null ? ref.get(): null;
12439                if (dumpPackage != null && (rec == null
12440                        || !dumpPackage.equals(rec.key.packageName))) {
12441                    continue;
12442                }
12443                printed = true;
12444                if (rec != null) {
12445                    pw.print("  * "); pw.println(rec);
12446                    if (dumpAll) {
12447                        rec.dump(pw, "    ");
12448                    }
12449                } else {
12450                    pw.print("  * "); pw.println(ref);
12451                }
12452            }
12453        }
12454
12455        if (!printed) {
12456            pw.println("  (nothing)");
12457        }
12458    }
12459
12460    private static final int dumpProcessList(PrintWriter pw,
12461            ActivityManagerService service, List list,
12462            String prefix, String normalLabel, String persistentLabel,
12463            String dumpPackage) {
12464        int numPers = 0;
12465        final int N = list.size()-1;
12466        for (int i=N; i>=0; i--) {
12467            ProcessRecord r = (ProcessRecord)list.get(i);
12468            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12469                continue;
12470            }
12471            pw.println(String.format("%s%s #%2d: %s",
12472                    prefix, (r.persistent ? persistentLabel : normalLabel),
12473                    i, r.toString()));
12474            if (r.persistent) {
12475                numPers++;
12476            }
12477        }
12478        return numPers;
12479    }
12480
12481    private static final boolean dumpProcessOomList(PrintWriter pw,
12482            ActivityManagerService service, List<ProcessRecord> origList,
12483            String prefix, String normalLabel, String persistentLabel,
12484            boolean inclDetails, String dumpPackage) {
12485
12486        ArrayList<Pair<ProcessRecord, Integer>> list
12487                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12488        for (int i=0; i<origList.size(); i++) {
12489            ProcessRecord r = origList.get(i);
12490            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12491                continue;
12492            }
12493            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12494        }
12495
12496        if (list.size() <= 0) {
12497            return false;
12498        }
12499
12500        Comparator<Pair<ProcessRecord, Integer>> comparator
12501                = new Comparator<Pair<ProcessRecord, Integer>>() {
12502            @Override
12503            public int compare(Pair<ProcessRecord, Integer> object1,
12504                    Pair<ProcessRecord, Integer> object2) {
12505                if (object1.first.setAdj != object2.first.setAdj) {
12506                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12507                }
12508                if (object1.second.intValue() != object2.second.intValue()) {
12509                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12510                }
12511                return 0;
12512            }
12513        };
12514
12515        Collections.sort(list, comparator);
12516
12517        final long curRealtime = SystemClock.elapsedRealtime();
12518        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12519        final long curUptime = SystemClock.uptimeMillis();
12520        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12521
12522        for (int i=list.size()-1; i>=0; i--) {
12523            ProcessRecord r = list.get(i).first;
12524            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12525            char schedGroup;
12526            switch (r.setSchedGroup) {
12527                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12528                    schedGroup = 'B';
12529                    break;
12530                case Process.THREAD_GROUP_DEFAULT:
12531                    schedGroup = 'F';
12532                    break;
12533                default:
12534                    schedGroup = '?';
12535                    break;
12536            }
12537            char foreground;
12538            if (r.foregroundActivities) {
12539                foreground = 'A';
12540            } else if (r.foregroundServices) {
12541                foreground = 'S';
12542            } else {
12543                foreground = ' ';
12544            }
12545            String procState = ProcessList.makeProcStateString(r.curProcState);
12546            pw.print(prefix);
12547            pw.print(r.persistent ? persistentLabel : normalLabel);
12548            pw.print(" #");
12549            int num = (origList.size()-1)-list.get(i).second;
12550            if (num < 10) pw.print(' ');
12551            pw.print(num);
12552            pw.print(": ");
12553            pw.print(oomAdj);
12554            pw.print(' ');
12555            pw.print(schedGroup);
12556            pw.print('/');
12557            pw.print(foreground);
12558            pw.print('/');
12559            pw.print(procState);
12560            pw.print(" trm:");
12561            if (r.trimMemoryLevel < 10) pw.print(' ');
12562            pw.print(r.trimMemoryLevel);
12563            pw.print(' ');
12564            pw.print(r.toShortString());
12565            pw.print(" (");
12566            pw.print(r.adjType);
12567            pw.println(')');
12568            if (r.adjSource != null || r.adjTarget != null) {
12569                pw.print(prefix);
12570                pw.print("    ");
12571                if (r.adjTarget instanceof ComponentName) {
12572                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12573                } else if (r.adjTarget != null) {
12574                    pw.print(r.adjTarget.toString());
12575                } else {
12576                    pw.print("{null}");
12577                }
12578                pw.print("<=");
12579                if (r.adjSource instanceof ProcessRecord) {
12580                    pw.print("Proc{");
12581                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12582                    pw.println("}");
12583                } else if (r.adjSource != null) {
12584                    pw.println(r.adjSource.toString());
12585                } else {
12586                    pw.println("{null}");
12587                }
12588            }
12589            if (inclDetails) {
12590                pw.print(prefix);
12591                pw.print("    ");
12592                pw.print("oom: max="); pw.print(r.maxAdj);
12593                pw.print(" curRaw="); pw.print(r.curRawAdj);
12594                pw.print(" setRaw="); pw.print(r.setRawAdj);
12595                pw.print(" cur="); pw.print(r.curAdj);
12596                pw.print(" set="); pw.println(r.setAdj);
12597                pw.print(prefix);
12598                pw.print("    ");
12599                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12600                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12601                pw.print(" lastPss="); pw.print(r.lastPss);
12602                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12603                pw.print(prefix);
12604                pw.print("    ");
12605                pw.print("cached="); pw.print(r.cached);
12606                pw.print(" empty="); pw.print(r.empty);
12607                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12608
12609                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12610                    if (r.lastWakeTime != 0) {
12611                        long wtime;
12612                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12613                        synchronized (stats) {
12614                            wtime = stats.getProcessWakeTime(r.info.uid,
12615                                    r.pid, curRealtime);
12616                        }
12617                        long timeUsed = wtime - r.lastWakeTime;
12618                        pw.print(prefix);
12619                        pw.print("    ");
12620                        pw.print("keep awake over ");
12621                        TimeUtils.formatDuration(realtimeSince, pw);
12622                        pw.print(" used ");
12623                        TimeUtils.formatDuration(timeUsed, pw);
12624                        pw.print(" (");
12625                        pw.print((timeUsed*100)/realtimeSince);
12626                        pw.println("%)");
12627                    }
12628                    if (r.lastCpuTime != 0) {
12629                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12630                        pw.print(prefix);
12631                        pw.print("    ");
12632                        pw.print("run cpu over ");
12633                        TimeUtils.formatDuration(uptimeSince, pw);
12634                        pw.print(" used ");
12635                        TimeUtils.formatDuration(timeUsed, pw);
12636                        pw.print(" (");
12637                        pw.print((timeUsed*100)/uptimeSince);
12638                        pw.println("%)");
12639                    }
12640                }
12641            }
12642        }
12643        return true;
12644    }
12645
12646    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12647        ArrayList<ProcessRecord> procs;
12648        synchronized (this) {
12649            if (args != null && args.length > start
12650                    && args[start].charAt(0) != '-') {
12651                procs = new ArrayList<ProcessRecord>();
12652                int pid = -1;
12653                try {
12654                    pid = Integer.parseInt(args[start]);
12655                } catch (NumberFormatException e) {
12656                }
12657                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12658                    ProcessRecord proc = mLruProcesses.get(i);
12659                    if (proc.pid == pid) {
12660                        procs.add(proc);
12661                    } else if (proc.processName.equals(args[start])) {
12662                        procs.add(proc);
12663                    }
12664                }
12665                if (procs.size() <= 0) {
12666                    return null;
12667                }
12668            } else {
12669                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12670            }
12671        }
12672        return procs;
12673    }
12674
12675    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12676            PrintWriter pw, String[] args) {
12677        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12678        if (procs == null) {
12679            pw.println("No process found for: " + args[0]);
12680            return;
12681        }
12682
12683        long uptime = SystemClock.uptimeMillis();
12684        long realtime = SystemClock.elapsedRealtime();
12685        pw.println("Applications Graphics Acceleration Info:");
12686        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12687
12688        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12689            ProcessRecord r = procs.get(i);
12690            if (r.thread != null) {
12691                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12692                pw.flush();
12693                try {
12694                    TransferPipe tp = new TransferPipe();
12695                    try {
12696                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12697                        tp.go(fd);
12698                    } finally {
12699                        tp.kill();
12700                    }
12701                } catch (IOException e) {
12702                    pw.println("Failure while dumping the app: " + r);
12703                    pw.flush();
12704                } catch (RemoteException e) {
12705                    pw.println("Got a RemoteException while dumping the app " + r);
12706                    pw.flush();
12707                }
12708            }
12709        }
12710    }
12711
12712    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12713        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12714        if (procs == null) {
12715            pw.println("No process found for: " + args[0]);
12716            return;
12717        }
12718
12719        pw.println("Applications Database Info:");
12720
12721        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12722            ProcessRecord r = procs.get(i);
12723            if (r.thread != null) {
12724                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12725                pw.flush();
12726                try {
12727                    TransferPipe tp = new TransferPipe();
12728                    try {
12729                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12730                        tp.go(fd);
12731                    } finally {
12732                        tp.kill();
12733                    }
12734                } catch (IOException e) {
12735                    pw.println("Failure while dumping the app: " + r);
12736                    pw.flush();
12737                } catch (RemoteException e) {
12738                    pw.println("Got a RemoteException while dumping the app " + r);
12739                    pw.flush();
12740                }
12741            }
12742        }
12743    }
12744
12745    final static class MemItem {
12746        final boolean isProc;
12747        final String label;
12748        final String shortLabel;
12749        final long pss;
12750        final int id;
12751        final boolean hasActivities;
12752        ArrayList<MemItem> subitems;
12753
12754        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12755                boolean _hasActivities) {
12756            isProc = true;
12757            label = _label;
12758            shortLabel = _shortLabel;
12759            pss = _pss;
12760            id = _id;
12761            hasActivities = _hasActivities;
12762        }
12763
12764        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12765            isProc = false;
12766            label = _label;
12767            shortLabel = _shortLabel;
12768            pss = _pss;
12769            id = _id;
12770            hasActivities = false;
12771        }
12772    }
12773
12774    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12775            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12776        if (sort && !isCompact) {
12777            Collections.sort(items, new Comparator<MemItem>() {
12778                @Override
12779                public int compare(MemItem lhs, MemItem rhs) {
12780                    if (lhs.pss < rhs.pss) {
12781                        return 1;
12782                    } else if (lhs.pss > rhs.pss) {
12783                        return -1;
12784                    }
12785                    return 0;
12786                }
12787            });
12788        }
12789
12790        for (int i=0; i<items.size(); i++) {
12791            MemItem mi = items.get(i);
12792            if (!isCompact) {
12793                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12794            } else if (mi.isProc) {
12795                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12796                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12797                pw.println(mi.hasActivities ? ",a" : ",e");
12798            } else {
12799                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12800                pw.println(mi.pss);
12801            }
12802            if (mi.subitems != null) {
12803                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12804                        true, isCompact);
12805            }
12806        }
12807    }
12808
12809    // These are in KB.
12810    static final long[] DUMP_MEM_BUCKETS = new long[] {
12811        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12812        120*1024, 160*1024, 200*1024,
12813        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12814        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12815    };
12816
12817    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12818            boolean stackLike) {
12819        int start = label.lastIndexOf('.');
12820        if (start >= 0) start++;
12821        else start = 0;
12822        int end = label.length();
12823        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12824            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12825                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12826                out.append(bucket);
12827                out.append(stackLike ? "MB." : "MB ");
12828                out.append(label, start, end);
12829                return;
12830            }
12831        }
12832        out.append(memKB/1024);
12833        out.append(stackLike ? "MB." : "MB ");
12834        out.append(label, start, end);
12835    }
12836
12837    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12838            ProcessList.NATIVE_ADJ,
12839            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12840            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12841            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12842            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12843            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12844    };
12845    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12846            "Native",
12847            "System", "Persistent", "Foreground",
12848            "Visible", "Perceptible",
12849            "Heavy Weight", "Backup",
12850            "A Services", "Home",
12851            "Previous", "B Services", "Cached"
12852    };
12853    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12854            "native",
12855            "sys", "pers", "fore",
12856            "vis", "percept",
12857            "heavy", "backup",
12858            "servicea", "home",
12859            "prev", "serviceb", "cached"
12860    };
12861
12862    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12863            long realtime, boolean isCheckinRequest, boolean isCompact) {
12864        if (isCheckinRequest || isCompact) {
12865            // short checkin version
12866            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12867        } else {
12868            pw.println("Applications Memory Usage (kB):");
12869            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12870        }
12871    }
12872
12873    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12874            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12875        boolean dumpDetails = false;
12876        boolean dumpFullDetails = false;
12877        boolean dumpDalvik = false;
12878        boolean oomOnly = false;
12879        boolean isCompact = false;
12880        boolean localOnly = false;
12881
12882        int opti = 0;
12883        while (opti < args.length) {
12884            String opt = args[opti];
12885            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12886                break;
12887            }
12888            opti++;
12889            if ("-a".equals(opt)) {
12890                dumpDetails = true;
12891                dumpFullDetails = true;
12892                dumpDalvik = true;
12893            } else if ("-d".equals(opt)) {
12894                dumpDalvik = true;
12895            } else if ("-c".equals(opt)) {
12896                isCompact = true;
12897            } else if ("--oom".equals(opt)) {
12898                oomOnly = true;
12899            } else if ("--local".equals(opt)) {
12900                localOnly = true;
12901            } else if ("-h".equals(opt)) {
12902                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12903                pw.println("  -a: include all available information for each process.");
12904                pw.println("  -d: include dalvik details when dumping process details.");
12905                pw.println("  -c: dump in a compact machine-parseable representation.");
12906                pw.println("  --oom: only show processes organized by oom adj.");
12907                pw.println("  --local: only collect details locally, don't call process.");
12908                pw.println("If [process] is specified it can be the name or ");
12909                pw.println("pid of a specific process to dump.");
12910                return;
12911            } else {
12912                pw.println("Unknown argument: " + opt + "; use -h for help");
12913            }
12914        }
12915
12916        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12917        long uptime = SystemClock.uptimeMillis();
12918        long realtime = SystemClock.elapsedRealtime();
12919        final long[] tmpLong = new long[1];
12920
12921        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12922        if (procs == null) {
12923            // No Java processes.  Maybe they want to print a native process.
12924            if (args != null && args.length > opti
12925                    && args[opti].charAt(0) != '-') {
12926                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12927                        = new ArrayList<ProcessCpuTracker.Stats>();
12928                updateCpuStatsNow();
12929                int findPid = -1;
12930                try {
12931                    findPid = Integer.parseInt(args[opti]);
12932                } catch (NumberFormatException e) {
12933                }
12934                synchronized (mProcessCpuThread) {
12935                    final int N = mProcessCpuTracker.countStats();
12936                    for (int i=0; i<N; i++) {
12937                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12938                        if (st.pid == findPid || (st.baseName != null
12939                                && st.baseName.equals(args[opti]))) {
12940                            nativeProcs.add(st);
12941                        }
12942                    }
12943                }
12944                if (nativeProcs.size() > 0) {
12945                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12946                            isCompact);
12947                    Debug.MemoryInfo mi = null;
12948                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12949                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12950                        final int pid = r.pid;
12951                        if (!isCheckinRequest && dumpDetails) {
12952                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12953                        }
12954                        if (mi == null) {
12955                            mi = new Debug.MemoryInfo();
12956                        }
12957                        if (dumpDetails || (!brief && !oomOnly)) {
12958                            Debug.getMemoryInfo(pid, mi);
12959                        } else {
12960                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12961                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12962                        }
12963                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12964                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12965                        if (isCheckinRequest) {
12966                            pw.println();
12967                        }
12968                    }
12969                    return;
12970                }
12971            }
12972            pw.println("No process found for: " + args[opti]);
12973            return;
12974        }
12975
12976        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12977            dumpDetails = true;
12978        }
12979
12980        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12981
12982        String[] innerArgs = new String[args.length-opti];
12983        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12984
12985        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12986        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12987        long nativePss=0, dalvikPss=0, otherPss=0;
12988        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12989
12990        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12991        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12992                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12993
12994        long totalPss = 0;
12995        long cachedPss = 0;
12996
12997        Debug.MemoryInfo mi = null;
12998        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12999            final ProcessRecord r = procs.get(i);
13000            final IApplicationThread thread;
13001            final int pid;
13002            final int oomAdj;
13003            final boolean hasActivities;
13004            synchronized (this) {
13005                thread = r.thread;
13006                pid = r.pid;
13007                oomAdj = r.getSetAdjWithServices();
13008                hasActivities = r.activities.size() > 0;
13009            }
13010            if (thread != null) {
13011                if (!isCheckinRequest && dumpDetails) {
13012                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13013                }
13014                if (mi == null) {
13015                    mi = new Debug.MemoryInfo();
13016                }
13017                if (dumpDetails || (!brief && !oomOnly)) {
13018                    Debug.getMemoryInfo(pid, mi);
13019                } else {
13020                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13021                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13022                }
13023                if (dumpDetails) {
13024                    if (localOnly) {
13025                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13026                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13027                        if (isCheckinRequest) {
13028                            pw.println();
13029                        }
13030                    } else {
13031                        try {
13032                            pw.flush();
13033                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13034                                    dumpDalvik, innerArgs);
13035                        } catch (RemoteException e) {
13036                            if (!isCheckinRequest) {
13037                                pw.println("Got RemoteException!");
13038                                pw.flush();
13039                            }
13040                        }
13041                    }
13042                }
13043
13044                final long myTotalPss = mi.getTotalPss();
13045                final long myTotalUss = mi.getTotalUss();
13046
13047                synchronized (this) {
13048                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13049                        // Record this for posterity if the process has been stable.
13050                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13051                    }
13052                }
13053
13054                if (!isCheckinRequest && mi != null) {
13055                    totalPss += myTotalPss;
13056                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13057                            (hasActivities ? " / activities)" : ")"),
13058                            r.processName, myTotalPss, pid, hasActivities);
13059                    procMems.add(pssItem);
13060                    procMemsMap.put(pid, pssItem);
13061
13062                    nativePss += mi.nativePss;
13063                    dalvikPss += mi.dalvikPss;
13064                    otherPss += mi.otherPss;
13065                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13066                        long mem = mi.getOtherPss(j);
13067                        miscPss[j] += mem;
13068                        otherPss -= mem;
13069                    }
13070
13071                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13072                        cachedPss += myTotalPss;
13073                    }
13074
13075                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13076                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13077                                || oomIndex == (oomPss.length-1)) {
13078                            oomPss[oomIndex] += myTotalPss;
13079                            if (oomProcs[oomIndex] == null) {
13080                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13081                            }
13082                            oomProcs[oomIndex].add(pssItem);
13083                            break;
13084                        }
13085                    }
13086                }
13087            }
13088        }
13089
13090        long nativeProcTotalPss = 0;
13091
13092        if (!isCheckinRequest && procs.size() > 1) {
13093            // If we are showing aggregations, also look for native processes to
13094            // include so that our aggregations are more accurate.
13095            updateCpuStatsNow();
13096            synchronized (mProcessCpuThread) {
13097                final int N = mProcessCpuTracker.countStats();
13098                for (int i=0; i<N; i++) {
13099                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13100                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13101                        if (mi == null) {
13102                            mi = new Debug.MemoryInfo();
13103                        }
13104                        if (!brief && !oomOnly) {
13105                            Debug.getMemoryInfo(st.pid, mi);
13106                        } else {
13107                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13108                            mi.nativePrivateDirty = (int)tmpLong[0];
13109                        }
13110
13111                        final long myTotalPss = mi.getTotalPss();
13112                        totalPss += myTotalPss;
13113                        nativeProcTotalPss += myTotalPss;
13114
13115                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13116                                st.name, myTotalPss, st.pid, false);
13117                        procMems.add(pssItem);
13118
13119                        nativePss += mi.nativePss;
13120                        dalvikPss += mi.dalvikPss;
13121                        otherPss += mi.otherPss;
13122                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13123                            long mem = mi.getOtherPss(j);
13124                            miscPss[j] += mem;
13125                            otherPss -= mem;
13126                        }
13127                        oomPss[0] += myTotalPss;
13128                        if (oomProcs[0] == null) {
13129                            oomProcs[0] = new ArrayList<MemItem>();
13130                        }
13131                        oomProcs[0].add(pssItem);
13132                    }
13133                }
13134            }
13135
13136            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13137
13138            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13139            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13140            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13141            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13142                String label = Debug.MemoryInfo.getOtherLabel(j);
13143                catMems.add(new MemItem(label, label, miscPss[j], j));
13144            }
13145
13146            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13147            for (int j=0; j<oomPss.length; j++) {
13148                if (oomPss[j] != 0) {
13149                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13150                            : DUMP_MEM_OOM_LABEL[j];
13151                    MemItem item = new MemItem(label, label, oomPss[j],
13152                            DUMP_MEM_OOM_ADJ[j]);
13153                    item.subitems = oomProcs[j];
13154                    oomMems.add(item);
13155                }
13156            }
13157
13158            if (!brief && !oomOnly && !isCompact) {
13159                pw.println();
13160                pw.println("Total PSS by process:");
13161                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13162                pw.println();
13163            }
13164            if (!isCompact) {
13165                pw.println("Total PSS by OOM adjustment:");
13166            }
13167            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13168            if (!brief && !oomOnly) {
13169                PrintWriter out = categoryPw != null ? categoryPw : pw;
13170                if (!isCompact) {
13171                    out.println();
13172                    out.println("Total PSS by category:");
13173                }
13174                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13175            }
13176            if (!isCompact) {
13177                pw.println();
13178            }
13179            MemInfoReader memInfo = new MemInfoReader();
13180            memInfo.readMemInfo();
13181            if (nativeProcTotalPss > 0) {
13182                synchronized (this) {
13183                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13184                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13185                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13186                            nativeProcTotalPss);
13187                }
13188            }
13189            if (!brief) {
13190                if (!isCompact) {
13191                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13192                    pw.print(" kB (status ");
13193                    switch (mLastMemoryLevel) {
13194                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13195                            pw.println("normal)");
13196                            break;
13197                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13198                            pw.println("moderate)");
13199                            break;
13200                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13201                            pw.println("low)");
13202                            break;
13203                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13204                            pw.println("critical)");
13205                            break;
13206                        default:
13207                            pw.print(mLastMemoryLevel);
13208                            pw.println(")");
13209                            break;
13210                    }
13211                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13212                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13213                            pw.print(cachedPss); pw.print(" cached pss + ");
13214                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13215                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13216                } else {
13217                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13218                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13219                            + memInfo.getFreeSizeKb()); pw.print(",");
13220                    pw.println(totalPss - cachedPss);
13221                }
13222            }
13223            if (!isCompact) {
13224                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13225                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13226                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13227                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13228                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13229                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13230                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13231                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13232                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13233                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13234                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13235            }
13236            if (!brief) {
13237                if (memInfo.getZramTotalSizeKb() != 0) {
13238                    if (!isCompact) {
13239                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13240                                pw.print(" kB physical used for ");
13241                                pw.print(memInfo.getSwapTotalSizeKb()
13242                                        - memInfo.getSwapFreeSizeKb());
13243                                pw.print(" kB in swap (");
13244                                pw.print(memInfo.getSwapTotalSizeKb());
13245                                pw.println(" kB total swap)");
13246                    } else {
13247                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13248                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13249                                pw.println(memInfo.getSwapFreeSizeKb());
13250                    }
13251                }
13252                final int[] SINGLE_LONG_FORMAT = new int[] {
13253                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13254                };
13255                long[] longOut = new long[1];
13256                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13257                        SINGLE_LONG_FORMAT, null, longOut, null);
13258                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13259                longOut[0] = 0;
13260                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13261                        SINGLE_LONG_FORMAT, null, longOut, null);
13262                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13263                longOut[0] = 0;
13264                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13265                        SINGLE_LONG_FORMAT, null, longOut, null);
13266                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13267                longOut[0] = 0;
13268                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13269                        SINGLE_LONG_FORMAT, null, longOut, null);
13270                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13271                if (!isCompact) {
13272                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13273                        pw.print("      KSM: "); pw.print(sharing);
13274                                pw.print(" kB saved from shared ");
13275                                pw.print(shared); pw.println(" kB");
13276                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13277                                pw.print(voltile); pw.println(" kB volatile");
13278                    }
13279                    pw.print("   Tuning: ");
13280                    pw.print(ActivityManager.staticGetMemoryClass());
13281                    pw.print(" (large ");
13282                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13283                    pw.print("), oom ");
13284                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13285                    pw.print(" kB");
13286                    pw.print(", restore limit ");
13287                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13288                    pw.print(" kB");
13289                    if (ActivityManager.isLowRamDeviceStatic()) {
13290                        pw.print(" (low-ram)");
13291                    }
13292                    if (ActivityManager.isHighEndGfx()) {
13293                        pw.print(" (high-end-gfx)");
13294                    }
13295                    pw.println();
13296                } else {
13297                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13298                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13299                    pw.println(voltile);
13300                    pw.print("tuning,");
13301                    pw.print(ActivityManager.staticGetMemoryClass());
13302                    pw.print(',');
13303                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13304                    pw.print(',');
13305                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13306                    if (ActivityManager.isLowRamDeviceStatic()) {
13307                        pw.print(",low-ram");
13308                    }
13309                    if (ActivityManager.isHighEndGfx()) {
13310                        pw.print(",high-end-gfx");
13311                    }
13312                    pw.println();
13313                }
13314            }
13315        }
13316    }
13317
13318    /**
13319     * Searches array of arguments for the specified string
13320     * @param args array of argument strings
13321     * @param value value to search for
13322     * @return true if the value is contained in the array
13323     */
13324    private static boolean scanArgs(String[] args, String value) {
13325        if (args != null) {
13326            for (String arg : args) {
13327                if (value.equals(arg)) {
13328                    return true;
13329                }
13330            }
13331        }
13332        return false;
13333    }
13334
13335    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13336            ContentProviderRecord cpr, boolean always) {
13337        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13338
13339        if (!inLaunching || always) {
13340            synchronized (cpr) {
13341                cpr.launchingApp = null;
13342                cpr.notifyAll();
13343            }
13344            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13345            String names[] = cpr.info.authority.split(";");
13346            for (int j = 0; j < names.length; j++) {
13347                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13348            }
13349        }
13350
13351        for (int i=0; i<cpr.connections.size(); i++) {
13352            ContentProviderConnection conn = cpr.connections.get(i);
13353            if (conn.waiting) {
13354                // If this connection is waiting for the provider, then we don't
13355                // need to mess with its process unless we are always removing
13356                // or for some reason the provider is not currently launching.
13357                if (inLaunching && !always) {
13358                    continue;
13359                }
13360            }
13361            ProcessRecord capp = conn.client;
13362            conn.dead = true;
13363            if (conn.stableCount > 0) {
13364                if (!capp.persistent && capp.thread != null
13365                        && capp.pid != 0
13366                        && capp.pid != MY_PID) {
13367                    killUnneededProcessLocked(capp, "depends on provider "
13368                            + cpr.name.flattenToShortString()
13369                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13370                }
13371            } else if (capp.thread != null && conn.provider.provider != null) {
13372                try {
13373                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13374                } catch (RemoteException e) {
13375                }
13376                // In the protocol here, we don't expect the client to correctly
13377                // clean up this connection, we'll just remove it.
13378                cpr.connections.remove(i);
13379                conn.client.conProviders.remove(conn);
13380            }
13381        }
13382
13383        if (inLaunching && always) {
13384            mLaunchingProviders.remove(cpr);
13385        }
13386        return inLaunching;
13387    }
13388
13389    /**
13390     * Main code for cleaning up a process when it has gone away.  This is
13391     * called both as a result of the process dying, or directly when stopping
13392     * a process when running in single process mode.
13393     */
13394    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13395            boolean restarting, boolean allowRestart, int index) {
13396        if (index >= 0) {
13397            removeLruProcessLocked(app);
13398            ProcessList.remove(app.pid);
13399        }
13400
13401        mProcessesToGc.remove(app);
13402        mPendingPssProcesses.remove(app);
13403
13404        // Dismiss any open dialogs.
13405        if (app.crashDialog != null && !app.forceCrashReport) {
13406            app.crashDialog.dismiss();
13407            app.crashDialog = null;
13408        }
13409        if (app.anrDialog != null) {
13410            app.anrDialog.dismiss();
13411            app.anrDialog = null;
13412        }
13413        if (app.waitDialog != null) {
13414            app.waitDialog.dismiss();
13415            app.waitDialog = null;
13416        }
13417
13418        app.crashing = false;
13419        app.notResponding = false;
13420
13421        app.resetPackageList(mProcessStats);
13422        app.unlinkDeathRecipient();
13423        app.makeInactive(mProcessStats);
13424        app.waitingToKill = null;
13425        app.forcingToForeground = null;
13426        updateProcessForegroundLocked(app, false, false);
13427        app.foregroundActivities = false;
13428        app.hasShownUi = false;
13429        app.treatLikeActivity = false;
13430        app.hasAboveClient = false;
13431        app.hasClientActivities = false;
13432
13433        mServices.killServicesLocked(app, allowRestart);
13434
13435        boolean restart = false;
13436
13437        // Remove published content providers.
13438        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13439            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13440            final boolean always = app.bad || !allowRestart;
13441            if (removeDyingProviderLocked(app, cpr, always) || always) {
13442                // We left the provider in the launching list, need to
13443                // restart it.
13444                restart = true;
13445            }
13446
13447            cpr.provider = null;
13448            cpr.proc = null;
13449        }
13450        app.pubProviders.clear();
13451
13452        // Take care of any launching providers waiting for this process.
13453        if (checkAppInLaunchingProvidersLocked(app, false)) {
13454            restart = true;
13455        }
13456
13457        // Unregister from connected content providers.
13458        if (!app.conProviders.isEmpty()) {
13459            for (int i=0; i<app.conProviders.size(); i++) {
13460                ContentProviderConnection conn = app.conProviders.get(i);
13461                conn.provider.connections.remove(conn);
13462            }
13463            app.conProviders.clear();
13464        }
13465
13466        // At this point there may be remaining entries in mLaunchingProviders
13467        // where we were the only one waiting, so they are no longer of use.
13468        // Look for these and clean up if found.
13469        // XXX Commented out for now.  Trying to figure out a way to reproduce
13470        // the actual situation to identify what is actually going on.
13471        if (false) {
13472            for (int i=0; i<mLaunchingProviders.size(); i++) {
13473                ContentProviderRecord cpr = (ContentProviderRecord)
13474                        mLaunchingProviders.get(i);
13475                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13476                    synchronized (cpr) {
13477                        cpr.launchingApp = null;
13478                        cpr.notifyAll();
13479                    }
13480                }
13481            }
13482        }
13483
13484        skipCurrentReceiverLocked(app);
13485
13486        // Unregister any receivers.
13487        for (int i=app.receivers.size()-1; i>=0; i--) {
13488            removeReceiverLocked(app.receivers.valueAt(i));
13489        }
13490        app.receivers.clear();
13491
13492        // If the app is undergoing backup, tell the backup manager about it
13493        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13494            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13495                    + mBackupTarget.appInfo + " died during backup");
13496            try {
13497                IBackupManager bm = IBackupManager.Stub.asInterface(
13498                        ServiceManager.getService(Context.BACKUP_SERVICE));
13499                bm.agentDisconnected(app.info.packageName);
13500            } catch (RemoteException e) {
13501                // can't happen; backup manager is local
13502            }
13503        }
13504
13505        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13506            ProcessChangeItem item = mPendingProcessChanges.get(i);
13507            if (item.pid == app.pid) {
13508                mPendingProcessChanges.remove(i);
13509                mAvailProcessChanges.add(item);
13510            }
13511        }
13512        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13513
13514        // If the caller is restarting this app, then leave it in its
13515        // current lists and let the caller take care of it.
13516        if (restarting) {
13517            return;
13518        }
13519
13520        if (!app.persistent || app.isolated) {
13521            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13522                    "Removing non-persistent process during cleanup: " + app);
13523            mProcessNames.remove(app.processName, app.uid);
13524            mIsolatedProcesses.remove(app.uid);
13525            if (mHeavyWeightProcess == app) {
13526                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13527                        mHeavyWeightProcess.userId, 0));
13528                mHeavyWeightProcess = null;
13529            }
13530        } else if (!app.removed) {
13531            // This app is persistent, so we need to keep its record around.
13532            // If it is not already on the pending app list, add it there
13533            // and start a new process for it.
13534            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13535                mPersistentStartingProcesses.add(app);
13536                restart = true;
13537            }
13538        }
13539        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13540                "Clean-up removing on hold: " + app);
13541        mProcessesOnHold.remove(app);
13542
13543        if (app == mHomeProcess) {
13544            mHomeProcess = null;
13545        }
13546        if (app == mPreviousProcess) {
13547            mPreviousProcess = null;
13548        }
13549
13550        if (restart && !app.isolated) {
13551            // We have components that still need to be running in the
13552            // process, so re-launch it.
13553            mProcessNames.put(app.processName, app.uid, app);
13554            startProcessLocked(app, "restart", app.processName);
13555        } else if (app.pid > 0 && app.pid != MY_PID) {
13556            // Goodbye!
13557            boolean removed;
13558            synchronized (mPidsSelfLocked) {
13559                mPidsSelfLocked.remove(app.pid);
13560                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13561            }
13562            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13563            if (app.isolated) {
13564                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13565            }
13566            app.setPid(0);
13567        }
13568    }
13569
13570    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13571        // Look through the content providers we are waiting to have launched,
13572        // and if any run in this process then either schedule a restart of
13573        // the process or kill the client waiting for it if this process has
13574        // gone bad.
13575        int NL = mLaunchingProviders.size();
13576        boolean restart = false;
13577        for (int i=0; i<NL; i++) {
13578            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13579            if (cpr.launchingApp == app) {
13580                if (!alwaysBad && !app.bad) {
13581                    restart = true;
13582                } else {
13583                    removeDyingProviderLocked(app, cpr, true);
13584                    // cpr should have been removed from mLaunchingProviders
13585                    NL = mLaunchingProviders.size();
13586                    i--;
13587                }
13588            }
13589        }
13590        return restart;
13591    }
13592
13593    // =========================================================
13594    // SERVICES
13595    // =========================================================
13596
13597    @Override
13598    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13599            int flags) {
13600        enforceNotIsolatedCaller("getServices");
13601        synchronized (this) {
13602            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13603        }
13604    }
13605
13606    @Override
13607    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13608        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13609        synchronized (this) {
13610            return mServices.getRunningServiceControlPanelLocked(name);
13611        }
13612    }
13613
13614    @Override
13615    public ComponentName startService(IApplicationThread caller, Intent service,
13616            String resolvedType, int userId) {
13617        enforceNotIsolatedCaller("startService");
13618        // Refuse possible leaked file descriptors
13619        if (service != null && service.hasFileDescriptors() == true) {
13620            throw new IllegalArgumentException("File descriptors passed in Intent");
13621        }
13622
13623        if (DEBUG_SERVICE)
13624            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13625        synchronized(this) {
13626            final int callingPid = Binder.getCallingPid();
13627            final int callingUid = Binder.getCallingUid();
13628            final long origId = Binder.clearCallingIdentity();
13629            ComponentName res = mServices.startServiceLocked(caller, service,
13630                    resolvedType, callingPid, callingUid, userId);
13631            Binder.restoreCallingIdentity(origId);
13632            return res;
13633        }
13634    }
13635
13636    ComponentName startServiceInPackage(int uid,
13637            Intent service, String resolvedType, int userId) {
13638        synchronized(this) {
13639            if (DEBUG_SERVICE)
13640                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13641            final long origId = Binder.clearCallingIdentity();
13642            ComponentName res = mServices.startServiceLocked(null, service,
13643                    resolvedType, -1, uid, userId);
13644            Binder.restoreCallingIdentity(origId);
13645            return res;
13646        }
13647    }
13648
13649    @Override
13650    public int stopService(IApplicationThread caller, Intent service,
13651            String resolvedType, int userId) {
13652        enforceNotIsolatedCaller("stopService");
13653        // Refuse possible leaked file descriptors
13654        if (service != null && service.hasFileDescriptors() == true) {
13655            throw new IllegalArgumentException("File descriptors passed in Intent");
13656        }
13657
13658        synchronized(this) {
13659            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13660        }
13661    }
13662
13663    @Override
13664    public IBinder peekService(Intent service, String resolvedType) {
13665        enforceNotIsolatedCaller("peekService");
13666        // Refuse possible leaked file descriptors
13667        if (service != null && service.hasFileDescriptors() == true) {
13668            throw new IllegalArgumentException("File descriptors passed in Intent");
13669        }
13670        synchronized(this) {
13671            return mServices.peekServiceLocked(service, resolvedType);
13672        }
13673    }
13674
13675    @Override
13676    public boolean stopServiceToken(ComponentName className, IBinder token,
13677            int startId) {
13678        synchronized(this) {
13679            return mServices.stopServiceTokenLocked(className, token, startId);
13680        }
13681    }
13682
13683    @Override
13684    public void setServiceForeground(ComponentName className, IBinder token,
13685            int id, Notification notification, boolean removeNotification) {
13686        synchronized(this) {
13687            mServices.setServiceForegroundLocked(className, token, id, notification,
13688                    removeNotification);
13689        }
13690    }
13691
13692    @Override
13693    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13694            boolean requireFull, String name, String callerPackage) {
13695        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13696                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13697    }
13698
13699    int unsafeConvertIncomingUser(int userId) {
13700        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13701                ? mCurrentUserId : userId;
13702    }
13703
13704    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13705            int allowMode, String name, String callerPackage) {
13706        final int callingUserId = UserHandle.getUserId(callingUid);
13707        if (callingUserId == userId) {
13708            return userId;
13709        }
13710
13711        // Note that we may be accessing mCurrentUserId outside of a lock...
13712        // shouldn't be a big deal, if this is being called outside
13713        // of a locked context there is intrinsically a race with
13714        // the value the caller will receive and someone else changing it.
13715        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13716        // we will switch to the calling user if access to the current user fails.
13717        int targetUserId = unsafeConvertIncomingUser(userId);
13718
13719        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13720            final boolean allow;
13721            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13722                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13723                // If the caller has this permission, they always pass go.  And collect $200.
13724                allow = true;
13725            } else if (allowMode == ALLOW_FULL_ONLY) {
13726                // We require full access, sucks to be you.
13727                allow = false;
13728            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13729                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13730                // If the caller does not have either permission, they are always doomed.
13731                allow = false;
13732            } else if (allowMode == ALLOW_NON_FULL) {
13733                // We are blanket allowing non-full access, you lucky caller!
13734                allow = true;
13735            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13736                // We may or may not allow this depending on whether the two users are
13737                // in the same profile.
13738                synchronized (mUserProfileGroupIdsSelfLocked) {
13739                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13740                            UserInfo.NO_PROFILE_GROUP_ID);
13741                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13742                            UserInfo.NO_PROFILE_GROUP_ID);
13743                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13744                            && callingProfile == targetProfile;
13745                }
13746            } else {
13747                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13748            }
13749            if (!allow) {
13750                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13751                    // In this case, they would like to just execute as their
13752                    // owner user instead of failing.
13753                    targetUserId = callingUserId;
13754                } else {
13755                    StringBuilder builder = new StringBuilder(128);
13756                    builder.append("Permission Denial: ");
13757                    builder.append(name);
13758                    if (callerPackage != null) {
13759                        builder.append(" from ");
13760                        builder.append(callerPackage);
13761                    }
13762                    builder.append(" asks to run as user ");
13763                    builder.append(userId);
13764                    builder.append(" but is calling from user ");
13765                    builder.append(UserHandle.getUserId(callingUid));
13766                    builder.append("; this requires ");
13767                    builder.append(INTERACT_ACROSS_USERS_FULL);
13768                    if (allowMode != ALLOW_FULL_ONLY) {
13769                        builder.append(" or ");
13770                        builder.append(INTERACT_ACROSS_USERS);
13771                    }
13772                    String msg = builder.toString();
13773                    Slog.w(TAG, msg);
13774                    throw new SecurityException(msg);
13775                }
13776            }
13777        }
13778        if (!allowAll && targetUserId < 0) {
13779            throw new IllegalArgumentException(
13780                    "Call does not support special user #" + targetUserId);
13781        }
13782        return targetUserId;
13783    }
13784
13785    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13786            String className, int flags) {
13787        boolean result = false;
13788        // For apps that don't have pre-defined UIDs, check for permission
13789        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13790            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13791                if (ActivityManager.checkUidPermission(
13792                        INTERACT_ACROSS_USERS,
13793                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13794                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13795                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13796                            + " requests FLAG_SINGLE_USER, but app does not hold "
13797                            + INTERACT_ACROSS_USERS;
13798                    Slog.w(TAG, msg);
13799                    throw new SecurityException(msg);
13800                }
13801                // Permission passed
13802                result = true;
13803            }
13804        } else if ("system".equals(componentProcessName)) {
13805            result = true;
13806        } else {
13807            // App with pre-defined UID, check if it's a persistent app
13808            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13809        }
13810        if (DEBUG_MU) {
13811            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13812                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13813        }
13814        return result;
13815    }
13816
13817    /**
13818     * Checks to see if the caller is in the same app as the singleton
13819     * component, or the component is in a special app. It allows special apps
13820     * to export singleton components but prevents exporting singleton
13821     * components for regular apps.
13822     */
13823    boolean isValidSingletonCall(int callingUid, int componentUid) {
13824        int componentAppId = UserHandle.getAppId(componentUid);
13825        return UserHandle.isSameApp(callingUid, componentUid)
13826                || componentAppId == Process.SYSTEM_UID
13827                || componentAppId == Process.PHONE_UID
13828                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13829                        == PackageManager.PERMISSION_GRANTED;
13830    }
13831
13832    public int bindService(IApplicationThread caller, IBinder token,
13833            Intent service, String resolvedType,
13834            IServiceConnection connection, int flags, int userId) {
13835        enforceNotIsolatedCaller("bindService");
13836        // Refuse possible leaked file descriptors
13837        if (service != null && service.hasFileDescriptors() == true) {
13838            throw new IllegalArgumentException("File descriptors passed in Intent");
13839        }
13840
13841        synchronized(this) {
13842            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13843                    connection, flags, userId);
13844        }
13845    }
13846
13847    public boolean unbindService(IServiceConnection connection) {
13848        synchronized (this) {
13849            return mServices.unbindServiceLocked(connection);
13850        }
13851    }
13852
13853    public void publishService(IBinder token, Intent intent, IBinder service) {
13854        // Refuse possible leaked file descriptors
13855        if (intent != null && intent.hasFileDescriptors() == true) {
13856            throw new IllegalArgumentException("File descriptors passed in Intent");
13857        }
13858
13859        synchronized(this) {
13860            if (!(token instanceof ServiceRecord)) {
13861                throw new IllegalArgumentException("Invalid service token");
13862            }
13863            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13864        }
13865    }
13866
13867    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13868        // Refuse possible leaked file descriptors
13869        if (intent != null && intent.hasFileDescriptors() == true) {
13870            throw new IllegalArgumentException("File descriptors passed in Intent");
13871        }
13872
13873        synchronized(this) {
13874            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13875        }
13876    }
13877
13878    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13879        synchronized(this) {
13880            if (!(token instanceof ServiceRecord)) {
13881                throw new IllegalArgumentException("Invalid service token");
13882            }
13883            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13884        }
13885    }
13886
13887    // =========================================================
13888    // BACKUP AND RESTORE
13889    // =========================================================
13890
13891    // Cause the target app to be launched if necessary and its backup agent
13892    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13893    // activity manager to announce its creation.
13894    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13895        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13896        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13897
13898        synchronized(this) {
13899            // !!! TODO: currently no check here that we're already bound
13900            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13901            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13902            synchronized (stats) {
13903                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13904            }
13905
13906            // Backup agent is now in use, its package can't be stopped.
13907            try {
13908                AppGlobals.getPackageManager().setPackageStoppedState(
13909                        app.packageName, false, UserHandle.getUserId(app.uid));
13910            } catch (RemoteException e) {
13911            } catch (IllegalArgumentException e) {
13912                Slog.w(TAG, "Failed trying to unstop package "
13913                        + app.packageName + ": " + e);
13914            }
13915
13916            BackupRecord r = new BackupRecord(ss, app, backupMode);
13917            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13918                    ? new ComponentName(app.packageName, app.backupAgentName)
13919                    : new ComponentName("android", "FullBackupAgent");
13920            // startProcessLocked() returns existing proc's record if it's already running
13921            ProcessRecord proc = startProcessLocked(app.processName, app,
13922                    false, 0, "backup", hostingName, false, false, false);
13923            if (proc == null) {
13924                Slog.e(TAG, "Unable to start backup agent process " + r);
13925                return false;
13926            }
13927
13928            r.app = proc;
13929            mBackupTarget = r;
13930            mBackupAppName = app.packageName;
13931
13932            // Try not to kill the process during backup
13933            updateOomAdjLocked(proc);
13934
13935            // If the process is already attached, schedule the creation of the backup agent now.
13936            // If it is not yet live, this will be done when it attaches to the framework.
13937            if (proc.thread != null) {
13938                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13939                try {
13940                    proc.thread.scheduleCreateBackupAgent(app,
13941                            compatibilityInfoForPackageLocked(app), backupMode);
13942                } catch (RemoteException e) {
13943                    // Will time out on the backup manager side
13944                }
13945            } else {
13946                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13947            }
13948            // Invariants: at this point, the target app process exists and the application
13949            // is either already running or in the process of coming up.  mBackupTarget and
13950            // mBackupAppName describe the app, so that when it binds back to the AM we
13951            // know that it's scheduled for a backup-agent operation.
13952        }
13953
13954        return true;
13955    }
13956
13957    @Override
13958    public void clearPendingBackup() {
13959        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13960        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13961
13962        synchronized (this) {
13963            mBackupTarget = null;
13964            mBackupAppName = null;
13965        }
13966    }
13967
13968    // A backup agent has just come up
13969    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13970        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13971                + " = " + agent);
13972
13973        synchronized(this) {
13974            if (!agentPackageName.equals(mBackupAppName)) {
13975                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13976                return;
13977            }
13978        }
13979
13980        long oldIdent = Binder.clearCallingIdentity();
13981        try {
13982            IBackupManager bm = IBackupManager.Stub.asInterface(
13983                    ServiceManager.getService(Context.BACKUP_SERVICE));
13984            bm.agentConnected(agentPackageName, agent);
13985        } catch (RemoteException e) {
13986            // can't happen; the backup manager service is local
13987        } catch (Exception e) {
13988            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13989            e.printStackTrace();
13990        } finally {
13991            Binder.restoreCallingIdentity(oldIdent);
13992        }
13993    }
13994
13995    // done with this agent
13996    public void unbindBackupAgent(ApplicationInfo appInfo) {
13997        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13998        if (appInfo == null) {
13999            Slog.w(TAG, "unbind backup agent for null app");
14000            return;
14001        }
14002
14003        synchronized(this) {
14004            try {
14005                if (mBackupAppName == null) {
14006                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14007                    return;
14008                }
14009
14010                if (!mBackupAppName.equals(appInfo.packageName)) {
14011                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14012                    return;
14013                }
14014
14015                // Not backing this app up any more; reset its OOM adjustment
14016                final ProcessRecord proc = mBackupTarget.app;
14017                updateOomAdjLocked(proc);
14018
14019                // If the app crashed during backup, 'thread' will be null here
14020                if (proc.thread != null) {
14021                    try {
14022                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14023                                compatibilityInfoForPackageLocked(appInfo));
14024                    } catch (Exception e) {
14025                        Slog.e(TAG, "Exception when unbinding backup agent:");
14026                        e.printStackTrace();
14027                    }
14028                }
14029            } finally {
14030                mBackupTarget = null;
14031                mBackupAppName = null;
14032            }
14033        }
14034    }
14035    // =========================================================
14036    // BROADCASTS
14037    // =========================================================
14038
14039    private final List getStickiesLocked(String action, IntentFilter filter,
14040            List cur, int userId) {
14041        final ContentResolver resolver = mContext.getContentResolver();
14042        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14043        if (stickies == null) {
14044            return cur;
14045        }
14046        final ArrayList<Intent> list = stickies.get(action);
14047        if (list == null) {
14048            return cur;
14049        }
14050        int N = list.size();
14051        for (int i=0; i<N; i++) {
14052            Intent intent = list.get(i);
14053            if (filter.match(resolver, intent, true, TAG) >= 0) {
14054                if (cur == null) {
14055                    cur = new ArrayList<Intent>();
14056                }
14057                cur.add(intent);
14058            }
14059        }
14060        return cur;
14061    }
14062
14063    boolean isPendingBroadcastProcessLocked(int pid) {
14064        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14065                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14066    }
14067
14068    void skipPendingBroadcastLocked(int pid) {
14069            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14070            for (BroadcastQueue queue : mBroadcastQueues) {
14071                queue.skipPendingBroadcastLocked(pid);
14072            }
14073    }
14074
14075    // The app just attached; send any pending broadcasts that it should receive
14076    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14077        boolean didSomething = false;
14078        for (BroadcastQueue queue : mBroadcastQueues) {
14079            didSomething |= queue.sendPendingBroadcastsLocked(app);
14080        }
14081        return didSomething;
14082    }
14083
14084    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14085            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14086        enforceNotIsolatedCaller("registerReceiver");
14087        int callingUid;
14088        int callingPid;
14089        synchronized(this) {
14090            ProcessRecord callerApp = null;
14091            if (caller != null) {
14092                callerApp = getRecordForAppLocked(caller);
14093                if (callerApp == null) {
14094                    throw new SecurityException(
14095                            "Unable to find app for caller " + caller
14096                            + " (pid=" + Binder.getCallingPid()
14097                            + ") when registering receiver " + receiver);
14098                }
14099                if (callerApp.info.uid != Process.SYSTEM_UID &&
14100                        !callerApp.pkgList.containsKey(callerPackage) &&
14101                        !"android".equals(callerPackage)) {
14102                    throw new SecurityException("Given caller package " + callerPackage
14103                            + " is not running in process " + callerApp);
14104                }
14105                callingUid = callerApp.info.uid;
14106                callingPid = callerApp.pid;
14107            } else {
14108                callerPackage = null;
14109                callingUid = Binder.getCallingUid();
14110                callingPid = Binder.getCallingPid();
14111            }
14112
14113            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14114                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14115
14116            List allSticky = null;
14117
14118            // Look for any matching sticky broadcasts...
14119            Iterator actions = filter.actionsIterator();
14120            if (actions != null) {
14121                while (actions.hasNext()) {
14122                    String action = (String)actions.next();
14123                    allSticky = getStickiesLocked(action, filter, allSticky,
14124                            UserHandle.USER_ALL);
14125                    allSticky = getStickiesLocked(action, filter, allSticky,
14126                            UserHandle.getUserId(callingUid));
14127                }
14128            } else {
14129                allSticky = getStickiesLocked(null, filter, allSticky,
14130                        UserHandle.USER_ALL);
14131                allSticky = getStickiesLocked(null, filter, allSticky,
14132                        UserHandle.getUserId(callingUid));
14133            }
14134
14135            // The first sticky in the list is returned directly back to
14136            // the client.
14137            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14138
14139            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14140                    + ": " + sticky);
14141
14142            if (receiver == null) {
14143                return sticky;
14144            }
14145
14146            ReceiverList rl
14147                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14148            if (rl == null) {
14149                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14150                        userId, receiver);
14151                if (rl.app != null) {
14152                    rl.app.receivers.add(rl);
14153                } else {
14154                    try {
14155                        receiver.asBinder().linkToDeath(rl, 0);
14156                    } catch (RemoteException e) {
14157                        return sticky;
14158                    }
14159                    rl.linkedToDeath = true;
14160                }
14161                mRegisteredReceivers.put(receiver.asBinder(), rl);
14162            } else if (rl.uid != callingUid) {
14163                throw new IllegalArgumentException(
14164                        "Receiver requested to register for uid " + callingUid
14165                        + " was previously registered for uid " + rl.uid);
14166            } else if (rl.pid != callingPid) {
14167                throw new IllegalArgumentException(
14168                        "Receiver requested to register for pid " + callingPid
14169                        + " was previously registered for pid " + rl.pid);
14170            } else if (rl.userId != userId) {
14171                throw new IllegalArgumentException(
14172                        "Receiver requested to register for user " + userId
14173                        + " was previously registered for user " + rl.userId);
14174            }
14175            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14176                    permission, callingUid, userId);
14177            rl.add(bf);
14178            if (!bf.debugCheck()) {
14179                Slog.w(TAG, "==> For Dynamic broadast");
14180            }
14181            mReceiverResolver.addFilter(bf);
14182
14183            // Enqueue broadcasts for all existing stickies that match
14184            // this filter.
14185            if (allSticky != null) {
14186                ArrayList receivers = new ArrayList();
14187                receivers.add(bf);
14188
14189                int N = allSticky.size();
14190                for (int i=0; i<N; i++) {
14191                    Intent intent = (Intent)allSticky.get(i);
14192                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14193                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14194                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14195                            null, null, false, true, true, -1);
14196                    queue.enqueueParallelBroadcastLocked(r);
14197                    queue.scheduleBroadcastsLocked();
14198                }
14199            }
14200
14201            return sticky;
14202        }
14203    }
14204
14205    public void unregisterReceiver(IIntentReceiver receiver) {
14206        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14207
14208        final long origId = Binder.clearCallingIdentity();
14209        try {
14210            boolean doTrim = false;
14211
14212            synchronized(this) {
14213                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14214                if (rl != null) {
14215                    if (rl.curBroadcast != null) {
14216                        BroadcastRecord r = rl.curBroadcast;
14217                        final boolean doNext = finishReceiverLocked(
14218                                receiver.asBinder(), r.resultCode, r.resultData,
14219                                r.resultExtras, r.resultAbort);
14220                        if (doNext) {
14221                            doTrim = true;
14222                            r.queue.processNextBroadcast(false);
14223                        }
14224                    }
14225
14226                    if (rl.app != null) {
14227                        rl.app.receivers.remove(rl);
14228                    }
14229                    removeReceiverLocked(rl);
14230                    if (rl.linkedToDeath) {
14231                        rl.linkedToDeath = false;
14232                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14233                    }
14234                }
14235            }
14236
14237            // If we actually concluded any broadcasts, we might now be able
14238            // to trim the recipients' apps from our working set
14239            if (doTrim) {
14240                trimApplications();
14241                return;
14242            }
14243
14244        } finally {
14245            Binder.restoreCallingIdentity(origId);
14246        }
14247    }
14248
14249    void removeReceiverLocked(ReceiverList rl) {
14250        mRegisteredReceivers.remove(rl.receiver.asBinder());
14251        int N = rl.size();
14252        for (int i=0; i<N; i++) {
14253            mReceiverResolver.removeFilter(rl.get(i));
14254        }
14255    }
14256
14257    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14258        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14259            ProcessRecord r = mLruProcesses.get(i);
14260            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14261                try {
14262                    r.thread.dispatchPackageBroadcast(cmd, packages);
14263                } catch (RemoteException ex) {
14264                }
14265            }
14266        }
14267    }
14268
14269    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14270            int[] users) {
14271        List<ResolveInfo> receivers = null;
14272        try {
14273            HashSet<ComponentName> singleUserReceivers = null;
14274            boolean scannedFirstReceivers = false;
14275            for (int user : users) {
14276                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14277                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14278                if (user != 0 && newReceivers != null) {
14279                    // If this is not the primary user, we need to check for
14280                    // any receivers that should be filtered out.
14281                    for (int i=0; i<newReceivers.size(); i++) {
14282                        ResolveInfo ri = newReceivers.get(i);
14283                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14284                            newReceivers.remove(i);
14285                            i--;
14286                        }
14287                    }
14288                }
14289                if (newReceivers != null && newReceivers.size() == 0) {
14290                    newReceivers = null;
14291                }
14292                if (receivers == null) {
14293                    receivers = newReceivers;
14294                } else if (newReceivers != null) {
14295                    // We need to concatenate the additional receivers
14296                    // found with what we have do far.  This would be easy,
14297                    // but we also need to de-dup any receivers that are
14298                    // singleUser.
14299                    if (!scannedFirstReceivers) {
14300                        // Collect any single user receivers we had already retrieved.
14301                        scannedFirstReceivers = true;
14302                        for (int i=0; i<receivers.size(); i++) {
14303                            ResolveInfo ri = receivers.get(i);
14304                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14305                                ComponentName cn = new ComponentName(
14306                                        ri.activityInfo.packageName, ri.activityInfo.name);
14307                                if (singleUserReceivers == null) {
14308                                    singleUserReceivers = new HashSet<ComponentName>();
14309                                }
14310                                singleUserReceivers.add(cn);
14311                            }
14312                        }
14313                    }
14314                    // Add the new results to the existing results, tracking
14315                    // and de-dupping single user receivers.
14316                    for (int i=0; i<newReceivers.size(); i++) {
14317                        ResolveInfo ri = newReceivers.get(i);
14318                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14319                            ComponentName cn = new ComponentName(
14320                                    ri.activityInfo.packageName, ri.activityInfo.name);
14321                            if (singleUserReceivers == null) {
14322                                singleUserReceivers = new HashSet<ComponentName>();
14323                            }
14324                            if (!singleUserReceivers.contains(cn)) {
14325                                singleUserReceivers.add(cn);
14326                                receivers.add(ri);
14327                            }
14328                        } else {
14329                            receivers.add(ri);
14330                        }
14331                    }
14332                }
14333            }
14334        } catch (RemoteException ex) {
14335            // pm is in same process, this will never happen.
14336        }
14337        return receivers;
14338    }
14339
14340    private final int broadcastIntentLocked(ProcessRecord callerApp,
14341            String callerPackage, Intent intent, String resolvedType,
14342            IIntentReceiver resultTo, int resultCode, String resultData,
14343            Bundle map, String requiredPermission, int appOp,
14344            boolean ordered, boolean sticky, int callingPid, int callingUid,
14345            int userId) {
14346        intent = new Intent(intent);
14347
14348        // By default broadcasts do not go to stopped apps.
14349        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14350
14351        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14352            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14353            + " ordered=" + ordered + " userid=" + userId);
14354        if ((resultTo != null) && !ordered) {
14355            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14356        }
14357
14358        userId = handleIncomingUser(callingPid, callingUid, userId,
14359                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14360
14361        // Make sure that the user who is receiving this broadcast is started.
14362        // If not, we will just skip it.
14363
14364
14365        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14366            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14367                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14368                Slog.w(TAG, "Skipping broadcast of " + intent
14369                        + ": user " + userId + " is stopped");
14370                return ActivityManager.BROADCAST_SUCCESS;
14371            }
14372        }
14373
14374        /*
14375         * Prevent non-system code (defined here to be non-persistent
14376         * processes) from sending protected broadcasts.
14377         */
14378        int callingAppId = UserHandle.getAppId(callingUid);
14379        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14380            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14381            || callingAppId == Process.NFC_UID || callingUid == 0) {
14382            // Always okay.
14383        } else if (callerApp == null || !callerApp.persistent) {
14384            try {
14385                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14386                        intent.getAction())) {
14387                    String msg = "Permission Denial: not allowed to send broadcast "
14388                            + intent.getAction() + " from pid="
14389                            + callingPid + ", uid=" + callingUid;
14390                    Slog.w(TAG, msg);
14391                    throw new SecurityException(msg);
14392                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14393                    // Special case for compatibility: we don't want apps to send this,
14394                    // but historically it has not been protected and apps may be using it
14395                    // to poke their own app widget.  So, instead of making it protected,
14396                    // just limit it to the caller.
14397                    if (callerApp == null) {
14398                        String msg = "Permission Denial: not allowed to send broadcast "
14399                                + intent.getAction() + " from unknown caller.";
14400                        Slog.w(TAG, msg);
14401                        throw new SecurityException(msg);
14402                    } else if (intent.getComponent() != null) {
14403                        // They are good enough to send to an explicit component...  verify
14404                        // it is being sent to the calling app.
14405                        if (!intent.getComponent().getPackageName().equals(
14406                                callerApp.info.packageName)) {
14407                            String msg = "Permission Denial: not allowed to send broadcast "
14408                                    + intent.getAction() + " to "
14409                                    + intent.getComponent().getPackageName() + " from "
14410                                    + callerApp.info.packageName;
14411                            Slog.w(TAG, msg);
14412                            throw new SecurityException(msg);
14413                        }
14414                    } else {
14415                        // Limit broadcast to their own package.
14416                        intent.setPackage(callerApp.info.packageName);
14417                    }
14418                }
14419            } catch (RemoteException e) {
14420                Slog.w(TAG, "Remote exception", e);
14421                return ActivityManager.BROADCAST_SUCCESS;
14422            }
14423        }
14424
14425        // Handle special intents: if this broadcast is from the package
14426        // manager about a package being removed, we need to remove all of
14427        // its activities from the history stack.
14428        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14429                intent.getAction());
14430        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14431                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14432                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14433                || uidRemoved) {
14434            if (checkComponentPermission(
14435                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14436                    callingPid, callingUid, -1, true)
14437                    == PackageManager.PERMISSION_GRANTED) {
14438                if (uidRemoved) {
14439                    final Bundle intentExtras = intent.getExtras();
14440                    final int uid = intentExtras != null
14441                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14442                    if (uid >= 0) {
14443                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14444                        synchronized (bs) {
14445                            bs.removeUidStatsLocked(uid);
14446                        }
14447                        mAppOpsService.uidRemoved(uid);
14448                    }
14449                } else {
14450                    // If resources are unavailable just force stop all
14451                    // those packages and flush the attribute cache as well.
14452                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14453                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14454                        if (list != null && (list.length > 0)) {
14455                            for (String pkg : list) {
14456                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14457                                        "storage unmount");
14458                            }
14459                            sendPackageBroadcastLocked(
14460                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14461                        }
14462                    } else {
14463                        Uri data = intent.getData();
14464                        String ssp;
14465                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14466                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14467                                    intent.getAction());
14468                            boolean fullUninstall = removed &&
14469                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14470                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14471                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14472                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14473                                        false, fullUninstall, userId,
14474                                        removed ? "pkg removed" : "pkg changed");
14475                            }
14476                            if (removed) {
14477                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14478                                        new String[] {ssp}, userId);
14479                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14480                                    mAppOpsService.packageRemoved(
14481                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14482
14483                                    // Remove all permissions granted from/to this package
14484                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14485                                }
14486                            }
14487                        }
14488                    }
14489                }
14490            } else {
14491                String msg = "Permission Denial: " + intent.getAction()
14492                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14493                        + ", uid=" + callingUid + ")"
14494                        + " requires "
14495                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14496                Slog.w(TAG, msg);
14497                throw new SecurityException(msg);
14498            }
14499
14500        // Special case for adding a package: by default turn on compatibility
14501        // mode.
14502        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14503            Uri data = intent.getData();
14504            String ssp;
14505            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14506                mCompatModePackages.handlePackageAddedLocked(ssp,
14507                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14508            }
14509        }
14510
14511        /*
14512         * If this is the time zone changed action, queue up a message that will reset the timezone
14513         * of all currently running processes. This message will get queued up before the broadcast
14514         * happens.
14515         */
14516        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14517            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14518        }
14519
14520        /*
14521         * If the user set the time, let all running processes know.
14522         */
14523        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14524            final int is24Hour = intent.getBooleanExtra(
14525                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14526            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14527        }
14528
14529        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14530            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14531        }
14532
14533        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14534            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14535            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14536        }
14537
14538        // Add to the sticky list if requested.
14539        if (sticky) {
14540            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14541                    callingPid, callingUid)
14542                    != PackageManager.PERMISSION_GRANTED) {
14543                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14544                        + callingPid + ", uid=" + callingUid
14545                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14546                Slog.w(TAG, msg);
14547                throw new SecurityException(msg);
14548            }
14549            if (requiredPermission != null) {
14550                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14551                        + " and enforce permission " + requiredPermission);
14552                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14553            }
14554            if (intent.getComponent() != null) {
14555                throw new SecurityException(
14556                        "Sticky broadcasts can't target a specific component");
14557            }
14558            // We use userId directly here, since the "all" target is maintained
14559            // as a separate set of sticky broadcasts.
14560            if (userId != UserHandle.USER_ALL) {
14561                // But first, if this is not a broadcast to all users, then
14562                // make sure it doesn't conflict with an existing broadcast to
14563                // all users.
14564                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14565                        UserHandle.USER_ALL);
14566                if (stickies != null) {
14567                    ArrayList<Intent> list = stickies.get(intent.getAction());
14568                    if (list != null) {
14569                        int N = list.size();
14570                        int i;
14571                        for (i=0; i<N; i++) {
14572                            if (intent.filterEquals(list.get(i))) {
14573                                throw new IllegalArgumentException(
14574                                        "Sticky broadcast " + intent + " for user "
14575                                        + userId + " conflicts with existing global broadcast");
14576                            }
14577                        }
14578                    }
14579                }
14580            }
14581            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14582            if (stickies == null) {
14583                stickies = new ArrayMap<String, ArrayList<Intent>>();
14584                mStickyBroadcasts.put(userId, stickies);
14585            }
14586            ArrayList<Intent> list = stickies.get(intent.getAction());
14587            if (list == null) {
14588                list = new ArrayList<Intent>();
14589                stickies.put(intent.getAction(), list);
14590            }
14591            int N = list.size();
14592            int i;
14593            for (i=0; i<N; i++) {
14594                if (intent.filterEquals(list.get(i))) {
14595                    // This sticky already exists, replace it.
14596                    list.set(i, new Intent(intent));
14597                    break;
14598                }
14599            }
14600            if (i >= N) {
14601                list.add(new Intent(intent));
14602            }
14603        }
14604
14605        int[] users;
14606        if (userId == UserHandle.USER_ALL) {
14607            // Caller wants broadcast to go to all started users.
14608            users = mStartedUserArray;
14609        } else {
14610            // Caller wants broadcast to go to one specific user.
14611            users = new int[] {userId};
14612        }
14613
14614        // Figure out who all will receive this broadcast.
14615        List receivers = null;
14616        List<BroadcastFilter> registeredReceivers = null;
14617        // Need to resolve the intent to interested receivers...
14618        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14619                 == 0) {
14620            receivers = collectReceiverComponents(intent, resolvedType, users);
14621        }
14622        if (intent.getComponent() == null) {
14623            registeredReceivers = mReceiverResolver.queryIntent(intent,
14624                    resolvedType, false, userId);
14625        }
14626
14627        final boolean replacePending =
14628                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14629
14630        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14631                + " replacePending=" + replacePending);
14632
14633        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14634        if (!ordered && NR > 0) {
14635            // If we are not serializing this broadcast, then send the
14636            // registered receivers separately so they don't wait for the
14637            // components to be launched.
14638            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14639            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14640                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14641                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14642                    ordered, sticky, false, userId);
14643            if (DEBUG_BROADCAST) Slog.v(
14644                    TAG, "Enqueueing parallel broadcast " + r);
14645            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14646            if (!replaced) {
14647                queue.enqueueParallelBroadcastLocked(r);
14648                queue.scheduleBroadcastsLocked();
14649            }
14650            registeredReceivers = null;
14651            NR = 0;
14652        }
14653
14654        // Merge into one list.
14655        int ir = 0;
14656        if (receivers != null) {
14657            // A special case for PACKAGE_ADDED: do not allow the package
14658            // being added to see this broadcast.  This prevents them from
14659            // using this as a back door to get run as soon as they are
14660            // installed.  Maybe in the future we want to have a special install
14661            // broadcast or such for apps, but we'd like to deliberately make
14662            // this decision.
14663            String skipPackages[] = null;
14664            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14665                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14666                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14667                Uri data = intent.getData();
14668                if (data != null) {
14669                    String pkgName = data.getSchemeSpecificPart();
14670                    if (pkgName != null) {
14671                        skipPackages = new String[] { pkgName };
14672                    }
14673                }
14674            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14675                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14676            }
14677            if (skipPackages != null && (skipPackages.length > 0)) {
14678                for (String skipPackage : skipPackages) {
14679                    if (skipPackage != null) {
14680                        int NT = receivers.size();
14681                        for (int it=0; it<NT; it++) {
14682                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14683                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14684                                receivers.remove(it);
14685                                it--;
14686                                NT--;
14687                            }
14688                        }
14689                    }
14690                }
14691            }
14692
14693            int NT = receivers != null ? receivers.size() : 0;
14694            int it = 0;
14695            ResolveInfo curt = null;
14696            BroadcastFilter curr = null;
14697            while (it < NT && ir < NR) {
14698                if (curt == null) {
14699                    curt = (ResolveInfo)receivers.get(it);
14700                }
14701                if (curr == null) {
14702                    curr = registeredReceivers.get(ir);
14703                }
14704                if (curr.getPriority() >= curt.priority) {
14705                    // Insert this broadcast record into the final list.
14706                    receivers.add(it, curr);
14707                    ir++;
14708                    curr = null;
14709                    it++;
14710                    NT++;
14711                } else {
14712                    // Skip to the next ResolveInfo in the final list.
14713                    it++;
14714                    curt = null;
14715                }
14716            }
14717        }
14718        while (ir < NR) {
14719            if (receivers == null) {
14720                receivers = new ArrayList();
14721            }
14722            receivers.add(registeredReceivers.get(ir));
14723            ir++;
14724        }
14725
14726        if ((receivers != null && receivers.size() > 0)
14727                || resultTo != null) {
14728            BroadcastQueue queue = broadcastQueueForIntent(intent);
14729            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14730                    callerPackage, callingPid, callingUid, resolvedType,
14731                    requiredPermission, appOp, receivers, resultTo, resultCode,
14732                    resultData, map, ordered, sticky, false, userId);
14733            if (DEBUG_BROADCAST) Slog.v(
14734                    TAG, "Enqueueing ordered broadcast " + r
14735                    + ": prev had " + queue.mOrderedBroadcasts.size());
14736            if (DEBUG_BROADCAST) {
14737                int seq = r.intent.getIntExtra("seq", -1);
14738                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14739            }
14740            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14741            if (!replaced) {
14742                queue.enqueueOrderedBroadcastLocked(r);
14743                queue.scheduleBroadcastsLocked();
14744            }
14745        }
14746
14747        return ActivityManager.BROADCAST_SUCCESS;
14748    }
14749
14750    final Intent verifyBroadcastLocked(Intent intent) {
14751        // Refuse possible leaked file descriptors
14752        if (intent != null && intent.hasFileDescriptors() == true) {
14753            throw new IllegalArgumentException("File descriptors passed in Intent");
14754        }
14755
14756        int flags = intent.getFlags();
14757
14758        if (!mProcessesReady) {
14759            // if the caller really truly claims to know what they're doing, go
14760            // ahead and allow the broadcast without launching any receivers
14761            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14762                intent = new Intent(intent);
14763                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14764            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14765                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14766                        + " before boot completion");
14767                throw new IllegalStateException("Cannot broadcast before boot completed");
14768            }
14769        }
14770
14771        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14772            throw new IllegalArgumentException(
14773                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14774        }
14775
14776        return intent;
14777    }
14778
14779    public final int broadcastIntent(IApplicationThread caller,
14780            Intent intent, String resolvedType, IIntentReceiver resultTo,
14781            int resultCode, String resultData, Bundle map,
14782            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14783        enforceNotIsolatedCaller("broadcastIntent");
14784        synchronized(this) {
14785            intent = verifyBroadcastLocked(intent);
14786
14787            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14788            final int callingPid = Binder.getCallingPid();
14789            final int callingUid = Binder.getCallingUid();
14790            final long origId = Binder.clearCallingIdentity();
14791            int res = broadcastIntentLocked(callerApp,
14792                    callerApp != null ? callerApp.info.packageName : null,
14793                    intent, resolvedType, resultTo,
14794                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14795                    callingPid, callingUid, userId);
14796            Binder.restoreCallingIdentity(origId);
14797            return res;
14798        }
14799    }
14800
14801    int broadcastIntentInPackage(String packageName, int uid,
14802            Intent intent, String resolvedType, IIntentReceiver resultTo,
14803            int resultCode, String resultData, Bundle map,
14804            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14805        synchronized(this) {
14806            intent = verifyBroadcastLocked(intent);
14807
14808            final long origId = Binder.clearCallingIdentity();
14809            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14810                    resultTo, resultCode, resultData, map, requiredPermission,
14811                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14812            Binder.restoreCallingIdentity(origId);
14813            return res;
14814        }
14815    }
14816
14817    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14818        // Refuse possible leaked file descriptors
14819        if (intent != null && intent.hasFileDescriptors() == true) {
14820            throw new IllegalArgumentException("File descriptors passed in Intent");
14821        }
14822
14823        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14824                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14825
14826        synchronized(this) {
14827            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14828                    != PackageManager.PERMISSION_GRANTED) {
14829                String msg = "Permission Denial: unbroadcastIntent() from pid="
14830                        + Binder.getCallingPid()
14831                        + ", uid=" + Binder.getCallingUid()
14832                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14833                Slog.w(TAG, msg);
14834                throw new SecurityException(msg);
14835            }
14836            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14837            if (stickies != null) {
14838                ArrayList<Intent> list = stickies.get(intent.getAction());
14839                if (list != null) {
14840                    int N = list.size();
14841                    int i;
14842                    for (i=0; i<N; i++) {
14843                        if (intent.filterEquals(list.get(i))) {
14844                            list.remove(i);
14845                            break;
14846                        }
14847                    }
14848                    if (list.size() <= 0) {
14849                        stickies.remove(intent.getAction());
14850                    }
14851                }
14852                if (stickies.size() <= 0) {
14853                    mStickyBroadcasts.remove(userId);
14854                }
14855            }
14856        }
14857    }
14858
14859    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14860            String resultData, Bundle resultExtras, boolean resultAbort) {
14861        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14862        if (r == null) {
14863            Slog.w(TAG, "finishReceiver called but not found on queue");
14864            return false;
14865        }
14866
14867        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14868    }
14869
14870    void backgroundServicesFinishedLocked(int userId) {
14871        for (BroadcastQueue queue : mBroadcastQueues) {
14872            queue.backgroundServicesFinishedLocked(userId);
14873        }
14874    }
14875
14876    public void finishReceiver(IBinder who, int resultCode, String resultData,
14877            Bundle resultExtras, boolean resultAbort) {
14878        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14879
14880        // Refuse possible leaked file descriptors
14881        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14882            throw new IllegalArgumentException("File descriptors passed in Bundle");
14883        }
14884
14885        final long origId = Binder.clearCallingIdentity();
14886        try {
14887            boolean doNext = false;
14888            BroadcastRecord r;
14889
14890            synchronized(this) {
14891                r = broadcastRecordForReceiverLocked(who);
14892                if (r != null) {
14893                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14894                        resultData, resultExtras, resultAbort, true);
14895                }
14896            }
14897
14898            if (doNext) {
14899                r.queue.processNextBroadcast(false);
14900            }
14901            trimApplications();
14902        } finally {
14903            Binder.restoreCallingIdentity(origId);
14904        }
14905    }
14906
14907    // =========================================================
14908    // INSTRUMENTATION
14909    // =========================================================
14910
14911    public boolean startInstrumentation(ComponentName className,
14912            String profileFile, int flags, Bundle arguments,
14913            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14914            int userId, String abiOverride) {
14915        enforceNotIsolatedCaller("startInstrumentation");
14916        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14917                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14918        // Refuse possible leaked file descriptors
14919        if (arguments != null && arguments.hasFileDescriptors()) {
14920            throw new IllegalArgumentException("File descriptors passed in Bundle");
14921        }
14922
14923        synchronized(this) {
14924            InstrumentationInfo ii = null;
14925            ApplicationInfo ai = null;
14926            try {
14927                ii = mContext.getPackageManager().getInstrumentationInfo(
14928                    className, STOCK_PM_FLAGS);
14929                ai = AppGlobals.getPackageManager().getApplicationInfo(
14930                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14931            } catch (PackageManager.NameNotFoundException e) {
14932            } catch (RemoteException e) {
14933            }
14934            if (ii == null) {
14935                reportStartInstrumentationFailure(watcher, className,
14936                        "Unable to find instrumentation info for: " + className);
14937                return false;
14938            }
14939            if (ai == null) {
14940                reportStartInstrumentationFailure(watcher, className,
14941                        "Unable to find instrumentation target package: " + ii.targetPackage);
14942                return false;
14943            }
14944
14945            int match = mContext.getPackageManager().checkSignatures(
14946                    ii.targetPackage, ii.packageName);
14947            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14948                String msg = "Permission Denial: starting instrumentation "
14949                        + className + " from pid="
14950                        + Binder.getCallingPid()
14951                        + ", uid=" + Binder.getCallingPid()
14952                        + " not allowed because package " + ii.packageName
14953                        + " does not have a signature matching the target "
14954                        + ii.targetPackage;
14955                reportStartInstrumentationFailure(watcher, className, msg);
14956                throw new SecurityException(msg);
14957            }
14958
14959            final long origId = Binder.clearCallingIdentity();
14960            // Instrumentation can kill and relaunch even persistent processes
14961            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14962                    "start instr");
14963            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14964            app.instrumentationClass = className;
14965            app.instrumentationInfo = ai;
14966            app.instrumentationProfileFile = profileFile;
14967            app.instrumentationArguments = arguments;
14968            app.instrumentationWatcher = watcher;
14969            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14970            app.instrumentationResultClass = className;
14971            Binder.restoreCallingIdentity(origId);
14972        }
14973
14974        return true;
14975    }
14976
14977    /**
14978     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14979     * error to the logs, but if somebody is watching, send the report there too.  This enables
14980     * the "am" command to report errors with more information.
14981     *
14982     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14983     * @param cn The component name of the instrumentation.
14984     * @param report The error report.
14985     */
14986    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14987            ComponentName cn, String report) {
14988        Slog.w(TAG, report);
14989        try {
14990            if (watcher != null) {
14991                Bundle results = new Bundle();
14992                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14993                results.putString("Error", report);
14994                watcher.instrumentationStatus(cn, -1, results);
14995            }
14996        } catch (RemoteException e) {
14997            Slog.w(TAG, e);
14998        }
14999    }
15000
15001    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15002        if (app.instrumentationWatcher != null) {
15003            try {
15004                // NOTE:  IInstrumentationWatcher *must* be oneway here
15005                app.instrumentationWatcher.instrumentationFinished(
15006                    app.instrumentationClass,
15007                    resultCode,
15008                    results);
15009            } catch (RemoteException e) {
15010            }
15011        }
15012        if (app.instrumentationUiAutomationConnection != null) {
15013            try {
15014                app.instrumentationUiAutomationConnection.shutdown();
15015            } catch (RemoteException re) {
15016                /* ignore */
15017            }
15018            // Only a UiAutomation can set this flag and now that
15019            // it is finished we make sure it is reset to its default.
15020            mUserIsMonkey = false;
15021        }
15022        app.instrumentationWatcher = null;
15023        app.instrumentationUiAutomationConnection = null;
15024        app.instrumentationClass = null;
15025        app.instrumentationInfo = null;
15026        app.instrumentationProfileFile = null;
15027        app.instrumentationArguments = null;
15028
15029        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15030                "finished inst");
15031    }
15032
15033    public void finishInstrumentation(IApplicationThread target,
15034            int resultCode, Bundle results) {
15035        int userId = UserHandle.getCallingUserId();
15036        // Refuse possible leaked file descriptors
15037        if (results != null && results.hasFileDescriptors()) {
15038            throw new IllegalArgumentException("File descriptors passed in Intent");
15039        }
15040
15041        synchronized(this) {
15042            ProcessRecord app = getRecordForAppLocked(target);
15043            if (app == null) {
15044                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15045                return;
15046            }
15047            final long origId = Binder.clearCallingIdentity();
15048            finishInstrumentationLocked(app, resultCode, results);
15049            Binder.restoreCallingIdentity(origId);
15050        }
15051    }
15052
15053    // =========================================================
15054    // CONFIGURATION
15055    // =========================================================
15056
15057    public ConfigurationInfo getDeviceConfigurationInfo() {
15058        ConfigurationInfo config = new ConfigurationInfo();
15059        synchronized (this) {
15060            config.reqTouchScreen = mConfiguration.touchscreen;
15061            config.reqKeyboardType = mConfiguration.keyboard;
15062            config.reqNavigation = mConfiguration.navigation;
15063            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15064                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15065                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15066            }
15067            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15068                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15069                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15070            }
15071            config.reqGlEsVersion = GL_ES_VERSION;
15072        }
15073        return config;
15074    }
15075
15076    ActivityStack getFocusedStack() {
15077        return mStackSupervisor.getFocusedStack();
15078    }
15079
15080    public Configuration getConfiguration() {
15081        Configuration ci;
15082        synchronized(this) {
15083            ci = new Configuration(mConfiguration);
15084        }
15085        return ci;
15086    }
15087
15088    public void updatePersistentConfiguration(Configuration values) {
15089        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15090                "updateConfiguration()");
15091        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15092                "updateConfiguration()");
15093        if (values == null) {
15094            throw new NullPointerException("Configuration must not be null");
15095        }
15096
15097        synchronized(this) {
15098            final long origId = Binder.clearCallingIdentity();
15099            updateConfigurationLocked(values, null, true, false);
15100            Binder.restoreCallingIdentity(origId);
15101        }
15102    }
15103
15104    public void updateConfiguration(Configuration values) {
15105        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15106                "updateConfiguration()");
15107
15108        synchronized(this) {
15109            if (values == null && mWindowManager != null) {
15110                // sentinel: fetch the current configuration from the window manager
15111                values = mWindowManager.computeNewConfiguration();
15112            }
15113
15114            if (mWindowManager != null) {
15115                mProcessList.applyDisplaySize(mWindowManager);
15116            }
15117
15118            final long origId = Binder.clearCallingIdentity();
15119            if (values != null) {
15120                Settings.System.clearConfiguration(values);
15121            }
15122            updateConfigurationLocked(values, null, false, false);
15123            Binder.restoreCallingIdentity(origId);
15124        }
15125    }
15126
15127    /**
15128     * Do either or both things: (1) change the current configuration, and (2)
15129     * make sure the given activity is running with the (now) current
15130     * configuration.  Returns true if the activity has been left running, or
15131     * false if <var>starting</var> is being destroyed to match the new
15132     * configuration.
15133     * @param persistent TODO
15134     */
15135    boolean updateConfigurationLocked(Configuration values,
15136            ActivityRecord starting, boolean persistent, boolean initLocale) {
15137        int changes = 0;
15138
15139        if (values != null) {
15140            Configuration newConfig = new Configuration(mConfiguration);
15141            changes = newConfig.updateFrom(values);
15142            if (changes != 0) {
15143                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15144                    Slog.i(TAG, "Updating configuration to: " + values);
15145                }
15146
15147                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15148
15149                if (values.locale != null && !initLocale) {
15150                    saveLocaleLocked(values.locale,
15151                                     !values.locale.equals(mConfiguration.locale),
15152                                     values.userSetLocale);
15153                }
15154
15155                mConfigurationSeq++;
15156                if (mConfigurationSeq <= 0) {
15157                    mConfigurationSeq = 1;
15158                }
15159                newConfig.seq = mConfigurationSeq;
15160                mConfiguration = newConfig;
15161                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15162                //mUsageStatsService.noteStartConfig(newConfig);
15163
15164                final Configuration configCopy = new Configuration(mConfiguration);
15165
15166                // TODO: If our config changes, should we auto dismiss any currently
15167                // showing dialogs?
15168                mShowDialogs = shouldShowDialogs(newConfig);
15169
15170                AttributeCache ac = AttributeCache.instance();
15171                if (ac != null) {
15172                    ac.updateConfiguration(configCopy);
15173                }
15174
15175                // Make sure all resources in our process are updated
15176                // right now, so that anyone who is going to retrieve
15177                // resource values after we return will be sure to get
15178                // the new ones.  This is especially important during
15179                // boot, where the first config change needs to guarantee
15180                // all resources have that config before following boot
15181                // code is executed.
15182                mSystemThread.applyConfigurationToResources(configCopy);
15183
15184                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15185                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15186                    msg.obj = new Configuration(configCopy);
15187                    mHandler.sendMessage(msg);
15188                }
15189
15190                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15191                    ProcessRecord app = mLruProcesses.get(i);
15192                    try {
15193                        if (app.thread != null) {
15194                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15195                                    + app.processName + " new config " + mConfiguration);
15196                            app.thread.scheduleConfigurationChanged(configCopy);
15197                        }
15198                    } catch (Exception e) {
15199                    }
15200                }
15201                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15202                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15203                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15204                        | Intent.FLAG_RECEIVER_FOREGROUND);
15205                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15206                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15207                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15208                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15209                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15210                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15211                    broadcastIntentLocked(null, null, intent,
15212                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15213                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15214                }
15215            }
15216        }
15217
15218        boolean kept = true;
15219        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15220        // mainStack is null during startup.
15221        if (mainStack != null) {
15222            if (changes != 0 && starting == null) {
15223                // If the configuration changed, and the caller is not already
15224                // in the process of starting an activity, then find the top
15225                // activity to check if its configuration needs to change.
15226                starting = mainStack.topRunningActivityLocked(null);
15227            }
15228
15229            if (starting != null) {
15230                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15231                // And we need to make sure at this point that all other activities
15232                // are made visible with the correct configuration.
15233                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15234            }
15235        }
15236
15237        if (values != null && mWindowManager != null) {
15238            mWindowManager.setNewConfiguration(mConfiguration);
15239        }
15240
15241        return kept;
15242    }
15243
15244    /**
15245     * Decide based on the configuration whether we should shouw the ANR,
15246     * crash, etc dialogs.  The idea is that if there is no affordnace to
15247     * press the on-screen buttons, we shouldn't show the dialog.
15248     *
15249     * A thought: SystemUI might also want to get told about this, the Power
15250     * dialog / global actions also might want different behaviors.
15251     */
15252    private static final boolean shouldShowDialogs(Configuration config) {
15253        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15254                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15255    }
15256
15257    /**
15258     * Save the locale.  You must be inside a synchronized (this) block.
15259     */
15260    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15261        if(isDiff) {
15262            SystemProperties.set("user.language", l.getLanguage());
15263            SystemProperties.set("user.region", l.getCountry());
15264        }
15265
15266        if(isPersist) {
15267            SystemProperties.set("persist.sys.language", l.getLanguage());
15268            SystemProperties.set("persist.sys.country", l.getCountry());
15269            SystemProperties.set("persist.sys.localevar", l.getVariant());
15270        }
15271    }
15272
15273    @Override
15274    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15275        ActivityRecord srec = ActivityRecord.forToken(token);
15276        return srec != null && srec.task.affinity != null &&
15277                srec.task.affinity.equals(destAffinity);
15278    }
15279
15280    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15281            Intent resultData) {
15282
15283        synchronized (this) {
15284            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15285            if (stack != null) {
15286                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15287            }
15288            return false;
15289        }
15290    }
15291
15292    public int getLaunchedFromUid(IBinder activityToken) {
15293        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15294        if (srec == null) {
15295            return -1;
15296        }
15297        return srec.launchedFromUid;
15298    }
15299
15300    public String getLaunchedFromPackage(IBinder activityToken) {
15301        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15302        if (srec == null) {
15303            return null;
15304        }
15305        return srec.launchedFromPackage;
15306    }
15307
15308    // =========================================================
15309    // LIFETIME MANAGEMENT
15310    // =========================================================
15311
15312    // Returns which broadcast queue the app is the current [or imminent] receiver
15313    // on, or 'null' if the app is not an active broadcast recipient.
15314    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15315        BroadcastRecord r = app.curReceiver;
15316        if (r != null) {
15317            return r.queue;
15318        }
15319
15320        // It's not the current receiver, but it might be starting up to become one
15321        synchronized (this) {
15322            for (BroadcastQueue queue : mBroadcastQueues) {
15323                r = queue.mPendingBroadcast;
15324                if (r != null && r.curApp == app) {
15325                    // found it; report which queue it's in
15326                    return queue;
15327                }
15328            }
15329        }
15330
15331        return null;
15332    }
15333
15334    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15335            boolean doingAll, long now) {
15336        if (mAdjSeq == app.adjSeq) {
15337            // This adjustment has already been computed.
15338            return app.curRawAdj;
15339        }
15340
15341        if (app.thread == null) {
15342            app.adjSeq = mAdjSeq;
15343            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15344            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15345            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15346        }
15347
15348        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15349        app.adjSource = null;
15350        app.adjTarget = null;
15351        app.empty = false;
15352        app.cached = false;
15353
15354        final int activitiesSize = app.activities.size();
15355
15356        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15357            // The max adjustment doesn't allow this app to be anything
15358            // below foreground, so it is not worth doing work for it.
15359            app.adjType = "fixed";
15360            app.adjSeq = mAdjSeq;
15361            app.curRawAdj = app.maxAdj;
15362            app.foregroundActivities = false;
15363            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15364            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15365            // System processes can do UI, and when they do we want to have
15366            // them trim their memory after the user leaves the UI.  To
15367            // facilitate this, here we need to determine whether or not it
15368            // is currently showing UI.
15369            app.systemNoUi = true;
15370            if (app == TOP_APP) {
15371                app.systemNoUi = false;
15372            } else if (activitiesSize > 0) {
15373                for (int j = 0; j < activitiesSize; j++) {
15374                    final ActivityRecord r = app.activities.get(j);
15375                    if (r.visible) {
15376                        app.systemNoUi = false;
15377                    }
15378                }
15379            }
15380            if (!app.systemNoUi) {
15381                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15382            }
15383            return (app.curAdj=app.maxAdj);
15384        }
15385
15386        app.systemNoUi = false;
15387
15388        // Determine the importance of the process, starting with most
15389        // important to least, and assign an appropriate OOM adjustment.
15390        int adj;
15391        int schedGroup;
15392        int procState;
15393        boolean foregroundActivities = false;
15394        BroadcastQueue queue;
15395        if (app == TOP_APP) {
15396            // The last app on the list is the foreground app.
15397            adj = ProcessList.FOREGROUND_APP_ADJ;
15398            schedGroup = Process.THREAD_GROUP_DEFAULT;
15399            app.adjType = "top-activity";
15400            foregroundActivities = true;
15401            procState = ActivityManager.PROCESS_STATE_TOP;
15402        } else if (app.instrumentationClass != null) {
15403            // Don't want to kill running instrumentation.
15404            adj = ProcessList.FOREGROUND_APP_ADJ;
15405            schedGroup = Process.THREAD_GROUP_DEFAULT;
15406            app.adjType = "instrumentation";
15407            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15408        } else if ((queue = isReceivingBroadcast(app)) != null) {
15409            // An app that is currently receiving a broadcast also
15410            // counts as being in the foreground for OOM killer purposes.
15411            // It's placed in a sched group based on the nature of the
15412            // broadcast as reflected by which queue it's active in.
15413            adj = ProcessList.FOREGROUND_APP_ADJ;
15414            schedGroup = (queue == mFgBroadcastQueue)
15415                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15416            app.adjType = "broadcast";
15417            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15418        } else if (app.executingServices.size() > 0) {
15419            // An app that is currently executing a service callback also
15420            // counts as being in the foreground.
15421            adj = ProcessList.FOREGROUND_APP_ADJ;
15422            schedGroup = app.execServicesFg ?
15423                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15424            app.adjType = "exec-service";
15425            procState = ActivityManager.PROCESS_STATE_SERVICE;
15426            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15427        } else {
15428            // As far as we know the process is empty.  We may change our mind later.
15429            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15430            // At this point we don't actually know the adjustment.  Use the cached adj
15431            // value that the caller wants us to.
15432            adj = cachedAdj;
15433            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15434            app.cached = true;
15435            app.empty = true;
15436            app.adjType = "cch-empty";
15437        }
15438
15439        // Examine all activities if not already foreground.
15440        if (!foregroundActivities && activitiesSize > 0) {
15441            for (int j = 0; j < activitiesSize; j++) {
15442                final ActivityRecord r = app.activities.get(j);
15443                if (r.app != app) {
15444                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15445                            + app + "?!?");
15446                    continue;
15447                }
15448                if (r.visible) {
15449                    // App has a visible activity; only upgrade adjustment.
15450                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15451                        adj = ProcessList.VISIBLE_APP_ADJ;
15452                        app.adjType = "visible";
15453                    }
15454                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15455                        procState = ActivityManager.PROCESS_STATE_TOP;
15456                    }
15457                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15458                    app.cached = false;
15459                    app.empty = false;
15460                    foregroundActivities = true;
15461                    break;
15462                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15463                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15464                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15465                        app.adjType = "pausing";
15466                    }
15467                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15468                        procState = ActivityManager.PROCESS_STATE_TOP;
15469                    }
15470                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15471                    app.cached = false;
15472                    app.empty = false;
15473                    foregroundActivities = true;
15474                } else if (r.state == ActivityState.STOPPING) {
15475                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15476                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15477                        app.adjType = "stopping";
15478                    }
15479                    // For the process state, we will at this point consider the
15480                    // process to be cached.  It will be cached either as an activity
15481                    // or empty depending on whether the activity is finishing.  We do
15482                    // this so that we can treat the process as cached for purposes of
15483                    // memory trimming (determing current memory level, trim command to
15484                    // send to process) since there can be an arbitrary number of stopping
15485                    // processes and they should soon all go into the cached state.
15486                    if (!r.finishing) {
15487                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15488                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15489                        }
15490                    }
15491                    app.cached = false;
15492                    app.empty = false;
15493                    foregroundActivities = true;
15494                } else {
15495                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15496                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15497                        app.adjType = "cch-act";
15498                    }
15499                }
15500            }
15501        }
15502
15503        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15504            if (app.foregroundServices) {
15505                // The user is aware of this app, so make it visible.
15506                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15507                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15508                app.cached = false;
15509                app.adjType = "fg-service";
15510                schedGroup = Process.THREAD_GROUP_DEFAULT;
15511            } else if (app.forcingToForeground != null) {
15512                // The user is aware of this app, so make it visible.
15513                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15514                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15515                app.cached = false;
15516                app.adjType = "force-fg";
15517                app.adjSource = app.forcingToForeground;
15518                schedGroup = Process.THREAD_GROUP_DEFAULT;
15519            }
15520        }
15521
15522        if (app == mHeavyWeightProcess) {
15523            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15524                // We don't want to kill the current heavy-weight process.
15525                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15526                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15527                app.cached = false;
15528                app.adjType = "heavy";
15529            }
15530            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15531                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15532            }
15533        }
15534
15535        if (app == mHomeProcess) {
15536            if (adj > ProcessList.HOME_APP_ADJ) {
15537                // This process is hosting what we currently consider to be the
15538                // home app, so we don't want to let it go into the background.
15539                adj = ProcessList.HOME_APP_ADJ;
15540                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15541                app.cached = false;
15542                app.adjType = "home";
15543            }
15544            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15545                procState = ActivityManager.PROCESS_STATE_HOME;
15546            }
15547        }
15548
15549        if (app == mPreviousProcess && app.activities.size() > 0) {
15550            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15551                // This was the previous process that showed UI to the user.
15552                // We want to try to keep it around more aggressively, to give
15553                // a good experience around switching between two apps.
15554                adj = ProcessList.PREVIOUS_APP_ADJ;
15555                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15556                app.cached = false;
15557                app.adjType = "previous";
15558            }
15559            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15560                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15561            }
15562        }
15563
15564        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15565                + " reason=" + app.adjType);
15566
15567        // By default, we use the computed adjustment.  It may be changed if
15568        // there are applications dependent on our services or providers, but
15569        // this gives us a baseline and makes sure we don't get into an
15570        // infinite recursion.
15571        app.adjSeq = mAdjSeq;
15572        app.curRawAdj = adj;
15573        app.hasStartedServices = false;
15574
15575        if (mBackupTarget != null && app == mBackupTarget.app) {
15576            // If possible we want to avoid killing apps while they're being backed up
15577            if (adj > ProcessList.BACKUP_APP_ADJ) {
15578                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15579                adj = ProcessList.BACKUP_APP_ADJ;
15580                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15581                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15582                }
15583                app.adjType = "backup";
15584                app.cached = false;
15585            }
15586            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15587                procState = ActivityManager.PROCESS_STATE_BACKUP;
15588            }
15589        }
15590
15591        boolean mayBeTop = false;
15592
15593        for (int is = app.services.size()-1;
15594                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15595                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15596                        || procState > ActivityManager.PROCESS_STATE_TOP);
15597                is--) {
15598            ServiceRecord s = app.services.valueAt(is);
15599            if (s.startRequested) {
15600                app.hasStartedServices = true;
15601                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15602                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15603                }
15604                if (app.hasShownUi && app != mHomeProcess) {
15605                    // If this process has shown some UI, let it immediately
15606                    // go to the LRU list because it may be pretty heavy with
15607                    // UI stuff.  We'll tag it with a label just to help
15608                    // debug and understand what is going on.
15609                    if (adj > ProcessList.SERVICE_ADJ) {
15610                        app.adjType = "cch-started-ui-services";
15611                    }
15612                } else {
15613                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15614                        // This service has seen some activity within
15615                        // recent memory, so we will keep its process ahead
15616                        // of the background processes.
15617                        if (adj > ProcessList.SERVICE_ADJ) {
15618                            adj = ProcessList.SERVICE_ADJ;
15619                            app.adjType = "started-services";
15620                            app.cached = false;
15621                        }
15622                    }
15623                    // If we have let the service slide into the background
15624                    // state, still have some text describing what it is doing
15625                    // even though the service no longer has an impact.
15626                    if (adj > ProcessList.SERVICE_ADJ) {
15627                        app.adjType = "cch-started-services";
15628                    }
15629                }
15630            }
15631            for (int conni = s.connections.size()-1;
15632                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15633                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15634                            || procState > ActivityManager.PROCESS_STATE_TOP);
15635                    conni--) {
15636                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15637                for (int i = 0;
15638                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15639                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15640                                || procState > ActivityManager.PROCESS_STATE_TOP);
15641                        i++) {
15642                    // XXX should compute this based on the max of
15643                    // all connected clients.
15644                    ConnectionRecord cr = clist.get(i);
15645                    if (cr.binding.client == app) {
15646                        // Binding to ourself is not interesting.
15647                        continue;
15648                    }
15649                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15650                        ProcessRecord client = cr.binding.client;
15651                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15652                                TOP_APP, doingAll, now);
15653                        int clientProcState = client.curProcState;
15654                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15655                            // If the other app is cached for any reason, for purposes here
15656                            // we are going to consider it empty.  The specific cached state
15657                            // doesn't propagate except under certain conditions.
15658                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15659                        }
15660                        String adjType = null;
15661                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15662                            // Not doing bind OOM management, so treat
15663                            // this guy more like a started service.
15664                            if (app.hasShownUi && app != mHomeProcess) {
15665                                // If this process has shown some UI, let it immediately
15666                                // go to the LRU list because it may be pretty heavy with
15667                                // UI stuff.  We'll tag it with a label just to help
15668                                // debug and understand what is going on.
15669                                if (adj > clientAdj) {
15670                                    adjType = "cch-bound-ui-services";
15671                                }
15672                                app.cached = false;
15673                                clientAdj = adj;
15674                                clientProcState = procState;
15675                            } else {
15676                                if (now >= (s.lastActivity
15677                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15678                                    // This service has not seen activity within
15679                                    // recent memory, so allow it to drop to the
15680                                    // LRU list if there is no other reason to keep
15681                                    // it around.  We'll also tag it with a label just
15682                                    // to help debug and undertand what is going on.
15683                                    if (adj > clientAdj) {
15684                                        adjType = "cch-bound-services";
15685                                    }
15686                                    clientAdj = adj;
15687                                }
15688                            }
15689                        }
15690                        if (adj > clientAdj) {
15691                            // If this process has recently shown UI, and
15692                            // the process that is binding to it is less
15693                            // important than being visible, then we don't
15694                            // care about the binding as much as we care
15695                            // about letting this process get into the LRU
15696                            // list to be killed and restarted if needed for
15697                            // memory.
15698                            if (app.hasShownUi && app != mHomeProcess
15699                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15700                                adjType = "cch-bound-ui-services";
15701                            } else {
15702                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15703                                        |Context.BIND_IMPORTANT)) != 0) {
15704                                    adj = clientAdj;
15705                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15706                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15707                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15708                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15709                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15710                                    adj = clientAdj;
15711                                } else {
15712                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15713                                        adj = ProcessList.VISIBLE_APP_ADJ;
15714                                    }
15715                                }
15716                                if (!client.cached) {
15717                                    app.cached = false;
15718                                }
15719                                adjType = "service";
15720                            }
15721                        }
15722                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15723                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15724                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15725                            }
15726                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15727                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15728                                    // Special handling of clients who are in the top state.
15729                                    // We *may* want to consider this process to be in the
15730                                    // top state as well, but only if there is not another
15731                                    // reason for it to be running.  Being on the top is a
15732                                    // special state, meaning you are specifically running
15733                                    // for the current top app.  If the process is already
15734                                    // running in the background for some other reason, it
15735                                    // is more important to continue considering it to be
15736                                    // in the background state.
15737                                    mayBeTop = true;
15738                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15739                                } else {
15740                                    // Special handling for above-top states (persistent
15741                                    // processes).  These should not bring the current process
15742                                    // into the top state, since they are not on top.  Instead
15743                                    // give them the best state after that.
15744                                    clientProcState =
15745                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15746                                }
15747                            }
15748                        } else {
15749                            if (clientProcState <
15750                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15751                                clientProcState =
15752                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15753                            }
15754                        }
15755                        if (procState > clientProcState) {
15756                            procState = clientProcState;
15757                        }
15758                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15759                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15760                            app.pendingUiClean = true;
15761                        }
15762                        if (adjType != null) {
15763                            app.adjType = adjType;
15764                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15765                                    .REASON_SERVICE_IN_USE;
15766                            app.adjSource = cr.binding.client;
15767                            app.adjSourceProcState = clientProcState;
15768                            app.adjTarget = s.name;
15769                        }
15770                    }
15771                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15772                        app.treatLikeActivity = true;
15773                    }
15774                    final ActivityRecord a = cr.activity;
15775                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15776                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15777                                (a.visible || a.state == ActivityState.RESUMED
15778                                 || a.state == ActivityState.PAUSING)) {
15779                            adj = ProcessList.FOREGROUND_APP_ADJ;
15780                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15781                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15782                            }
15783                            app.cached = false;
15784                            app.adjType = "service";
15785                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15786                                    .REASON_SERVICE_IN_USE;
15787                            app.adjSource = a;
15788                            app.adjSourceProcState = procState;
15789                            app.adjTarget = s.name;
15790                        }
15791                    }
15792                }
15793            }
15794        }
15795
15796        for (int provi = app.pubProviders.size()-1;
15797                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15798                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15799                        || procState > ActivityManager.PROCESS_STATE_TOP);
15800                provi--) {
15801            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15802            for (int i = cpr.connections.size()-1;
15803                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15804                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15805                            || procState > ActivityManager.PROCESS_STATE_TOP);
15806                    i--) {
15807                ContentProviderConnection conn = cpr.connections.get(i);
15808                ProcessRecord client = conn.client;
15809                if (client == app) {
15810                    // Being our own client is not interesting.
15811                    continue;
15812                }
15813                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15814                int clientProcState = client.curProcState;
15815                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15816                    // If the other app is cached for any reason, for purposes here
15817                    // we are going to consider it empty.
15818                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15819                }
15820                if (adj > clientAdj) {
15821                    if (app.hasShownUi && app != mHomeProcess
15822                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15823                        app.adjType = "cch-ui-provider";
15824                    } else {
15825                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15826                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15827                        app.adjType = "provider";
15828                    }
15829                    app.cached &= client.cached;
15830                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15831                            .REASON_PROVIDER_IN_USE;
15832                    app.adjSource = client;
15833                    app.adjSourceProcState = clientProcState;
15834                    app.adjTarget = cpr.name;
15835                }
15836                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15837                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15838                        // Special handling of clients who are in the top state.
15839                        // We *may* want to consider this process to be in the
15840                        // top state as well, but only if there is not another
15841                        // reason for it to be running.  Being on the top is a
15842                        // special state, meaning you are specifically running
15843                        // for the current top app.  If the process is already
15844                        // running in the background for some other reason, it
15845                        // is more important to continue considering it to be
15846                        // in the background state.
15847                        mayBeTop = true;
15848                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15849                    } else {
15850                        // Special handling for above-top states (persistent
15851                        // processes).  These should not bring the current process
15852                        // into the top state, since they are not on top.  Instead
15853                        // give them the best state after that.
15854                        clientProcState =
15855                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15856                    }
15857                }
15858                if (procState > clientProcState) {
15859                    procState = clientProcState;
15860                }
15861                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15862                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15863                }
15864            }
15865            // If the provider has external (non-framework) process
15866            // dependencies, ensure that its adjustment is at least
15867            // FOREGROUND_APP_ADJ.
15868            if (cpr.hasExternalProcessHandles()) {
15869                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15870                    adj = ProcessList.FOREGROUND_APP_ADJ;
15871                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15872                    app.cached = false;
15873                    app.adjType = "provider";
15874                    app.adjTarget = cpr.name;
15875                }
15876                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15877                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15878                }
15879            }
15880        }
15881
15882        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15883            // A client of one of our services or providers is in the top state.  We
15884            // *may* want to be in the top state, but not if we are already running in
15885            // the background for some other reason.  For the decision here, we are going
15886            // to pick out a few specific states that we want to remain in when a client
15887            // is top (states that tend to be longer-term) and otherwise allow it to go
15888            // to the top state.
15889            switch (procState) {
15890                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15891                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15892                case ActivityManager.PROCESS_STATE_SERVICE:
15893                    // These all are longer-term states, so pull them up to the top
15894                    // of the background states, but not all the way to the top state.
15895                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15896                    break;
15897                default:
15898                    // Otherwise, top is a better choice, so take it.
15899                    procState = ActivityManager.PROCESS_STATE_TOP;
15900                    break;
15901            }
15902        }
15903
15904        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15905            if (app.hasClientActivities) {
15906                // This is a cached process, but with client activities.  Mark it so.
15907                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15908                app.adjType = "cch-client-act";
15909            } else if (app.treatLikeActivity) {
15910                // This is a cached process, but somebody wants us to treat it like it has
15911                // an activity, okay!
15912                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15913                app.adjType = "cch-as-act";
15914            }
15915        }
15916
15917        if (adj == ProcessList.SERVICE_ADJ) {
15918            if (doingAll) {
15919                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15920                mNewNumServiceProcs++;
15921                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15922                if (!app.serviceb) {
15923                    // This service isn't far enough down on the LRU list to
15924                    // normally be a B service, but if we are low on RAM and it
15925                    // is large we want to force it down since we would prefer to
15926                    // keep launcher over it.
15927                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15928                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15929                        app.serviceHighRam = true;
15930                        app.serviceb = true;
15931                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15932                    } else {
15933                        mNewNumAServiceProcs++;
15934                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15935                    }
15936                } else {
15937                    app.serviceHighRam = false;
15938                }
15939            }
15940            if (app.serviceb) {
15941                adj = ProcessList.SERVICE_B_ADJ;
15942            }
15943        }
15944
15945        app.curRawAdj = adj;
15946
15947        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15948        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15949        if (adj > app.maxAdj) {
15950            adj = app.maxAdj;
15951            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15952                schedGroup = Process.THREAD_GROUP_DEFAULT;
15953            }
15954        }
15955
15956        // Do final modification to adj.  Everything we do between here and applying
15957        // the final setAdj must be done in this function, because we will also use
15958        // it when computing the final cached adj later.  Note that we don't need to
15959        // worry about this for max adj above, since max adj will always be used to
15960        // keep it out of the cached vaues.
15961        app.curAdj = app.modifyRawOomAdj(adj);
15962        app.curSchedGroup = schedGroup;
15963        app.curProcState = procState;
15964        app.foregroundActivities = foregroundActivities;
15965
15966        return app.curRawAdj;
15967    }
15968
15969    /**
15970     * Schedule PSS collection of a process.
15971     */
15972    void requestPssLocked(ProcessRecord proc, int procState) {
15973        if (mPendingPssProcesses.contains(proc)) {
15974            return;
15975        }
15976        if (mPendingPssProcesses.size() == 0) {
15977            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15978        }
15979        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15980        proc.pssProcState = procState;
15981        mPendingPssProcesses.add(proc);
15982    }
15983
15984    /**
15985     * Schedule PSS collection of all processes.
15986     */
15987    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15988        if (!always) {
15989            if (now < (mLastFullPssTime +
15990                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15991                return;
15992            }
15993        }
15994        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15995        mLastFullPssTime = now;
15996        mFullPssPending = true;
15997        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15998        mPendingPssProcesses.clear();
15999        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16000            ProcessRecord app = mLruProcesses.get(i);
16001            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16002                app.pssProcState = app.setProcState;
16003                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16004                        isSleeping(), now);
16005                mPendingPssProcesses.add(app);
16006            }
16007        }
16008        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16009    }
16010
16011    /**
16012     * Ask a given process to GC right now.
16013     */
16014    final void performAppGcLocked(ProcessRecord app) {
16015        try {
16016            app.lastRequestedGc = SystemClock.uptimeMillis();
16017            if (app.thread != null) {
16018                if (app.reportLowMemory) {
16019                    app.reportLowMemory = false;
16020                    app.thread.scheduleLowMemory();
16021                } else {
16022                    app.thread.processInBackground();
16023                }
16024            }
16025        } catch (Exception e) {
16026            // whatever.
16027        }
16028    }
16029
16030    /**
16031     * Returns true if things are idle enough to perform GCs.
16032     */
16033    private final boolean canGcNowLocked() {
16034        boolean processingBroadcasts = false;
16035        for (BroadcastQueue q : mBroadcastQueues) {
16036            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16037                processingBroadcasts = true;
16038            }
16039        }
16040        return !processingBroadcasts
16041                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16042    }
16043
16044    /**
16045     * Perform GCs on all processes that are waiting for it, but only
16046     * if things are idle.
16047     */
16048    final void performAppGcsLocked() {
16049        final int N = mProcessesToGc.size();
16050        if (N <= 0) {
16051            return;
16052        }
16053        if (canGcNowLocked()) {
16054            while (mProcessesToGc.size() > 0) {
16055                ProcessRecord proc = mProcessesToGc.remove(0);
16056                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16057                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16058                            <= SystemClock.uptimeMillis()) {
16059                        // To avoid spamming the system, we will GC processes one
16060                        // at a time, waiting a few seconds between each.
16061                        performAppGcLocked(proc);
16062                        scheduleAppGcsLocked();
16063                        return;
16064                    } else {
16065                        // It hasn't been long enough since we last GCed this
16066                        // process...  put it in the list to wait for its time.
16067                        addProcessToGcListLocked(proc);
16068                        break;
16069                    }
16070                }
16071            }
16072
16073            scheduleAppGcsLocked();
16074        }
16075    }
16076
16077    /**
16078     * If all looks good, perform GCs on all processes waiting for them.
16079     */
16080    final void performAppGcsIfAppropriateLocked() {
16081        if (canGcNowLocked()) {
16082            performAppGcsLocked();
16083            return;
16084        }
16085        // Still not idle, wait some more.
16086        scheduleAppGcsLocked();
16087    }
16088
16089    /**
16090     * Schedule the execution of all pending app GCs.
16091     */
16092    final void scheduleAppGcsLocked() {
16093        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16094
16095        if (mProcessesToGc.size() > 0) {
16096            // Schedule a GC for the time to the next process.
16097            ProcessRecord proc = mProcessesToGc.get(0);
16098            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16099
16100            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16101            long now = SystemClock.uptimeMillis();
16102            if (when < (now+GC_TIMEOUT)) {
16103                when = now + GC_TIMEOUT;
16104            }
16105            mHandler.sendMessageAtTime(msg, when);
16106        }
16107    }
16108
16109    /**
16110     * Add a process to the array of processes waiting to be GCed.  Keeps the
16111     * list in sorted order by the last GC time.  The process can't already be
16112     * on the list.
16113     */
16114    final void addProcessToGcListLocked(ProcessRecord proc) {
16115        boolean added = false;
16116        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16117            if (mProcessesToGc.get(i).lastRequestedGc <
16118                    proc.lastRequestedGc) {
16119                added = true;
16120                mProcessesToGc.add(i+1, proc);
16121                break;
16122            }
16123        }
16124        if (!added) {
16125            mProcessesToGc.add(0, proc);
16126        }
16127    }
16128
16129    /**
16130     * Set up to ask a process to GC itself.  This will either do it
16131     * immediately, or put it on the list of processes to gc the next
16132     * time things are idle.
16133     */
16134    final void scheduleAppGcLocked(ProcessRecord app) {
16135        long now = SystemClock.uptimeMillis();
16136        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16137            return;
16138        }
16139        if (!mProcessesToGc.contains(app)) {
16140            addProcessToGcListLocked(app);
16141            scheduleAppGcsLocked();
16142        }
16143    }
16144
16145    final void checkExcessivePowerUsageLocked(boolean doKills) {
16146        updateCpuStatsNow();
16147
16148        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16149        boolean doWakeKills = doKills;
16150        boolean doCpuKills = doKills;
16151        if (mLastPowerCheckRealtime == 0) {
16152            doWakeKills = false;
16153        }
16154        if (mLastPowerCheckUptime == 0) {
16155            doCpuKills = false;
16156        }
16157        if (stats.isScreenOn()) {
16158            doWakeKills = false;
16159        }
16160        final long curRealtime = SystemClock.elapsedRealtime();
16161        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16162        final long curUptime = SystemClock.uptimeMillis();
16163        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16164        mLastPowerCheckRealtime = curRealtime;
16165        mLastPowerCheckUptime = curUptime;
16166        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16167            doWakeKills = false;
16168        }
16169        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16170            doCpuKills = false;
16171        }
16172        int i = mLruProcesses.size();
16173        while (i > 0) {
16174            i--;
16175            ProcessRecord app = mLruProcesses.get(i);
16176            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16177                long wtime;
16178                synchronized (stats) {
16179                    wtime = stats.getProcessWakeTime(app.info.uid,
16180                            app.pid, curRealtime);
16181                }
16182                long wtimeUsed = wtime - app.lastWakeTime;
16183                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16184                if (DEBUG_POWER) {
16185                    StringBuilder sb = new StringBuilder(128);
16186                    sb.append("Wake for ");
16187                    app.toShortString(sb);
16188                    sb.append(": over ");
16189                    TimeUtils.formatDuration(realtimeSince, sb);
16190                    sb.append(" used ");
16191                    TimeUtils.formatDuration(wtimeUsed, sb);
16192                    sb.append(" (");
16193                    sb.append((wtimeUsed*100)/realtimeSince);
16194                    sb.append("%)");
16195                    Slog.i(TAG, sb.toString());
16196                    sb.setLength(0);
16197                    sb.append("CPU for ");
16198                    app.toShortString(sb);
16199                    sb.append(": over ");
16200                    TimeUtils.formatDuration(uptimeSince, sb);
16201                    sb.append(" used ");
16202                    TimeUtils.formatDuration(cputimeUsed, sb);
16203                    sb.append(" (");
16204                    sb.append((cputimeUsed*100)/uptimeSince);
16205                    sb.append("%)");
16206                    Slog.i(TAG, sb.toString());
16207                }
16208                // If a process has held a wake lock for more
16209                // than 50% of the time during this period,
16210                // that sounds bad.  Kill!
16211                if (doWakeKills && realtimeSince > 0
16212                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16213                    synchronized (stats) {
16214                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16215                                realtimeSince, wtimeUsed);
16216                    }
16217                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16218                            + " during " + realtimeSince);
16219                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16220                } else if (doCpuKills && uptimeSince > 0
16221                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16222                    synchronized (stats) {
16223                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16224                                uptimeSince, cputimeUsed);
16225                    }
16226                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16227                            + " during " + uptimeSince);
16228                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16229                } else {
16230                    app.lastWakeTime = wtime;
16231                    app.lastCpuTime = app.curCpuTime;
16232                }
16233            }
16234        }
16235    }
16236
16237    private final boolean applyOomAdjLocked(ProcessRecord app,
16238            ProcessRecord TOP_APP, boolean doingAll, long now) {
16239        boolean success = true;
16240
16241        if (app.curRawAdj != app.setRawAdj) {
16242            app.setRawAdj = app.curRawAdj;
16243        }
16244
16245        int changes = 0;
16246
16247        if (app.curAdj != app.setAdj) {
16248            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16249            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16250                TAG, "Set " + app.pid + " " + app.processName +
16251                " adj " + app.curAdj + ": " + app.adjType);
16252            app.setAdj = app.curAdj;
16253        }
16254
16255        if (app.setSchedGroup != app.curSchedGroup) {
16256            app.setSchedGroup = app.curSchedGroup;
16257            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16258                    "Setting process group of " + app.processName
16259                    + " to " + app.curSchedGroup);
16260            if (app.waitingToKill != null &&
16261                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16262                killUnneededProcessLocked(app, app.waitingToKill);
16263                success = false;
16264            } else {
16265                if (true) {
16266                    long oldId = Binder.clearCallingIdentity();
16267                    try {
16268                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16269                    } catch (Exception e) {
16270                        Slog.w(TAG, "Failed setting process group of " + app.pid
16271                                + " to " + app.curSchedGroup);
16272                        e.printStackTrace();
16273                    } finally {
16274                        Binder.restoreCallingIdentity(oldId);
16275                    }
16276                } else {
16277                    if (app.thread != null) {
16278                        try {
16279                            app.thread.setSchedulingGroup(app.curSchedGroup);
16280                        } catch (RemoteException e) {
16281                        }
16282                    }
16283                }
16284                Process.setSwappiness(app.pid,
16285                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16286            }
16287        }
16288        if (app.repForegroundActivities != app.foregroundActivities) {
16289            app.repForegroundActivities = app.foregroundActivities;
16290            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16291        }
16292        if (app.repProcState != app.curProcState) {
16293            app.repProcState = app.curProcState;
16294            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16295            if (app.thread != null) {
16296                try {
16297                    if (false) {
16298                        //RuntimeException h = new RuntimeException("here");
16299                        Slog.i(TAG, "Sending new process state " + app.repProcState
16300                                + " to " + app /*, h*/);
16301                    }
16302                    app.thread.setProcessState(app.repProcState);
16303                } catch (RemoteException e) {
16304                }
16305            }
16306        }
16307        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16308                app.setProcState)) {
16309            app.lastStateTime = now;
16310            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16311                    isSleeping(), now);
16312            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16313                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16314                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16315                    + (app.nextPssTime-now) + ": " + app);
16316        } else {
16317            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16318                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16319                requestPssLocked(app, app.setProcState);
16320                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16321                        isSleeping(), now);
16322            } else if (false && DEBUG_PSS) {
16323                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16324            }
16325        }
16326        if (app.setProcState != app.curProcState) {
16327            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16328                    "Proc state change of " + app.processName
16329                    + " to " + app.curProcState);
16330            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16331            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16332            if (setImportant && !curImportant) {
16333                // This app is no longer something we consider important enough to allow to
16334                // use arbitrary amounts of battery power.  Note
16335                // its current wake lock time to later know to kill it if
16336                // it is not behaving well.
16337                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16338                synchronized (stats) {
16339                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16340                            app.pid, SystemClock.elapsedRealtime());
16341                }
16342                app.lastCpuTime = app.curCpuTime;
16343
16344            }
16345            app.setProcState = app.curProcState;
16346            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16347                app.notCachedSinceIdle = false;
16348            }
16349            if (!doingAll) {
16350                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16351            } else {
16352                app.procStateChanged = true;
16353            }
16354        }
16355
16356        if (changes != 0) {
16357            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16358            int i = mPendingProcessChanges.size()-1;
16359            ProcessChangeItem item = null;
16360            while (i >= 0) {
16361                item = mPendingProcessChanges.get(i);
16362                if (item.pid == app.pid) {
16363                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16364                    break;
16365                }
16366                i--;
16367            }
16368            if (i < 0) {
16369                // No existing item in pending changes; need a new one.
16370                final int NA = mAvailProcessChanges.size();
16371                if (NA > 0) {
16372                    item = mAvailProcessChanges.remove(NA-1);
16373                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16374                } else {
16375                    item = new ProcessChangeItem();
16376                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16377                }
16378                item.changes = 0;
16379                item.pid = app.pid;
16380                item.uid = app.info.uid;
16381                if (mPendingProcessChanges.size() == 0) {
16382                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16383                            "*** Enqueueing dispatch processes changed!");
16384                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16385                }
16386                mPendingProcessChanges.add(item);
16387            }
16388            item.changes |= changes;
16389            item.processState = app.repProcState;
16390            item.foregroundActivities = app.repForegroundActivities;
16391            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16392                    + Integer.toHexString(System.identityHashCode(item))
16393                    + " " + app.toShortString() + ": changes=" + item.changes
16394                    + " procState=" + item.processState
16395                    + " foreground=" + item.foregroundActivities
16396                    + " type=" + app.adjType + " source=" + app.adjSource
16397                    + " target=" + app.adjTarget);
16398        }
16399
16400        return success;
16401    }
16402
16403    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16404        if (proc.thread != null) {
16405            if (proc.baseProcessTracker != null) {
16406                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16407            }
16408            if (proc.repProcState >= 0) {
16409                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16410                        proc.repProcState);
16411            }
16412        }
16413    }
16414
16415    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16416            ProcessRecord TOP_APP, boolean doingAll, long now) {
16417        if (app.thread == null) {
16418            return false;
16419        }
16420
16421        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16422
16423        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16424    }
16425
16426    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16427            boolean oomAdj) {
16428        if (isForeground != proc.foregroundServices) {
16429            proc.foregroundServices = isForeground;
16430            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16431                    proc.info.uid);
16432            if (isForeground) {
16433                if (curProcs == null) {
16434                    curProcs = new ArrayList<ProcessRecord>();
16435                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16436                }
16437                if (!curProcs.contains(proc)) {
16438                    curProcs.add(proc);
16439                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16440                            proc.info.packageName, proc.info.uid);
16441                }
16442            } else {
16443                if (curProcs != null) {
16444                    if (curProcs.remove(proc)) {
16445                        mBatteryStatsService.noteEvent(
16446                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16447                                proc.info.packageName, proc.info.uid);
16448                        if (curProcs.size() <= 0) {
16449                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16450                        }
16451                    }
16452                }
16453            }
16454            if (oomAdj) {
16455                updateOomAdjLocked();
16456            }
16457        }
16458    }
16459
16460    private final ActivityRecord resumedAppLocked() {
16461        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16462        String pkg;
16463        int uid;
16464        if (act != null) {
16465            pkg = act.packageName;
16466            uid = act.info.applicationInfo.uid;
16467        } else {
16468            pkg = null;
16469            uid = -1;
16470        }
16471        // Has the UID or resumed package name changed?
16472        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16473                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16474            if (mCurResumedPackage != null) {
16475                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16476                        mCurResumedPackage, mCurResumedUid);
16477            }
16478            mCurResumedPackage = pkg;
16479            mCurResumedUid = uid;
16480            if (mCurResumedPackage != null) {
16481                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16482                        mCurResumedPackage, mCurResumedUid);
16483            }
16484        }
16485        return act;
16486    }
16487
16488    final boolean updateOomAdjLocked(ProcessRecord app) {
16489        final ActivityRecord TOP_ACT = resumedAppLocked();
16490        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16491        final boolean wasCached = app.cached;
16492
16493        mAdjSeq++;
16494
16495        // This is the desired cached adjusment we want to tell it to use.
16496        // If our app is currently cached, we know it, and that is it.  Otherwise,
16497        // we don't know it yet, and it needs to now be cached we will then
16498        // need to do a complete oom adj.
16499        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16500                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16501        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16502                SystemClock.uptimeMillis());
16503        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16504            // Changed to/from cached state, so apps after it in the LRU
16505            // list may also be changed.
16506            updateOomAdjLocked();
16507        }
16508        return success;
16509    }
16510
16511    final void updateOomAdjLocked() {
16512        final ActivityRecord TOP_ACT = resumedAppLocked();
16513        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16514        final long now = SystemClock.uptimeMillis();
16515        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16516        final int N = mLruProcesses.size();
16517
16518        if (false) {
16519            RuntimeException e = new RuntimeException();
16520            e.fillInStackTrace();
16521            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16522        }
16523
16524        mAdjSeq++;
16525        mNewNumServiceProcs = 0;
16526        mNewNumAServiceProcs = 0;
16527
16528        final int emptyProcessLimit;
16529        final int cachedProcessLimit;
16530        if (mProcessLimit <= 0) {
16531            emptyProcessLimit = cachedProcessLimit = 0;
16532        } else if (mProcessLimit == 1) {
16533            emptyProcessLimit = 1;
16534            cachedProcessLimit = 0;
16535        } else {
16536            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16537            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16538        }
16539
16540        // Let's determine how many processes we have running vs.
16541        // how many slots we have for background processes; we may want
16542        // to put multiple processes in a slot of there are enough of
16543        // them.
16544        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16545                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16546        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16547        if (numEmptyProcs > cachedProcessLimit) {
16548            // If there are more empty processes than our limit on cached
16549            // processes, then use the cached process limit for the factor.
16550            // This ensures that the really old empty processes get pushed
16551            // down to the bottom, so if we are running low on memory we will
16552            // have a better chance at keeping around more cached processes
16553            // instead of a gazillion empty processes.
16554            numEmptyProcs = cachedProcessLimit;
16555        }
16556        int emptyFactor = numEmptyProcs/numSlots;
16557        if (emptyFactor < 1) emptyFactor = 1;
16558        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16559        if (cachedFactor < 1) cachedFactor = 1;
16560        int stepCached = 0;
16561        int stepEmpty = 0;
16562        int numCached = 0;
16563        int numEmpty = 0;
16564        int numTrimming = 0;
16565
16566        mNumNonCachedProcs = 0;
16567        mNumCachedHiddenProcs = 0;
16568
16569        // First update the OOM adjustment for each of the
16570        // application processes based on their current state.
16571        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16572        int nextCachedAdj = curCachedAdj+1;
16573        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16574        int nextEmptyAdj = curEmptyAdj+2;
16575        for (int i=N-1; i>=0; i--) {
16576            ProcessRecord app = mLruProcesses.get(i);
16577            if (!app.killedByAm && app.thread != null) {
16578                app.procStateChanged = false;
16579                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16580
16581                // If we haven't yet assigned the final cached adj
16582                // to the process, do that now.
16583                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16584                    switch (app.curProcState) {
16585                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16586                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16587                            // This process is a cached process holding activities...
16588                            // assign it the next cached value for that type, and then
16589                            // step that cached level.
16590                            app.curRawAdj = curCachedAdj;
16591                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16592                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16593                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16594                                    + ")");
16595                            if (curCachedAdj != nextCachedAdj) {
16596                                stepCached++;
16597                                if (stepCached >= cachedFactor) {
16598                                    stepCached = 0;
16599                                    curCachedAdj = nextCachedAdj;
16600                                    nextCachedAdj += 2;
16601                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16602                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16603                                    }
16604                                }
16605                            }
16606                            break;
16607                        default:
16608                            // For everything else, assign next empty cached process
16609                            // level and bump that up.  Note that this means that
16610                            // long-running services that have dropped down to the
16611                            // cached level will be treated as empty (since their process
16612                            // state is still as a service), which is what we want.
16613                            app.curRawAdj = curEmptyAdj;
16614                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16615                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16616                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16617                                    + ")");
16618                            if (curEmptyAdj != nextEmptyAdj) {
16619                                stepEmpty++;
16620                                if (stepEmpty >= emptyFactor) {
16621                                    stepEmpty = 0;
16622                                    curEmptyAdj = nextEmptyAdj;
16623                                    nextEmptyAdj += 2;
16624                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16625                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16626                                    }
16627                                }
16628                            }
16629                            break;
16630                    }
16631                }
16632
16633                applyOomAdjLocked(app, TOP_APP, true, now);
16634
16635                // Count the number of process types.
16636                switch (app.curProcState) {
16637                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16638                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16639                        mNumCachedHiddenProcs++;
16640                        numCached++;
16641                        if (numCached > cachedProcessLimit) {
16642                            killUnneededProcessLocked(app, "cached #" + numCached);
16643                        }
16644                        break;
16645                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16646                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16647                                && app.lastActivityTime < oldTime) {
16648                            killUnneededProcessLocked(app, "empty for "
16649                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16650                                    / 1000) + "s");
16651                        } else {
16652                            numEmpty++;
16653                            if (numEmpty > emptyProcessLimit) {
16654                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16655                            }
16656                        }
16657                        break;
16658                    default:
16659                        mNumNonCachedProcs++;
16660                        break;
16661                }
16662
16663                if (app.isolated && app.services.size() <= 0) {
16664                    // If this is an isolated process, and there are no
16665                    // services running in it, then the process is no longer
16666                    // needed.  We agressively kill these because we can by
16667                    // definition not re-use the same process again, and it is
16668                    // good to avoid having whatever code was running in them
16669                    // left sitting around after no longer needed.
16670                    killUnneededProcessLocked(app, "isolated not needed");
16671                }
16672
16673                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16674                        && !app.killedByAm) {
16675                    numTrimming++;
16676                }
16677            }
16678        }
16679
16680        mNumServiceProcs = mNewNumServiceProcs;
16681
16682        // Now determine the memory trimming level of background processes.
16683        // Unfortunately we need to start at the back of the list to do this
16684        // properly.  We only do this if the number of background apps we
16685        // are managing to keep around is less than half the maximum we desire;
16686        // if we are keeping a good number around, we'll let them use whatever
16687        // memory they want.
16688        final int numCachedAndEmpty = numCached + numEmpty;
16689        int memFactor;
16690        if (numCached <= ProcessList.TRIM_CACHED_APPS
16691                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16692            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16693                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16694            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16695                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16696            } else {
16697                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16698            }
16699        } else {
16700            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16701        }
16702        // We always allow the memory level to go up (better).  We only allow it to go
16703        // down if we are in a state where that is allowed, *and* the total number of processes
16704        // has gone down since last time.
16705        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16706                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16707                + " last=" + mLastNumProcesses);
16708        if (memFactor > mLastMemoryLevel) {
16709            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16710                memFactor = mLastMemoryLevel;
16711                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16712            }
16713        }
16714        mLastMemoryLevel = memFactor;
16715        mLastNumProcesses = mLruProcesses.size();
16716        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16717        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16718        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16719            if (mLowRamStartTime == 0) {
16720                mLowRamStartTime = now;
16721            }
16722            int step = 0;
16723            int fgTrimLevel;
16724            switch (memFactor) {
16725                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16726                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16727                    break;
16728                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16729                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16730                    break;
16731                default:
16732                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16733                    break;
16734            }
16735            int factor = numTrimming/3;
16736            int minFactor = 2;
16737            if (mHomeProcess != null) minFactor++;
16738            if (mPreviousProcess != null) minFactor++;
16739            if (factor < minFactor) factor = minFactor;
16740            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16741            for (int i=N-1; i>=0; i--) {
16742                ProcessRecord app = mLruProcesses.get(i);
16743                if (allChanged || app.procStateChanged) {
16744                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16745                    app.procStateChanged = false;
16746                }
16747                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16748                        && !app.killedByAm) {
16749                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16750                        try {
16751                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16752                                    "Trimming memory of " + app.processName
16753                                    + " to " + curLevel);
16754                            app.thread.scheduleTrimMemory(curLevel);
16755                        } catch (RemoteException e) {
16756                        }
16757                        if (false) {
16758                            // For now we won't do this; our memory trimming seems
16759                            // to be good enough at this point that destroying
16760                            // activities causes more harm than good.
16761                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16762                                    && app != mHomeProcess && app != mPreviousProcess) {
16763                                // Need to do this on its own message because the stack may not
16764                                // be in a consistent state at this point.
16765                                // For these apps we will also finish their activities
16766                                // to help them free memory.
16767                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16768                            }
16769                        }
16770                    }
16771                    app.trimMemoryLevel = curLevel;
16772                    step++;
16773                    if (step >= factor) {
16774                        step = 0;
16775                        switch (curLevel) {
16776                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16777                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16778                                break;
16779                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16780                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16781                                break;
16782                        }
16783                    }
16784                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16785                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16786                            && app.thread != null) {
16787                        try {
16788                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16789                                    "Trimming memory of heavy-weight " + app.processName
16790                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16791                            app.thread.scheduleTrimMemory(
16792                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16793                        } catch (RemoteException e) {
16794                        }
16795                    }
16796                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16797                } else {
16798                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16799                            || app.systemNoUi) && app.pendingUiClean) {
16800                        // If this application is now in the background and it
16801                        // had done UI, then give it the special trim level to
16802                        // have it free UI resources.
16803                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16804                        if (app.trimMemoryLevel < level && app.thread != null) {
16805                            try {
16806                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16807                                        "Trimming memory of bg-ui " + app.processName
16808                                        + " to " + level);
16809                                app.thread.scheduleTrimMemory(level);
16810                            } catch (RemoteException e) {
16811                            }
16812                        }
16813                        app.pendingUiClean = false;
16814                    }
16815                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16816                        try {
16817                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16818                                    "Trimming memory of fg " + app.processName
16819                                    + " to " + fgTrimLevel);
16820                            app.thread.scheduleTrimMemory(fgTrimLevel);
16821                        } catch (RemoteException e) {
16822                        }
16823                    }
16824                    app.trimMemoryLevel = fgTrimLevel;
16825                }
16826            }
16827        } else {
16828            if (mLowRamStartTime != 0) {
16829                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16830                mLowRamStartTime = 0;
16831            }
16832            for (int i=N-1; i>=0; i--) {
16833                ProcessRecord app = mLruProcesses.get(i);
16834                if (allChanged || app.procStateChanged) {
16835                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16836                    app.procStateChanged = false;
16837                }
16838                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16839                        || app.systemNoUi) && app.pendingUiClean) {
16840                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16841                            && app.thread != null) {
16842                        try {
16843                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16844                                    "Trimming memory of ui hidden " + app.processName
16845                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16846                            app.thread.scheduleTrimMemory(
16847                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16848                        } catch (RemoteException e) {
16849                        }
16850                    }
16851                    app.pendingUiClean = false;
16852                }
16853                app.trimMemoryLevel = 0;
16854            }
16855        }
16856
16857        if (mAlwaysFinishActivities) {
16858            // Need to do this on its own message because the stack may not
16859            // be in a consistent state at this point.
16860            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16861        }
16862
16863        if (allChanged) {
16864            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16865        }
16866
16867        if (mProcessStats.shouldWriteNowLocked(now)) {
16868            mHandler.post(new Runnable() {
16869                @Override public void run() {
16870                    synchronized (ActivityManagerService.this) {
16871                        mProcessStats.writeStateAsyncLocked();
16872                    }
16873                }
16874            });
16875        }
16876
16877        if (DEBUG_OOM_ADJ) {
16878            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16879        }
16880    }
16881
16882    final void trimApplications() {
16883        synchronized (this) {
16884            int i;
16885
16886            // First remove any unused application processes whose package
16887            // has been removed.
16888            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16889                final ProcessRecord app = mRemovedProcesses.get(i);
16890                if (app.activities.size() == 0
16891                        && app.curReceiver == null && app.services.size() == 0) {
16892                    Slog.i(
16893                        TAG, "Exiting empty application process "
16894                        + app.processName + " ("
16895                        + (app.thread != null ? app.thread.asBinder() : null)
16896                        + ")\n");
16897                    if (app.pid > 0 && app.pid != MY_PID) {
16898                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16899                                app.processName, app.setAdj, "empty");
16900                        app.killedByAm = true;
16901                        Process.killProcessQuiet(app.pid);
16902                        Process.killProcessGroup(app.info.uid, app.pid);
16903                    } else {
16904                        try {
16905                            app.thread.scheduleExit();
16906                        } catch (Exception e) {
16907                            // Ignore exceptions.
16908                        }
16909                    }
16910                    cleanUpApplicationRecordLocked(app, false, true, -1);
16911                    mRemovedProcesses.remove(i);
16912
16913                    if (app.persistent) {
16914                        addAppLocked(app.info, false, null /* ABI override */);
16915                    }
16916                }
16917            }
16918
16919            // Now update the oom adj for all processes.
16920            updateOomAdjLocked();
16921        }
16922    }
16923
16924    /** This method sends the specified signal to each of the persistent apps */
16925    public void signalPersistentProcesses(int sig) throws RemoteException {
16926        if (sig != Process.SIGNAL_USR1) {
16927            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16928        }
16929
16930        synchronized (this) {
16931            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16932                    != PackageManager.PERMISSION_GRANTED) {
16933                throw new SecurityException("Requires permission "
16934                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16935            }
16936
16937            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16938                ProcessRecord r = mLruProcesses.get(i);
16939                if (r.thread != null && r.persistent) {
16940                    Process.sendSignal(r.pid, sig);
16941                }
16942            }
16943        }
16944    }
16945
16946    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16947        if (proc == null || proc == mProfileProc) {
16948            proc = mProfileProc;
16949            path = mProfileFile;
16950            profileType = mProfileType;
16951            clearProfilerLocked();
16952        }
16953        if (proc == null) {
16954            return;
16955        }
16956        try {
16957            proc.thread.profilerControl(false, path, null, profileType);
16958        } catch (RemoteException e) {
16959            throw new IllegalStateException("Process disappeared");
16960        }
16961    }
16962
16963    private void clearProfilerLocked() {
16964        if (mProfileFd != null) {
16965            try {
16966                mProfileFd.close();
16967            } catch (IOException e) {
16968            }
16969        }
16970        mProfileApp = null;
16971        mProfileProc = null;
16972        mProfileFile = null;
16973        mProfileType = 0;
16974        mAutoStopProfiler = false;
16975    }
16976
16977    public boolean profileControl(String process, int userId, boolean start,
16978            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16979
16980        try {
16981            synchronized (this) {
16982                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16983                // its own permission.
16984                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16985                        != PackageManager.PERMISSION_GRANTED) {
16986                    throw new SecurityException("Requires permission "
16987                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16988                }
16989
16990                if (start && fd == null) {
16991                    throw new IllegalArgumentException("null fd");
16992                }
16993
16994                ProcessRecord proc = null;
16995                if (process != null) {
16996                    proc = findProcessLocked(process, userId, "profileControl");
16997                }
16998
16999                if (start && (proc == null || proc.thread == null)) {
17000                    throw new IllegalArgumentException("Unknown process: " + process);
17001                }
17002
17003                if (start) {
17004                    stopProfilerLocked(null, null, 0);
17005                    setProfileApp(proc.info, proc.processName, path, fd, false);
17006                    mProfileProc = proc;
17007                    mProfileType = profileType;
17008                    try {
17009                        fd = fd.dup();
17010                    } catch (IOException e) {
17011                        fd = null;
17012                    }
17013                    proc.thread.profilerControl(start, path, fd, profileType);
17014                    fd = null;
17015                    mProfileFd = null;
17016                } else {
17017                    stopProfilerLocked(proc, path, profileType);
17018                    if (fd != null) {
17019                        try {
17020                            fd.close();
17021                        } catch (IOException e) {
17022                        }
17023                    }
17024                }
17025
17026                return true;
17027            }
17028        } catch (RemoteException e) {
17029            throw new IllegalStateException("Process disappeared");
17030        } finally {
17031            if (fd != null) {
17032                try {
17033                    fd.close();
17034                } catch (IOException e) {
17035                }
17036            }
17037        }
17038    }
17039
17040    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17041        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17042                userId, true, ALLOW_FULL_ONLY, callName, null);
17043        ProcessRecord proc = null;
17044        try {
17045            int pid = Integer.parseInt(process);
17046            synchronized (mPidsSelfLocked) {
17047                proc = mPidsSelfLocked.get(pid);
17048            }
17049        } catch (NumberFormatException e) {
17050        }
17051
17052        if (proc == null) {
17053            ArrayMap<String, SparseArray<ProcessRecord>> all
17054                    = mProcessNames.getMap();
17055            SparseArray<ProcessRecord> procs = all.get(process);
17056            if (procs != null && procs.size() > 0) {
17057                proc = procs.valueAt(0);
17058                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17059                    for (int i=1; i<procs.size(); i++) {
17060                        ProcessRecord thisProc = procs.valueAt(i);
17061                        if (thisProc.userId == userId) {
17062                            proc = thisProc;
17063                            break;
17064                        }
17065                    }
17066                }
17067            }
17068        }
17069
17070        return proc;
17071    }
17072
17073    public boolean dumpHeap(String process, int userId, boolean managed,
17074            String path, ParcelFileDescriptor fd) throws RemoteException {
17075
17076        try {
17077            synchronized (this) {
17078                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17079                // its own permission (same as profileControl).
17080                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17081                        != PackageManager.PERMISSION_GRANTED) {
17082                    throw new SecurityException("Requires permission "
17083                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17084                }
17085
17086                if (fd == null) {
17087                    throw new IllegalArgumentException("null fd");
17088                }
17089
17090                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17091                if (proc == null || proc.thread == null) {
17092                    throw new IllegalArgumentException("Unknown process: " + process);
17093                }
17094
17095                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17096                if (!isDebuggable) {
17097                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17098                        throw new SecurityException("Process not debuggable: " + proc);
17099                    }
17100                }
17101
17102                proc.thread.dumpHeap(managed, path, fd);
17103                fd = null;
17104                return true;
17105            }
17106        } catch (RemoteException e) {
17107            throw new IllegalStateException("Process disappeared");
17108        } finally {
17109            if (fd != null) {
17110                try {
17111                    fd.close();
17112                } catch (IOException e) {
17113                }
17114            }
17115        }
17116    }
17117
17118    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17119    public void monitor() {
17120        synchronized (this) { }
17121    }
17122
17123    void onCoreSettingsChange(Bundle settings) {
17124        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17125            ProcessRecord processRecord = mLruProcesses.get(i);
17126            try {
17127                if (processRecord.thread != null) {
17128                    processRecord.thread.setCoreSettings(settings);
17129                }
17130            } catch (RemoteException re) {
17131                /* ignore */
17132            }
17133        }
17134    }
17135
17136    // Multi-user methods
17137
17138    /**
17139     * Start user, if its not already running, but don't bring it to foreground.
17140     */
17141    @Override
17142    public boolean startUserInBackground(final int userId) {
17143        return startUser(userId, /* foreground */ false);
17144    }
17145
17146    /**
17147     * Refreshes the list of users related to the current user when either a
17148     * user switch happens or when a new related user is started in the
17149     * background.
17150     */
17151    private void updateCurrentProfileIdsLocked() {
17152        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17153                mCurrentUserId, false /* enabledOnly */);
17154        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17155        for (int i = 0; i < currentProfileIds.length; i++) {
17156            currentProfileIds[i] = profiles.get(i).id;
17157        }
17158        mCurrentProfileIds = currentProfileIds;
17159
17160        synchronized (mUserProfileGroupIdsSelfLocked) {
17161            mUserProfileGroupIdsSelfLocked.clear();
17162            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17163            for (int i = 0; i < users.size(); i++) {
17164                UserInfo user = users.get(i);
17165                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17166                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17167                }
17168            }
17169        }
17170    }
17171
17172    private Set getProfileIdsLocked(int userId) {
17173        Set userIds = new HashSet<Integer>();
17174        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17175                userId, false /* enabledOnly */);
17176        for (UserInfo user : profiles) {
17177            userIds.add(Integer.valueOf(user.id));
17178        }
17179        return userIds;
17180    }
17181
17182    @Override
17183    public boolean switchUser(final int userId) {
17184        return startUser(userId, /* foregound */ true);
17185    }
17186
17187    private boolean startUser(final int userId, boolean foreground) {
17188        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17189                != PackageManager.PERMISSION_GRANTED) {
17190            String msg = "Permission Denial: switchUser() from pid="
17191                    + Binder.getCallingPid()
17192                    + ", uid=" + Binder.getCallingUid()
17193                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17194            Slog.w(TAG, msg);
17195            throw new SecurityException(msg);
17196        }
17197
17198        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17199
17200        final long ident = Binder.clearCallingIdentity();
17201        try {
17202            synchronized (this) {
17203                final int oldUserId = mCurrentUserId;
17204                if (oldUserId == userId) {
17205                    return true;
17206                }
17207
17208                mStackSupervisor.setLockTaskModeLocked(null, false);
17209
17210                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17211                if (userInfo == null) {
17212                    Slog.w(TAG, "No user info for user #" + userId);
17213                    return false;
17214                }
17215
17216                if (foreground) {
17217                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17218                            R.anim.screen_user_enter);
17219                }
17220
17221                boolean needStart = false;
17222
17223                // If the user we are switching to is not currently started, then
17224                // we need to start it now.
17225                if (mStartedUsers.get(userId) == null) {
17226                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17227                    updateStartedUserArrayLocked();
17228                    needStart = true;
17229                }
17230
17231                final Integer userIdInt = Integer.valueOf(userId);
17232                mUserLru.remove(userIdInt);
17233                mUserLru.add(userIdInt);
17234
17235                if (foreground) {
17236                    mCurrentUserId = userId;
17237                    updateCurrentProfileIdsLocked();
17238                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17239                    // Once the internal notion of the active user has switched, we lock the device
17240                    // with the option to show the user switcher on the keyguard.
17241                    mWindowManager.lockNow(null);
17242                } else {
17243                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17244                    updateCurrentProfileIdsLocked();
17245                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17246                    mUserLru.remove(currentUserIdInt);
17247                    mUserLru.add(currentUserIdInt);
17248                }
17249
17250                final UserStartedState uss = mStartedUsers.get(userId);
17251
17252                // Make sure user is in the started state.  If it is currently
17253                // stopping, we need to knock that off.
17254                if (uss.mState == UserStartedState.STATE_STOPPING) {
17255                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17256                    // so we can just fairly silently bring the user back from
17257                    // the almost-dead.
17258                    uss.mState = UserStartedState.STATE_RUNNING;
17259                    updateStartedUserArrayLocked();
17260                    needStart = true;
17261                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17262                    // This means ACTION_SHUTDOWN has been sent, so we will
17263                    // need to treat this as a new boot of the user.
17264                    uss.mState = UserStartedState.STATE_BOOTING;
17265                    updateStartedUserArrayLocked();
17266                    needStart = true;
17267                }
17268
17269                if (uss.mState == UserStartedState.STATE_BOOTING) {
17270                    // Booting up a new user, need to tell system services about it.
17271                    // Note that this is on the same handler as scheduling of broadcasts,
17272                    // which is important because it needs to go first.
17273                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
17274                }
17275
17276                if (foreground) {
17277                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17278                            oldUserId));
17279                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17280                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17281                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17282                            oldUserId, userId, uss));
17283                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17284                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17285                }
17286
17287                if (needStart) {
17288                    // Send USER_STARTED broadcast
17289                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17290                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17291                            | Intent.FLAG_RECEIVER_FOREGROUND);
17292                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17293                    broadcastIntentLocked(null, null, intent,
17294                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17295                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17296                }
17297
17298                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17299                    if (userId != UserHandle.USER_OWNER) {
17300                        // Send PRE_BOOT_COMPLETED broadcasts for this new user
17301                        final ArrayList<ComponentName> doneReceivers
17302                                = new ArrayList<ComponentName>();
17303                        deliverPreBootCompleted(null, doneReceivers, userId);
17304
17305                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17306                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17307                        broadcastIntentLocked(null, null, intent, null,
17308                                new IIntentReceiver.Stub() {
17309                                    public void performReceive(Intent intent, int resultCode,
17310                                            String data, Bundle extras, boolean ordered,
17311                                            boolean sticky, int sendingUser) {
17312                                        userInitialized(uss, userId);
17313                                    }
17314                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17315                                true, false, MY_PID, Process.SYSTEM_UID,
17316                                userId);
17317                        uss.initializing = true;
17318                    } else {
17319                        getUserManagerLocked().makeInitialized(userInfo.id);
17320                    }
17321                }
17322
17323                if (foreground) {
17324                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17325                    if (homeInFront) {
17326                        startHomeActivityLocked(userId);
17327                    } else {
17328                        mStackSupervisor.resumeTopActivitiesLocked();
17329                    }
17330                    EventLogTags.writeAmSwitchUser(userId);
17331                    getUserManagerLocked().userForeground(userId);
17332                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17333                } else {
17334                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17335                }
17336
17337                if (needStart) {
17338                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17339                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17340                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17341                    broadcastIntentLocked(null, null, intent,
17342                            null, new IIntentReceiver.Stub() {
17343                                @Override
17344                                public void performReceive(Intent intent, int resultCode, String data,
17345                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17346                                        throws RemoteException {
17347                                }
17348                            }, 0, null, null,
17349                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17350                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17351                }
17352            }
17353        } finally {
17354            Binder.restoreCallingIdentity(ident);
17355        }
17356
17357        return true;
17358    }
17359
17360    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17361        long ident = Binder.clearCallingIdentity();
17362        try {
17363            Intent intent;
17364            if (oldUserId >= 0) {
17365                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17366                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17367                int count = profiles.size();
17368                for (int i = 0; i < count; i++) {
17369                    int profileUserId = profiles.get(i).id;
17370                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17371                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17372                            | Intent.FLAG_RECEIVER_FOREGROUND);
17373                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17374                    broadcastIntentLocked(null, null, intent,
17375                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17376                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17377                }
17378            }
17379            if (newUserId >= 0) {
17380                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17381                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17382                int count = profiles.size();
17383                for (int i = 0; i < count; i++) {
17384                    int profileUserId = profiles.get(i).id;
17385                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17386                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17387                            | Intent.FLAG_RECEIVER_FOREGROUND);
17388                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17389                    broadcastIntentLocked(null, null, intent,
17390                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17391                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17392                }
17393                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17394                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17395                        | Intent.FLAG_RECEIVER_FOREGROUND);
17396                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17397                broadcastIntentLocked(null, null, intent,
17398                        null, null, 0, null, null,
17399                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17400                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17401            }
17402        } finally {
17403            Binder.restoreCallingIdentity(ident);
17404        }
17405    }
17406
17407    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17408            final int newUserId) {
17409        final int N = mUserSwitchObservers.beginBroadcast();
17410        if (N > 0) {
17411            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17412                int mCount = 0;
17413                @Override
17414                public void sendResult(Bundle data) throws RemoteException {
17415                    synchronized (ActivityManagerService.this) {
17416                        if (mCurUserSwitchCallback == this) {
17417                            mCount++;
17418                            if (mCount == N) {
17419                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17420                            }
17421                        }
17422                    }
17423                }
17424            };
17425            synchronized (this) {
17426                uss.switching = true;
17427                mCurUserSwitchCallback = callback;
17428            }
17429            for (int i=0; i<N; i++) {
17430                try {
17431                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17432                            newUserId, callback);
17433                } catch (RemoteException e) {
17434                }
17435            }
17436        } else {
17437            synchronized (this) {
17438                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17439            }
17440        }
17441        mUserSwitchObservers.finishBroadcast();
17442    }
17443
17444    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17445        synchronized (this) {
17446            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17447            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17448        }
17449    }
17450
17451    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17452        mCurUserSwitchCallback = null;
17453        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17454        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17455                oldUserId, newUserId, uss));
17456    }
17457
17458    void userInitialized(UserStartedState uss, int newUserId) {
17459        completeSwitchAndInitalize(uss, newUserId, true, false);
17460    }
17461
17462    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17463        completeSwitchAndInitalize(uss, newUserId, false, true);
17464    }
17465
17466    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17467            boolean clearInitializing, boolean clearSwitching) {
17468        boolean unfrozen = false;
17469        synchronized (this) {
17470            if (clearInitializing) {
17471                uss.initializing = false;
17472                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17473            }
17474            if (clearSwitching) {
17475                uss.switching = false;
17476            }
17477            if (!uss.switching && !uss.initializing) {
17478                mWindowManager.stopFreezingScreen();
17479                unfrozen = true;
17480            }
17481        }
17482        if (unfrozen) {
17483            final int N = mUserSwitchObservers.beginBroadcast();
17484            for (int i=0; i<N; i++) {
17485                try {
17486                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17487                } catch (RemoteException e) {
17488                }
17489            }
17490            mUserSwitchObservers.finishBroadcast();
17491        }
17492    }
17493
17494    void scheduleStartProfilesLocked() {
17495        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17496            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17497                    DateUtils.SECOND_IN_MILLIS);
17498        }
17499    }
17500
17501    void startProfilesLocked() {
17502        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17503        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17504                mCurrentUserId, false /* enabledOnly */);
17505        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17506        for (UserInfo user : profiles) {
17507            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17508                    && user.id != mCurrentUserId) {
17509                toStart.add(user);
17510            }
17511        }
17512        final int n = toStart.size();
17513        int i = 0;
17514        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17515            startUserInBackground(toStart.get(i).id);
17516        }
17517        if (i < n) {
17518            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17519        }
17520    }
17521
17522    void finishUserBoot(UserStartedState uss) {
17523        synchronized (this) {
17524            if (uss.mState == UserStartedState.STATE_BOOTING
17525                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17526                uss.mState = UserStartedState.STATE_RUNNING;
17527                final int userId = uss.mHandle.getIdentifier();
17528                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17529                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17530                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17531                broadcastIntentLocked(null, null, intent,
17532                        null, null, 0, null, null,
17533                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17534                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17535            }
17536        }
17537    }
17538
17539    void finishUserSwitch(UserStartedState uss) {
17540        synchronized (this) {
17541            finishUserBoot(uss);
17542
17543            startProfilesLocked();
17544
17545            int num = mUserLru.size();
17546            int i = 0;
17547            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17548                Integer oldUserId = mUserLru.get(i);
17549                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17550                if (oldUss == null) {
17551                    // Shouldn't happen, but be sane if it does.
17552                    mUserLru.remove(i);
17553                    num--;
17554                    continue;
17555                }
17556                if (oldUss.mState == UserStartedState.STATE_STOPPING
17557                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17558                    // This user is already stopping, doesn't count.
17559                    num--;
17560                    i++;
17561                    continue;
17562                }
17563                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17564                    // Owner and current can't be stopped, but count as running.
17565                    i++;
17566                    continue;
17567                }
17568                // This is a user to be stopped.
17569                stopUserLocked(oldUserId, null);
17570                num--;
17571                i++;
17572            }
17573        }
17574    }
17575
17576    @Override
17577    public int stopUser(final int userId, final IStopUserCallback callback) {
17578        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17579                != PackageManager.PERMISSION_GRANTED) {
17580            String msg = "Permission Denial: switchUser() from pid="
17581                    + Binder.getCallingPid()
17582                    + ", uid=" + Binder.getCallingUid()
17583                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17584            Slog.w(TAG, msg);
17585            throw new SecurityException(msg);
17586        }
17587        if (userId <= 0) {
17588            throw new IllegalArgumentException("Can't stop primary user " + userId);
17589        }
17590        synchronized (this) {
17591            return stopUserLocked(userId, callback);
17592        }
17593    }
17594
17595    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17596        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17597        if (mCurrentUserId == userId) {
17598            return ActivityManager.USER_OP_IS_CURRENT;
17599        }
17600
17601        final UserStartedState uss = mStartedUsers.get(userId);
17602        if (uss == null) {
17603            // User is not started, nothing to do...  but we do need to
17604            // callback if requested.
17605            if (callback != null) {
17606                mHandler.post(new Runnable() {
17607                    @Override
17608                    public void run() {
17609                        try {
17610                            callback.userStopped(userId);
17611                        } catch (RemoteException e) {
17612                        }
17613                    }
17614                });
17615            }
17616            return ActivityManager.USER_OP_SUCCESS;
17617        }
17618
17619        if (callback != null) {
17620            uss.mStopCallbacks.add(callback);
17621        }
17622
17623        if (uss.mState != UserStartedState.STATE_STOPPING
17624                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17625            uss.mState = UserStartedState.STATE_STOPPING;
17626            updateStartedUserArrayLocked();
17627
17628            long ident = Binder.clearCallingIdentity();
17629            try {
17630                // We are going to broadcast ACTION_USER_STOPPING and then
17631                // once that is done send a final ACTION_SHUTDOWN and then
17632                // stop the user.
17633                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17634                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17635                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17636                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17637                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17638                // This is the result receiver for the final shutdown broadcast.
17639                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17640                    @Override
17641                    public void performReceive(Intent intent, int resultCode, String data,
17642                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17643                        finishUserStop(uss);
17644                    }
17645                };
17646                // This is the result receiver for the initial stopping broadcast.
17647                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17648                    @Override
17649                    public void performReceive(Intent intent, int resultCode, String data,
17650                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17651                        // On to the next.
17652                        synchronized (ActivityManagerService.this) {
17653                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17654                                // Whoops, we are being started back up.  Abort, abort!
17655                                return;
17656                            }
17657                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17658                        }
17659                        mBatteryStatsService.noteEvent(
17660                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17661                                Integer.toString(userId), userId);
17662                        mSystemServiceManager.stopUser(userId);
17663                        broadcastIntentLocked(null, null, shutdownIntent,
17664                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17665                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17666                    }
17667                };
17668                // Kick things off.
17669                broadcastIntentLocked(null, null, stoppingIntent,
17670                        null, stoppingReceiver, 0, null, null,
17671                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17672                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17673            } finally {
17674                Binder.restoreCallingIdentity(ident);
17675            }
17676        }
17677
17678        return ActivityManager.USER_OP_SUCCESS;
17679    }
17680
17681    void finishUserStop(UserStartedState uss) {
17682        final int userId = uss.mHandle.getIdentifier();
17683        boolean stopped;
17684        ArrayList<IStopUserCallback> callbacks;
17685        synchronized (this) {
17686            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17687            if (mStartedUsers.get(userId) != uss) {
17688                stopped = false;
17689            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17690                stopped = false;
17691            } else {
17692                stopped = true;
17693                // User can no longer run.
17694                mStartedUsers.remove(userId);
17695                mUserLru.remove(Integer.valueOf(userId));
17696                updateStartedUserArrayLocked();
17697
17698                // Clean up all state and processes associated with the user.
17699                // Kill all the processes for the user.
17700                forceStopUserLocked(userId, "finish user");
17701            }
17702        }
17703
17704        // Explicitly remove the old information in mRecentTasks.
17705        removeRecentTasksForUser(userId);
17706
17707        for (int i=0; i<callbacks.size(); i++) {
17708            try {
17709                if (stopped) callbacks.get(i).userStopped(userId);
17710                else callbacks.get(i).userStopAborted(userId);
17711            } catch (RemoteException e) {
17712            }
17713        }
17714
17715        if (stopped) {
17716            mSystemServiceManager.cleanupUser(userId);
17717            synchronized (this) {
17718                mStackSupervisor.removeUserLocked(userId);
17719            }
17720        }
17721    }
17722
17723    @Override
17724    public UserInfo getCurrentUser() {
17725        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17726                != PackageManager.PERMISSION_GRANTED) && (
17727                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17728                != PackageManager.PERMISSION_GRANTED)) {
17729            String msg = "Permission Denial: getCurrentUser() from pid="
17730                    + Binder.getCallingPid()
17731                    + ", uid=" + Binder.getCallingUid()
17732                    + " requires " + INTERACT_ACROSS_USERS;
17733            Slog.w(TAG, msg);
17734            throw new SecurityException(msg);
17735        }
17736        synchronized (this) {
17737            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17738        }
17739    }
17740
17741    int getCurrentUserIdLocked() {
17742        return mCurrentUserId;
17743    }
17744
17745    @Override
17746    public boolean isUserRunning(int userId, boolean orStopped) {
17747        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17748                != PackageManager.PERMISSION_GRANTED) {
17749            String msg = "Permission Denial: isUserRunning() from pid="
17750                    + Binder.getCallingPid()
17751                    + ", uid=" + Binder.getCallingUid()
17752                    + " requires " + INTERACT_ACROSS_USERS;
17753            Slog.w(TAG, msg);
17754            throw new SecurityException(msg);
17755        }
17756        synchronized (this) {
17757            return isUserRunningLocked(userId, orStopped);
17758        }
17759    }
17760
17761    boolean isUserRunningLocked(int userId, boolean orStopped) {
17762        UserStartedState state = mStartedUsers.get(userId);
17763        if (state == null) {
17764            return false;
17765        }
17766        if (orStopped) {
17767            return true;
17768        }
17769        return state.mState != UserStartedState.STATE_STOPPING
17770                && state.mState != UserStartedState.STATE_SHUTDOWN;
17771    }
17772
17773    @Override
17774    public int[] getRunningUserIds() {
17775        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17776                != PackageManager.PERMISSION_GRANTED) {
17777            String msg = "Permission Denial: isUserRunning() from pid="
17778                    + Binder.getCallingPid()
17779                    + ", uid=" + Binder.getCallingUid()
17780                    + " requires " + INTERACT_ACROSS_USERS;
17781            Slog.w(TAG, msg);
17782            throw new SecurityException(msg);
17783        }
17784        synchronized (this) {
17785            return mStartedUserArray;
17786        }
17787    }
17788
17789    private void updateStartedUserArrayLocked() {
17790        int num = 0;
17791        for (int i=0; i<mStartedUsers.size();  i++) {
17792            UserStartedState uss = mStartedUsers.valueAt(i);
17793            // This list does not include stopping users.
17794            if (uss.mState != UserStartedState.STATE_STOPPING
17795                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17796                num++;
17797            }
17798        }
17799        mStartedUserArray = new int[num];
17800        num = 0;
17801        for (int i=0; i<mStartedUsers.size();  i++) {
17802            UserStartedState uss = mStartedUsers.valueAt(i);
17803            if (uss.mState != UserStartedState.STATE_STOPPING
17804                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17805                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17806                num++;
17807            }
17808        }
17809    }
17810
17811    @Override
17812    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17813        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17814                != PackageManager.PERMISSION_GRANTED) {
17815            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17816                    + Binder.getCallingPid()
17817                    + ", uid=" + Binder.getCallingUid()
17818                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17819            Slog.w(TAG, msg);
17820            throw new SecurityException(msg);
17821        }
17822
17823        mUserSwitchObservers.register(observer);
17824    }
17825
17826    @Override
17827    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17828        mUserSwitchObservers.unregister(observer);
17829    }
17830
17831    private boolean userExists(int userId) {
17832        if (userId == 0) {
17833            return true;
17834        }
17835        UserManagerService ums = getUserManagerLocked();
17836        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17837    }
17838
17839    int[] getUsersLocked() {
17840        UserManagerService ums = getUserManagerLocked();
17841        return ums != null ? ums.getUserIds() : new int[] { 0 };
17842    }
17843
17844    UserManagerService getUserManagerLocked() {
17845        if (mUserManager == null) {
17846            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17847            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17848        }
17849        return mUserManager;
17850    }
17851
17852    private int applyUserId(int uid, int userId) {
17853        return UserHandle.getUid(userId, uid);
17854    }
17855
17856    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17857        if (info == null) return null;
17858        ApplicationInfo newInfo = new ApplicationInfo(info);
17859        newInfo.uid = applyUserId(info.uid, userId);
17860        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17861                + info.packageName;
17862        return newInfo;
17863    }
17864
17865    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17866        if (aInfo == null
17867                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17868            return aInfo;
17869        }
17870
17871        ActivityInfo info = new ActivityInfo(aInfo);
17872        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17873        return info;
17874    }
17875
17876    private final class LocalService extends ActivityManagerInternal {
17877        @Override
17878        public void goingToSleep() {
17879            ActivityManagerService.this.goingToSleep();
17880        }
17881
17882        @Override
17883        public void wakingUp() {
17884            ActivityManagerService.this.wakingUp();
17885        }
17886
17887        @Override
17888        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
17889                String processName, String abiOverride, int uid, Runnable crashHandler) {
17890            synchronized(ActivityManagerService.this) {
17891                ApplicationInfo info = new ApplicationInfo();
17892                // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
17893                // For isolated processes, the former contains the parent's uid and the latter the
17894                // actual uid of the isolated process.
17895                // In the special case introduced by this method (which is, starting an isolated
17896                // process directly from the SystemServer without an actual parent app process) the
17897                // closest thing to a parent's uid is SYSTEM_UID.
17898                // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
17899                // the |isolated| logic in the ProcessRecord constructor.
17900                info.uid = Process.SYSTEM_UID;
17901                info.processName = processName;
17902                info.className = entryPoint;
17903                info.packageName = "android";
17904                ProcessRecord proc = startProcessLocked(processName, info /* info */,
17905                        false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
17906                        null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
17907                        uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
17908                        crashHandler);
17909                return proc.pid;
17910            }
17911        }
17912    }
17913
17914    /**
17915     * An implementation of IAppTask, that allows an app to manage its own tasks via
17916     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17917     * only the process that calls getAppTasks() can call the AppTask methods.
17918     */
17919    class AppTaskImpl extends IAppTask.Stub {
17920        private int mTaskId;
17921        private int mCallingUid;
17922
17923        public AppTaskImpl(int taskId, int callingUid) {
17924            mTaskId = taskId;
17925            mCallingUid = callingUid;
17926        }
17927
17928        @Override
17929        public void finishAndRemoveTask() {
17930            // Ensure that we are called from the same process that created this AppTask
17931            if (mCallingUid != Binder.getCallingUid()) {
17932                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17933                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17934                return;
17935            }
17936
17937            synchronized (ActivityManagerService.this) {
17938                long origId = Binder.clearCallingIdentity();
17939                try {
17940                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17941                    if (tr != null) {
17942                        // Only kill the process if we are not a new document
17943                        int flags = tr.getBaseIntent().getFlags();
17944                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17945                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17946                        removeTaskByIdLocked(mTaskId,
17947                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17948                    }
17949                } finally {
17950                    Binder.restoreCallingIdentity(origId);
17951                }
17952            }
17953        }
17954
17955        @Override
17956        public ActivityManager.RecentTaskInfo getTaskInfo() {
17957            // Ensure that we are called from the same process that created this AppTask
17958            if (mCallingUid != Binder.getCallingUid()) {
17959                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17960                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17961                return null;
17962            }
17963
17964            synchronized (ActivityManagerService.this) {
17965                long origId = Binder.clearCallingIdentity();
17966                try {
17967                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17968                    if (tr != null) {
17969                        return createRecentTaskInfoFromTaskRecord(tr);
17970                    }
17971                } finally {
17972                    Binder.restoreCallingIdentity(origId);
17973                }
17974                return null;
17975            }
17976        }
17977    }
17978}
17979