ActivityManagerService.java revision f4f8bb793fe101af770dc974b29c26722bce285f
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.IActivityContainer;
37import android.app.IActivityContainerCallback;
38import android.app.IAppTask;
39import android.app.admin.DevicePolicyManager;
40import android.app.usage.UsageStats;
41import android.app.usage.UsageStatsManagerInternal;
42import android.appwidget.AppWidgetManager;
43import android.graphics.Rect;
44import android.os.BatteryStats;
45import android.os.PersistableBundle;
46import android.service.voice.IVoiceInteractionSession;
47import android.util.ArrayMap;
48import android.util.ArraySet;
49import android.util.SparseIntArray;
50
51import com.android.internal.R;
52import com.android.internal.annotations.GuardedBy;
53import com.android.internal.app.IAppOpsService;
54import com.android.internal.app.IVoiceInteractor;
55import com.android.internal.app.ProcessMap;
56import com.android.internal.app.ProcessStats;
57import com.android.internal.content.PackageMonitor;
58import com.android.internal.os.BackgroundThread;
59import com.android.internal.os.BatteryStatsImpl;
60import com.android.internal.os.ProcessCpuTracker;
61import com.android.internal.os.TransferPipe;
62import com.android.internal.os.Zygote;
63import com.android.internal.util.FastPrintWriter;
64import com.android.internal.util.FastXmlSerializer;
65import com.android.internal.util.MemInfoReader;
66import com.android.internal.util.Preconditions;
67import com.android.server.AppOpsService;
68import com.android.server.AttributeCache;
69import com.android.server.IntentResolver;
70import com.android.server.LocalServices;
71import com.android.server.ServiceThread;
72import com.android.server.SystemService;
73import com.android.server.SystemServiceManager;
74import com.android.server.Watchdog;
75import com.android.server.am.ActivityStack.ActivityState;
76import com.android.server.firewall.IntentFirewall;
77import com.android.server.pm.UserManagerService;
78import com.android.server.wm.AppTransition;
79import com.android.server.wm.WindowManagerService;
80import com.google.android.collect.Lists;
81import com.google.android.collect.Maps;
82
83import libcore.io.IoUtils;
84
85import org.xmlpull.v1.XmlPullParser;
86import org.xmlpull.v1.XmlPullParserException;
87import org.xmlpull.v1.XmlSerializer;
88
89import android.app.Activity;
90import android.app.ActivityManager;
91import android.app.ActivityManager.RunningTaskInfo;
92import android.app.ActivityManager.StackInfo;
93import android.app.ActivityManagerInternal;
94import android.app.ActivityManagerNative;
95import android.app.ActivityOptions;
96import android.app.ActivityThread;
97import android.app.AlertDialog;
98import android.app.AppGlobals;
99import android.app.ApplicationErrorReport;
100import android.app.Dialog;
101import android.app.IActivityController;
102import android.app.IApplicationThread;
103import android.app.IInstrumentationWatcher;
104import android.app.INotificationManager;
105import android.app.IProcessObserver;
106import android.app.IServiceConnection;
107import android.app.IStopUserCallback;
108import android.app.IUiAutomationConnection;
109import android.app.IUserSwitchObserver;
110import android.app.Instrumentation;
111import android.app.Notification;
112import android.app.NotificationManager;
113import android.app.PendingIntent;
114import android.app.backup.IBackupManager;
115import android.content.ActivityNotFoundException;
116import android.content.BroadcastReceiver;
117import android.content.ClipData;
118import android.content.ComponentCallbacks2;
119import android.content.ComponentName;
120import android.content.ContentProvider;
121import android.content.ContentResolver;
122import android.content.Context;
123import android.content.DialogInterface;
124import android.content.IContentProvider;
125import android.content.IIntentReceiver;
126import android.content.IIntentSender;
127import android.content.Intent;
128import android.content.IntentFilter;
129import android.content.IntentSender;
130import android.content.pm.ActivityInfo;
131import android.content.pm.ApplicationInfo;
132import android.content.pm.ConfigurationInfo;
133import android.content.pm.IPackageDataObserver;
134import android.content.pm.IPackageManager;
135import android.content.pm.InstrumentationInfo;
136import android.content.pm.PackageInfo;
137import android.content.pm.PackageManager;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.UserInfo;
140import android.content.pm.PackageManager.NameNotFoundException;
141import android.content.pm.PathPermission;
142import android.content.pm.ProviderInfo;
143import android.content.pm.ResolveInfo;
144import android.content.pm.ServiceInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.net.Proxy;
148import android.net.ProxyInfo;
149import android.net.Uri;
150import android.os.Binder;
151import android.os.Build;
152import android.os.Bundle;
153import android.os.Debug;
154import android.os.DropBoxManager;
155import android.os.Environment;
156import android.os.FactoryTest;
157import android.os.FileObserver;
158import android.os.FileUtils;
159import android.os.Handler;
160import android.os.IBinder;
161import android.os.IPermissionController;
162import android.os.IRemoteCallback;
163import android.os.IUserManager;
164import android.os.Looper;
165import android.os.Message;
166import android.os.Parcel;
167import android.os.ParcelFileDescriptor;
168import android.os.Process;
169import android.os.RemoteCallbackList;
170import android.os.RemoteException;
171import android.os.SELinux;
172import android.os.ServiceManager;
173import android.os.StrictMode;
174import android.os.SystemClock;
175import android.os.SystemProperties;
176import android.os.UpdateLock;
177import android.os.UserHandle;
178import android.provider.Settings;
179import android.text.format.DateUtils;
180import android.text.format.Time;
181import android.util.AtomicFile;
182import android.util.EventLog;
183import android.util.Log;
184import android.util.Pair;
185import android.util.PrintWriterPrinter;
186import android.util.Slog;
187import android.util.SparseArray;
188import android.util.TimeUtils;
189import android.util.Xml;
190import android.view.Gravity;
191import android.view.LayoutInflater;
192import android.view.View;
193import android.view.WindowManager;
194
195import java.io.BufferedInputStream;
196import java.io.BufferedOutputStream;
197import java.io.DataInputStream;
198import java.io.DataOutputStream;
199import java.io.File;
200import java.io.FileDescriptor;
201import java.io.FileInputStream;
202import java.io.FileNotFoundException;
203import java.io.FileOutputStream;
204import java.io.IOException;
205import java.io.InputStreamReader;
206import java.io.PrintWriter;
207import java.io.StringWriter;
208import java.lang.ref.WeakReference;
209import java.util.ArrayList;
210import java.util.Arrays;
211import java.util.Collections;
212import java.util.Comparator;
213import java.util.HashMap;
214import java.util.HashSet;
215import java.util.Iterator;
216import java.util.List;
217import java.util.Locale;
218import java.util.Map;
219import java.util.Set;
220import java.util.concurrent.atomic.AtomicBoolean;
221import java.util.concurrent.atomic.AtomicLong;
222
223public final class ActivityManagerService extends ActivityManagerNative
224        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
225
226    private static final String USER_DATA_DIR = "/data/user/";
227    // File that stores last updated system version and called preboot receivers
228    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
229
230    static final String TAG = "ActivityManager";
231    static final String TAG_MU = "ActivityManagerServiceMU";
232    static final boolean DEBUG = false;
233    static final boolean localLOGV = DEBUG;
234    static final boolean DEBUG_BACKUP = localLOGV || false;
235    static final boolean DEBUG_BROADCAST = localLOGV || false;
236    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
237    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
238    static final boolean DEBUG_CLEANUP = localLOGV || false;
239    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
240    static final boolean DEBUG_FOCUS = false;
241    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
242    static final boolean DEBUG_MU = localLOGV || false;
243    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
244    static final boolean DEBUG_LRU = localLOGV || false;
245    static final boolean DEBUG_PAUSE = localLOGV || false;
246    static final boolean DEBUG_POWER = localLOGV || false;
247    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
248    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
249    static final boolean DEBUG_PROCESSES = localLOGV || false;
250    static final boolean DEBUG_PROVIDER = localLOGV || false;
251    static final boolean DEBUG_RESULTS = localLOGV || false;
252    static final boolean DEBUG_SERVICE = localLOGV || false;
253    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
254    static final boolean DEBUG_STACK = localLOGV || false;
255    static final boolean DEBUG_SWITCH = localLOGV || false;
256    static final boolean DEBUG_TASKS = localLOGV || false;
257    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
258    static final boolean DEBUG_TRANSITION = localLOGV || false;
259    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
260    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
261    static final boolean DEBUG_VISBILITY = localLOGV || false;
262    static final boolean DEBUG_PSS = localLOGV || false;
263    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
264    static final boolean VALIDATE_TOKENS = false;
265    static final boolean SHOW_ACTIVITY_START_TIME = true;
266
267    // Control over CPU and battery monitoring.
268    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
269    static final boolean MONITOR_CPU_USAGE = true;
270    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
271    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
272    static final boolean MONITOR_THREAD_CPU_USAGE = false;
273
274    // The flags that are set for all calls we make to the package manager.
275    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
276
277    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
278
279    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
280
281    // Maximum number of recent tasks that we can remember.
282    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
283
284    // Maximum number recent bitmaps to keep in memory.
285    static final int MAX_RECENT_BITMAPS = 5;
286
287    // Amount of time after a call to stopAppSwitches() during which we will
288    // prevent further untrusted switches from happening.
289    static final long APP_SWITCH_DELAY_TIME = 5*1000;
290
291    // How long we wait for a launched process to attach to the activity manager
292    // before we decide it's never going to come up for real.
293    static final int PROC_START_TIMEOUT = 10*1000;
294
295    // How long we wait for a launched process to attach to the activity manager
296    // before we decide it's never going to come up for real, when the process was
297    // started with a wrapper for instrumentation (such as Valgrind) because it
298    // could take much longer than usual.
299    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
300
301    // How long to wait after going idle before forcing apps to GC.
302    static final int GC_TIMEOUT = 5*1000;
303
304    // The minimum amount of time between successive GC requests for a process.
305    static final int GC_MIN_INTERVAL = 60*1000;
306
307    // The minimum amount of time between successive PSS requests for a process.
308    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
309
310    // The minimum amount of time between successive PSS requests for a process
311    // when the request is due to the memory state being lowered.
312    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
313
314    // The rate at which we check for apps using excessive power -- 15 mins.
315    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
316
317    // The minimum sample duration we will allow before deciding we have
318    // enough data on wake locks to start killing things.
319    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
320
321    // The minimum sample duration we will allow before deciding we have
322    // enough data on CPU usage to start killing things.
323    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
324
325    // How long we allow a receiver to run before giving up on it.
326    static final int BROADCAST_FG_TIMEOUT = 10*1000;
327    static final int BROADCAST_BG_TIMEOUT = 60*1000;
328
329    // How long we wait until we timeout on key dispatching.
330    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
331
332    // How long we wait until we timeout on key dispatching during instrumentation.
333    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
334
335    // Amount of time we wait for observers to handle a user switch before
336    // giving up on them and unfreezing the screen.
337    static final int USER_SWITCH_TIMEOUT = 2*1000;
338
339    // Maximum number of users we allow to be running at a time.
340    static final int MAX_RUNNING_USERS = 3;
341
342    // How long to wait in getAssistContextExtras for the activity and foreground services
343    // to respond with the result.
344    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
345
346    // Maximum number of persisted Uri grants a package is allowed
347    static final int MAX_PERSISTED_URI_GRANTS = 128;
348
349    static final int MY_PID = Process.myPid();
350
351    static final String[] EMPTY_STRING_ARRAY = new String[0];
352
353    // How many bytes to write into the dropbox log before truncating
354    static final int DROPBOX_MAX_SIZE = 256 * 1024;
355
356    // Access modes for handleIncomingUser.
357    static final int ALLOW_NON_FULL = 0;
358    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
359    static final int ALLOW_FULL_ONLY = 2;
360
361    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
362
363    /** All system services */
364    SystemServiceManager mSystemServiceManager;
365
366    /** Run all ActivityStacks through this */
367    ActivityStackSupervisor mStackSupervisor;
368
369    public IntentFirewall mIntentFirewall;
370
371    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
372    // default actuion automatically.  Important for devices without direct input
373    // devices.
374    private boolean mShowDialogs = true;
375
376    BroadcastQueue mFgBroadcastQueue;
377    BroadcastQueue mBgBroadcastQueue;
378    // Convenient for easy iteration over the queues. Foreground is first
379    // so that dispatch of foreground broadcasts gets precedence.
380    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
381
382    BroadcastQueue broadcastQueueForIntent(Intent intent) {
383        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
384        if (DEBUG_BACKGROUND_BROADCAST) {
385            Slog.i(TAG, "Broadcast intent " + intent + " on "
386                    + (isFg ? "foreground" : "background")
387                    + " queue");
388        }
389        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
390    }
391
392    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
393        for (BroadcastQueue queue : mBroadcastQueues) {
394            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
395            if (r != null) {
396                return r;
397            }
398        }
399        return null;
400    }
401
402    /**
403     * Activity we have told the window manager to have key focus.
404     */
405    ActivityRecord mFocusedActivity = null;
406
407    /**
408     * List of intents that were used to start the most recent tasks.
409     */
410    ArrayList<TaskRecord> mRecentTasks;
411    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
412
413    public class PendingAssistExtras extends Binder implements Runnable {
414        public final ActivityRecord activity;
415        public boolean haveResult = false;
416        public Bundle result = null;
417        public PendingAssistExtras(ActivityRecord _activity) {
418            activity = _activity;
419        }
420        @Override
421        public void run() {
422            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
423            synchronized (this) {
424                haveResult = true;
425                notifyAll();
426            }
427        }
428    }
429
430    final ArrayList<PendingAssistExtras> mPendingAssistExtras
431            = new ArrayList<PendingAssistExtras>();
432
433    /**
434     * Process management.
435     */
436    final ProcessList mProcessList = new ProcessList();
437
438    /**
439     * All of the applications we currently have running organized by name.
440     * The keys are strings of the application package name (as
441     * returned by the package manager), and the keys are ApplicationRecord
442     * objects.
443     */
444    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
445
446    /**
447     * Tracking long-term execution of processes to look for abuse and other
448     * bad app behavior.
449     */
450    final ProcessStatsService mProcessStats;
451
452    /**
453     * The currently running isolated processes.
454     */
455    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
456
457    /**
458     * Counter for assigning isolated process uids, to avoid frequently reusing the
459     * same ones.
460     */
461    int mNextIsolatedProcessUid = 0;
462
463    /**
464     * The currently running heavy-weight process, if any.
465     */
466    ProcessRecord mHeavyWeightProcess = null;
467
468    /**
469     * The last time that various processes have crashed.
470     */
471    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
472
473    /**
474     * Information about a process that is currently marked as bad.
475     */
476    static final class BadProcessInfo {
477        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
478            this.time = time;
479            this.shortMsg = shortMsg;
480            this.longMsg = longMsg;
481            this.stack = stack;
482        }
483
484        final long time;
485        final String shortMsg;
486        final String longMsg;
487        final String stack;
488    }
489
490    /**
491     * Set of applications that we consider to be bad, and will reject
492     * incoming broadcasts from (which the user has no control over).
493     * Processes are added to this set when they have crashed twice within
494     * a minimum amount of time; they are removed from it when they are
495     * later restarted (hopefully due to some user action).  The value is the
496     * time it was added to the list.
497     */
498    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
499
500    /**
501     * All of the processes we currently have running organized by pid.
502     * The keys are the pid running the application.
503     *
504     * <p>NOTE: This object is protected by its own lock, NOT the global
505     * activity manager lock!
506     */
507    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
508
509    /**
510     * All of the processes that have been forced to be foreground.  The key
511     * is the pid of the caller who requested it (we hold a death
512     * link on it).
513     */
514    abstract class ForegroundToken implements IBinder.DeathRecipient {
515        int pid;
516        IBinder token;
517    }
518    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
519
520    /**
521     * List of records for processes that someone had tried to start before the
522     * system was ready.  We don't start them at that point, but ensure they
523     * are started by the time booting is complete.
524     */
525    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
526
527    /**
528     * List of persistent applications that are in the process
529     * of being started.
530     */
531    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
532
533    /**
534     * Processes that are being forcibly torn down.
535     */
536    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
537
538    /**
539     * List of running applications, sorted by recent usage.
540     * The first entry in the list is the least recently used.
541     */
542    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
543
544    /**
545     * Where in mLruProcesses that the processes hosting activities start.
546     */
547    int mLruProcessActivityStart = 0;
548
549    /**
550     * Where in mLruProcesses that the processes hosting services start.
551     * This is after (lower index) than mLruProcessesActivityStart.
552     */
553    int mLruProcessServiceStart = 0;
554
555    /**
556     * List of processes that should gc as soon as things are idle.
557     */
558    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
559
560    /**
561     * Processes we want to collect PSS data from.
562     */
563    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
564
565    /**
566     * Last time we requested PSS data of all processes.
567     */
568    long mLastFullPssTime = SystemClock.uptimeMillis();
569
570    /**
571     * If set, the next time we collect PSS data we should do a full collection
572     * with data from native processes and the kernel.
573     */
574    boolean mFullPssPending = false;
575
576    /**
577     * This is the process holding what we currently consider to be
578     * the "home" activity.
579     */
580    ProcessRecord mHomeProcess;
581
582    /**
583     * This is the process holding the activity the user last visited that
584     * is in a different process from the one they are currently in.
585     */
586    ProcessRecord mPreviousProcess;
587
588    /**
589     * The time at which the previous process was last visible.
590     */
591    long mPreviousProcessVisibleTime;
592
593    /**
594     * Which uses have been started, so are allowed to run code.
595     */
596    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
597
598    /**
599     * LRU list of history of current users.  Most recently current is at the end.
600     */
601    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
602
603    /**
604     * Constant array of the users that are currently started.
605     */
606    int[] mStartedUserArray = new int[] { 0 };
607
608    /**
609     * Registered observers of the user switching mechanics.
610     */
611    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
612            = new RemoteCallbackList<IUserSwitchObserver>();
613
614    /**
615     * Currently active user switch.
616     */
617    Object mCurUserSwitchCallback;
618
619    /**
620     * Packages that the user has asked to have run in screen size
621     * compatibility mode instead of filling the screen.
622     */
623    final CompatModePackages mCompatModePackages;
624
625    /**
626     * Set of IntentSenderRecord objects that are currently active.
627     */
628    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
629            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
630
631    /**
632     * Fingerprints (hashCode()) of stack traces that we've
633     * already logged DropBox entries for.  Guarded by itself.  If
634     * something (rogue user app) forces this over
635     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
636     */
637    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
638    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
639
640    /**
641     * Strict Mode background batched logging state.
642     *
643     * The string buffer is guarded by itself, and its lock is also
644     * used to determine if another batched write is already
645     * in-flight.
646     */
647    private final StringBuilder mStrictModeBuffer = new StringBuilder();
648
649    /**
650     * Keeps track of all IIntentReceivers that have been registered for
651     * broadcasts.  Hash keys are the receiver IBinder, hash value is
652     * a ReceiverList.
653     */
654    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
655            new HashMap<IBinder, ReceiverList>();
656
657    /**
658     * Resolver for broadcast intents to registered receivers.
659     * Holds BroadcastFilter (subclass of IntentFilter).
660     */
661    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
662            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
663        @Override
664        protected boolean allowFilterResult(
665                BroadcastFilter filter, List<BroadcastFilter> dest) {
666            IBinder target = filter.receiverList.receiver.asBinder();
667            for (int i=dest.size()-1; i>=0; i--) {
668                if (dest.get(i).receiverList.receiver.asBinder() == target) {
669                    return false;
670                }
671            }
672            return true;
673        }
674
675        @Override
676        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
677            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
678                    || userId == filter.owningUserId) {
679                return super.newResult(filter, match, userId);
680            }
681            return null;
682        }
683
684        @Override
685        protected BroadcastFilter[] newArray(int size) {
686            return new BroadcastFilter[size];
687        }
688
689        @Override
690        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
691            return packageName.equals(filter.packageName);
692        }
693    };
694
695    /**
696     * State of all active sticky broadcasts per user.  Keys are the action of the
697     * sticky Intent, values are an ArrayList of all broadcasted intents with
698     * that action (which should usually be one).  The SparseArray is keyed
699     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
700     * for stickies that are sent to all users.
701     */
702    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
703            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
704
705    final ActiveServices mServices;
706
707    /**
708     * Backup/restore process management
709     */
710    String mBackupAppName = null;
711    BackupRecord mBackupTarget = null;
712
713    final ProviderMap mProviderMap;
714
715    /**
716     * List of content providers who have clients waiting for them.  The
717     * application is currently being launched and the provider will be
718     * removed from this list once it is published.
719     */
720    final ArrayList<ContentProviderRecord> mLaunchingProviders
721            = new ArrayList<ContentProviderRecord>();
722
723    /**
724     * File storing persisted {@link #mGrantedUriPermissions}.
725     */
726    private final AtomicFile mGrantFile;
727
728    /** XML constants used in {@link #mGrantFile} */
729    private static final String TAG_URI_GRANTS = "uri-grants";
730    private static final String TAG_URI_GRANT = "uri-grant";
731    private static final String ATTR_USER_HANDLE = "userHandle";
732    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
733    private static final String ATTR_TARGET_USER_ID = "targetUserId";
734    private static final String ATTR_SOURCE_PKG = "sourcePkg";
735    private static final String ATTR_TARGET_PKG = "targetPkg";
736    private static final String ATTR_URI = "uri";
737    private static final String ATTR_MODE_FLAGS = "modeFlags";
738    private static final String ATTR_CREATED_TIME = "createdTime";
739    private static final String ATTR_PREFIX = "prefix";
740
741    /**
742     * Global set of specific {@link Uri} permissions that have been granted.
743     * This optimized lookup structure maps from {@link UriPermission#targetUid}
744     * to {@link UriPermission#uri} to {@link UriPermission}.
745     */
746    @GuardedBy("this")
747    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
748            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
749
750    public static class GrantUri {
751        public final int sourceUserId;
752        public final Uri uri;
753        public boolean prefix;
754
755        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
756            this.sourceUserId = sourceUserId;
757            this.uri = uri;
758            this.prefix = prefix;
759        }
760
761        @Override
762        public int hashCode() {
763            return toString().hashCode();
764        }
765
766        @Override
767        public boolean equals(Object o) {
768            if (o instanceof GrantUri) {
769                GrantUri other = (GrantUri) o;
770                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
771                        && prefix == other.prefix;
772            }
773            return false;
774        }
775
776        @Override
777        public String toString() {
778            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
779            if (prefix) result += " [prefix]";
780            return result;
781        }
782
783        public String toSafeString() {
784            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
785            if (prefix) result += " [prefix]";
786            return result;
787        }
788
789        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
790            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
791                    ContentProvider.getUriWithoutUserId(uri), false);
792        }
793    }
794
795    CoreSettingsObserver mCoreSettingsObserver;
796
797    /**
798     * Thread-local storage used to carry caller permissions over through
799     * indirect content-provider access.
800     */
801    private class Identity {
802        public int pid;
803        public int uid;
804
805        Identity(int _pid, int _uid) {
806            pid = _pid;
807            uid = _uid;
808        }
809    }
810
811    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
812
813    /**
814     * All information we have collected about the runtime performance of
815     * any user id that can impact battery performance.
816     */
817    final BatteryStatsService mBatteryStatsService;
818
819    /**
820     * Information about component usage
821     */
822    UsageStatsManagerInternal mUsageStatsService;
823
824    /**
825     * Information about and control over application operations
826     */
827    final AppOpsService mAppOpsService;
828
829    /**
830     * Save recent tasks information across reboots.
831     */
832    final TaskPersister mTaskPersister;
833
834    /**
835     * Current configuration information.  HistoryRecord objects are given
836     * a reference to this object to indicate which configuration they are
837     * currently running in, so this object must be kept immutable.
838     */
839    Configuration mConfiguration = new Configuration();
840
841    /**
842     * Current sequencing integer of the configuration, for skipping old
843     * configurations.
844     */
845    int mConfigurationSeq = 0;
846
847    /**
848     * Hardware-reported OpenGLES version.
849     */
850    final int GL_ES_VERSION;
851
852    /**
853     * List of initialization arguments to pass to all processes when binding applications to them.
854     * For example, references to the commonly used services.
855     */
856    HashMap<String, IBinder> mAppBindArgs;
857
858    /**
859     * Temporary to avoid allocations.  Protected by main lock.
860     */
861    final StringBuilder mStringBuilder = new StringBuilder(256);
862
863    /**
864     * Used to control how we initialize the service.
865     */
866    ComponentName mTopComponent;
867    String mTopAction = Intent.ACTION_MAIN;
868    String mTopData;
869    boolean mProcessesReady = false;
870    boolean mSystemReady = false;
871    boolean mBooting = false;
872    boolean mWaitingUpdate = false;
873    boolean mDidUpdate = false;
874    boolean mOnBattery = false;
875    boolean mLaunchWarningShown = false;
876
877    Context mContext;
878
879    int mFactoryTest;
880
881    boolean mCheckedForSetup;
882
883    /**
884     * The time at which we will allow normal application switches again,
885     * after a call to {@link #stopAppSwitches()}.
886     */
887    long mAppSwitchesAllowedTime;
888
889    /**
890     * This is set to true after the first switch after mAppSwitchesAllowedTime
891     * is set; any switches after that will clear the time.
892     */
893    boolean mDidAppSwitch;
894
895    /**
896     * Last time (in realtime) at which we checked for power usage.
897     */
898    long mLastPowerCheckRealtime;
899
900    /**
901     * Last time (in uptime) at which we checked for power usage.
902     */
903    long mLastPowerCheckUptime;
904
905    /**
906     * Set while we are wanting to sleep, to prevent any
907     * activities from being started/resumed.
908     */
909    private boolean mSleeping = false;
910
911    /**
912     * Set while we are running a voice interaction.  This overrides
913     * sleeping while it is active.
914     */
915    private boolean mRunningVoice = false;
916
917    /**
918     * State of external calls telling us if the device is asleep.
919     */
920    private boolean mWentToSleep = false;
921
922    /**
923     * State of external call telling us if the lock screen is shown.
924     */
925    private boolean mLockScreenShown = false;
926
927    /**
928     * Set if we are shutting down the system, similar to sleeping.
929     */
930    boolean mShuttingDown = false;
931
932    /**
933     * Current sequence id for oom_adj computation traversal.
934     */
935    int mAdjSeq = 0;
936
937    /**
938     * Current sequence id for process LRU updating.
939     */
940    int mLruSeq = 0;
941
942    /**
943     * Keep track of the non-cached/empty process we last found, to help
944     * determine how to distribute cached/empty processes next time.
945     */
946    int mNumNonCachedProcs = 0;
947
948    /**
949     * Keep track of the number of cached hidden procs, to balance oom adj
950     * distribution between those and empty procs.
951     */
952    int mNumCachedHiddenProcs = 0;
953
954    /**
955     * Keep track of the number of service processes we last found, to
956     * determine on the next iteration which should be B services.
957     */
958    int mNumServiceProcs = 0;
959    int mNewNumAServiceProcs = 0;
960    int mNewNumServiceProcs = 0;
961
962    /**
963     * Allow the current computed overall memory level of the system to go down?
964     * This is set to false when we are killing processes for reasons other than
965     * memory management, so that the now smaller process list will not be taken as
966     * an indication that memory is tighter.
967     */
968    boolean mAllowLowerMemLevel = false;
969
970    /**
971     * The last computed memory level, for holding when we are in a state that
972     * processes are going away for other reasons.
973     */
974    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
975
976    /**
977     * The last total number of process we have, to determine if changes actually look
978     * like a shrinking number of process due to lower RAM.
979     */
980    int mLastNumProcesses;
981
982    /**
983     * The uptime of the last time we performed idle maintenance.
984     */
985    long mLastIdleTime = SystemClock.uptimeMillis();
986
987    /**
988     * Total time spent with RAM that has been added in the past since the last idle time.
989     */
990    long mLowRamTimeSinceLastIdle = 0;
991
992    /**
993     * If RAM is currently low, when that horrible situation started.
994     */
995    long mLowRamStartTime = 0;
996
997    /**
998     * For reporting to battery stats the current top application.
999     */
1000    private String mCurResumedPackage = null;
1001    private int mCurResumedUid = -1;
1002
1003    /**
1004     * For reporting to battery stats the apps currently running foreground
1005     * service.  The ProcessMap is package/uid tuples; each of these contain
1006     * an array of the currently foreground processes.
1007     */
1008    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1009            = new ProcessMap<ArrayList<ProcessRecord>>();
1010
1011    /**
1012     * This is set if we had to do a delayed dexopt of an app before launching
1013     * it, to increase the ANR timeouts in that case.
1014     */
1015    boolean mDidDexOpt;
1016
1017    /**
1018     * Set if the systemServer made a call to enterSafeMode.
1019     */
1020    boolean mSafeMode;
1021
1022    String mDebugApp = null;
1023    boolean mWaitForDebugger = false;
1024    boolean mDebugTransient = false;
1025    String mOrigDebugApp = null;
1026    boolean mOrigWaitForDebugger = false;
1027    boolean mAlwaysFinishActivities = false;
1028    IActivityController mController = null;
1029    String mProfileApp = null;
1030    ProcessRecord mProfileProc = null;
1031    String mProfileFile;
1032    ParcelFileDescriptor mProfileFd;
1033    int mProfileType = 0;
1034    boolean mAutoStopProfiler = false;
1035    String mOpenGlTraceApp = null;
1036
1037    static class ProcessChangeItem {
1038        static final int CHANGE_ACTIVITIES = 1<<0;
1039        static final int CHANGE_PROCESS_STATE = 1<<1;
1040        int changes;
1041        int uid;
1042        int pid;
1043        int processState;
1044        boolean foregroundActivities;
1045    }
1046
1047    final RemoteCallbackList<IProcessObserver> mProcessObservers
1048            = new RemoteCallbackList<IProcessObserver>();
1049    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1050
1051    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1052            = new ArrayList<ProcessChangeItem>();
1053    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1054            = new ArrayList<ProcessChangeItem>();
1055
1056    /**
1057     * Runtime CPU use collection thread.  This object's lock is used to
1058     * protect all related state.
1059     */
1060    final Thread mProcessCpuThread;
1061
1062    /**
1063     * Used to collect process stats when showing not responding dialog.
1064     * Protected by mProcessCpuThread.
1065     */
1066    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1067            MONITOR_THREAD_CPU_USAGE);
1068    final AtomicLong mLastCpuTime = new AtomicLong(0);
1069    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1070
1071    long mLastWriteTime = 0;
1072
1073    /**
1074     * Used to retain an update lock when the foreground activity is in
1075     * immersive mode.
1076     */
1077    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1078
1079    /**
1080     * Set to true after the system has finished booting.
1081     */
1082    boolean mBooted = false;
1083
1084    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1085    int mProcessLimitOverride = -1;
1086
1087    WindowManagerService mWindowManager;
1088
1089    final ActivityThread mSystemThread;
1090
1091    int mCurrentUserId = 0;
1092    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1093
1094    /**
1095     * Mapping from each known user ID to the profile group ID it is associated with.
1096     */
1097    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1098
1099    private UserManagerService mUserManager;
1100
1101    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1102        final ProcessRecord mApp;
1103        final int mPid;
1104        final IApplicationThread mAppThread;
1105
1106        AppDeathRecipient(ProcessRecord app, int pid,
1107                IApplicationThread thread) {
1108            if (localLOGV) Slog.v(
1109                TAG, "New death recipient " + this
1110                + " for thread " + thread.asBinder());
1111            mApp = app;
1112            mPid = pid;
1113            mAppThread = thread;
1114        }
1115
1116        @Override
1117        public void binderDied() {
1118            if (localLOGV) Slog.v(
1119                TAG, "Death received in " + this
1120                + " for thread " + mAppThread.asBinder());
1121            synchronized(ActivityManagerService.this) {
1122                appDiedLocked(mApp, mPid, mAppThread);
1123            }
1124        }
1125    }
1126
1127    static final int SHOW_ERROR_MSG = 1;
1128    static final int SHOW_NOT_RESPONDING_MSG = 2;
1129    static final int SHOW_FACTORY_ERROR_MSG = 3;
1130    static final int UPDATE_CONFIGURATION_MSG = 4;
1131    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1132    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1133    static final int SERVICE_TIMEOUT_MSG = 12;
1134    static final int UPDATE_TIME_ZONE = 13;
1135    static final int SHOW_UID_ERROR_MSG = 14;
1136    static final int IM_FEELING_LUCKY_MSG = 15;
1137    static final int PROC_START_TIMEOUT_MSG = 20;
1138    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1139    static final int KILL_APPLICATION_MSG = 22;
1140    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1141    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1142    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1143    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1144    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1145    static final int CLEAR_DNS_CACHE_MSG = 28;
1146    static final int UPDATE_HTTP_PROXY_MSG = 29;
1147    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1148    static final int DISPATCH_PROCESSES_CHANGED = 31;
1149    static final int DISPATCH_PROCESS_DIED = 32;
1150    static final int REPORT_MEM_USAGE_MSG = 33;
1151    static final int REPORT_USER_SWITCH_MSG = 34;
1152    static final int CONTINUE_USER_SWITCH_MSG = 35;
1153    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1154    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1155    static final int PERSIST_URI_GRANTS_MSG = 38;
1156    static final int REQUEST_ALL_PSS_MSG = 39;
1157    static final int START_PROFILES_MSG = 40;
1158    static final int UPDATE_TIME = 41;
1159    static final int SYSTEM_USER_START_MSG = 42;
1160    static final int SYSTEM_USER_CURRENT_MSG = 43;
1161    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1162    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1163
1164    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1165    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1166    static final int FIRST_COMPAT_MODE_MSG = 300;
1167    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1168
1169    AlertDialog mUidAlert;
1170    CompatModeDialog mCompatModeDialog;
1171    long mLastMemUsageReportTime = 0;
1172
1173    private LockToAppRequestDialog mLockToAppRequest;
1174
1175    /**
1176     * Flag whether the current user is a "monkey", i.e. whether
1177     * the UI is driven by a UI automation tool.
1178     */
1179    private boolean mUserIsMonkey;
1180
1181    /** Flag whether the device has a recents UI */
1182    final boolean mHasRecents;
1183
1184    final ServiceThread mHandlerThread;
1185    final MainHandler mHandler;
1186
1187    final class MainHandler extends Handler {
1188        public MainHandler(Looper looper) {
1189            super(looper, null, true);
1190        }
1191
1192        @Override
1193        public void handleMessage(Message msg) {
1194            switch (msg.what) {
1195            case SHOW_ERROR_MSG: {
1196                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1197                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1198                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1199                synchronized (ActivityManagerService.this) {
1200                    ProcessRecord proc = (ProcessRecord)data.get("app");
1201                    AppErrorResult res = (AppErrorResult) data.get("result");
1202                    if (proc != null && proc.crashDialog != null) {
1203                        Slog.e(TAG, "App already has crash dialog: " + proc);
1204                        if (res != null) {
1205                            res.set(0);
1206                        }
1207                        return;
1208                    }
1209                    if (!showBackground && UserHandle.getAppId(proc.uid)
1210                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1211                            && proc.pid != MY_PID) {
1212                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1213                        if (res != null) {
1214                            res.set(0);
1215                        }
1216                        return;
1217                    }
1218                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1219                        Dialog d = new AppErrorDialog(mContext,
1220                                ActivityManagerService.this, res, proc);
1221                        d.show();
1222                        proc.crashDialog = d;
1223                    } else {
1224                        // The device is asleep, so just pretend that the user
1225                        // saw a crash dialog and hit "force quit".
1226                        if (res != null) {
1227                            res.set(0);
1228                        }
1229                    }
1230                }
1231
1232                ensureBootCompleted();
1233            } break;
1234            case SHOW_NOT_RESPONDING_MSG: {
1235                synchronized (ActivityManagerService.this) {
1236                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1237                    ProcessRecord proc = (ProcessRecord)data.get("app");
1238                    if (proc != null && proc.anrDialog != null) {
1239                        Slog.e(TAG, "App already has anr dialog: " + proc);
1240                        return;
1241                    }
1242
1243                    Intent intent = new Intent("android.intent.action.ANR");
1244                    if (!mProcessesReady) {
1245                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1246                                | Intent.FLAG_RECEIVER_FOREGROUND);
1247                    }
1248                    broadcastIntentLocked(null, null, intent,
1249                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1250                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1251
1252                    if (mShowDialogs) {
1253                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1254                                mContext, proc, (ActivityRecord)data.get("activity"),
1255                                msg.arg1 != 0);
1256                        d.show();
1257                        proc.anrDialog = d;
1258                    } else {
1259                        // Just kill the app if there is no dialog to be shown.
1260                        killAppAtUsersRequest(proc, null);
1261                    }
1262                }
1263
1264                ensureBootCompleted();
1265            } break;
1266            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1267                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1268                synchronized (ActivityManagerService.this) {
1269                    ProcessRecord proc = (ProcessRecord) data.get("app");
1270                    if (proc == null) {
1271                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1272                        break;
1273                    }
1274                    if (proc.crashDialog != null) {
1275                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1276                        return;
1277                    }
1278                    AppErrorResult res = (AppErrorResult) data.get("result");
1279                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1280                        Dialog d = new StrictModeViolationDialog(mContext,
1281                                ActivityManagerService.this, res, proc);
1282                        d.show();
1283                        proc.crashDialog = d;
1284                    } else {
1285                        // The device is asleep, so just pretend that the user
1286                        // saw a crash dialog and hit "force quit".
1287                        res.set(0);
1288                    }
1289                }
1290                ensureBootCompleted();
1291            } break;
1292            case SHOW_FACTORY_ERROR_MSG: {
1293                Dialog d = new FactoryErrorDialog(
1294                    mContext, msg.getData().getCharSequence("msg"));
1295                d.show();
1296                ensureBootCompleted();
1297            } break;
1298            case UPDATE_CONFIGURATION_MSG: {
1299                final ContentResolver resolver = mContext.getContentResolver();
1300                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1301            } break;
1302            case GC_BACKGROUND_PROCESSES_MSG: {
1303                synchronized (ActivityManagerService.this) {
1304                    performAppGcsIfAppropriateLocked();
1305                }
1306            } break;
1307            case WAIT_FOR_DEBUGGER_MSG: {
1308                synchronized (ActivityManagerService.this) {
1309                    ProcessRecord app = (ProcessRecord)msg.obj;
1310                    if (msg.arg1 != 0) {
1311                        if (!app.waitedForDebugger) {
1312                            Dialog d = new AppWaitingForDebuggerDialog(
1313                                    ActivityManagerService.this,
1314                                    mContext, app);
1315                            app.waitDialog = d;
1316                            app.waitedForDebugger = true;
1317                            d.show();
1318                        }
1319                    } else {
1320                        if (app.waitDialog != null) {
1321                            app.waitDialog.dismiss();
1322                            app.waitDialog = null;
1323                        }
1324                    }
1325                }
1326            } break;
1327            case SERVICE_TIMEOUT_MSG: {
1328                if (mDidDexOpt) {
1329                    mDidDexOpt = false;
1330                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1331                    nmsg.obj = msg.obj;
1332                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1333                    return;
1334                }
1335                mServices.serviceTimeout((ProcessRecord)msg.obj);
1336            } break;
1337            case UPDATE_TIME_ZONE: {
1338                synchronized (ActivityManagerService.this) {
1339                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1340                        ProcessRecord r = mLruProcesses.get(i);
1341                        if (r.thread != null) {
1342                            try {
1343                                r.thread.updateTimeZone();
1344                            } catch (RemoteException ex) {
1345                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1346                            }
1347                        }
1348                    }
1349                }
1350            } break;
1351            case CLEAR_DNS_CACHE_MSG: {
1352                synchronized (ActivityManagerService.this) {
1353                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1354                        ProcessRecord r = mLruProcesses.get(i);
1355                        if (r.thread != null) {
1356                            try {
1357                                r.thread.clearDnsCache();
1358                            } catch (RemoteException ex) {
1359                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1360                            }
1361                        }
1362                    }
1363                }
1364            } break;
1365            case UPDATE_HTTP_PROXY_MSG: {
1366                ProxyInfo proxy = (ProxyInfo)msg.obj;
1367                String host = "";
1368                String port = "";
1369                String exclList = "";
1370                Uri pacFileUrl = Uri.EMPTY;
1371                if (proxy != null) {
1372                    host = proxy.getHost();
1373                    port = Integer.toString(proxy.getPort());
1374                    exclList = proxy.getExclusionListAsString();
1375                    pacFileUrl = proxy.getPacFileUrl();
1376                }
1377                synchronized (ActivityManagerService.this) {
1378                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1379                        ProcessRecord r = mLruProcesses.get(i);
1380                        if (r.thread != null) {
1381                            try {
1382                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1383                            } catch (RemoteException ex) {
1384                                Slog.w(TAG, "Failed to update http proxy for: " +
1385                                        r.info.processName);
1386                            }
1387                        }
1388                    }
1389                }
1390            } break;
1391            case SHOW_UID_ERROR_MSG: {
1392                String title = "System UIDs Inconsistent";
1393                String text = "UIDs on the system are inconsistent, you need to wipe your"
1394                        + " data partition or your device will be unstable.";
1395                Log.e(TAG, title + ": " + text);
1396                if (mShowDialogs) {
1397                    // XXX This is a temporary dialog, no need to localize.
1398                    AlertDialog d = new BaseErrorDialog(mContext);
1399                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1400                    d.setCancelable(false);
1401                    d.setTitle(title);
1402                    d.setMessage(text);
1403                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1404                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1405                    mUidAlert = d;
1406                    d.show();
1407                }
1408            } break;
1409            case IM_FEELING_LUCKY_MSG: {
1410                if (mUidAlert != null) {
1411                    mUidAlert.dismiss();
1412                    mUidAlert = null;
1413                }
1414            } break;
1415            case PROC_START_TIMEOUT_MSG: {
1416                if (mDidDexOpt) {
1417                    mDidDexOpt = false;
1418                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1419                    nmsg.obj = msg.obj;
1420                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1421                    return;
1422                }
1423                ProcessRecord app = (ProcessRecord)msg.obj;
1424                synchronized (ActivityManagerService.this) {
1425                    processStartTimedOutLocked(app);
1426                }
1427            } break;
1428            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1429                synchronized (ActivityManagerService.this) {
1430                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1431                }
1432            } break;
1433            case KILL_APPLICATION_MSG: {
1434                synchronized (ActivityManagerService.this) {
1435                    int appid = msg.arg1;
1436                    boolean restart = (msg.arg2 == 1);
1437                    Bundle bundle = (Bundle)msg.obj;
1438                    String pkg = bundle.getString("pkg");
1439                    String reason = bundle.getString("reason");
1440                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1441                            false, UserHandle.USER_ALL, reason);
1442                }
1443            } break;
1444            case FINALIZE_PENDING_INTENT_MSG: {
1445                ((PendingIntentRecord)msg.obj).completeFinalize();
1446            } break;
1447            case POST_HEAVY_NOTIFICATION_MSG: {
1448                INotificationManager inm = NotificationManager.getService();
1449                if (inm == null) {
1450                    return;
1451                }
1452
1453                ActivityRecord root = (ActivityRecord)msg.obj;
1454                ProcessRecord process = root.app;
1455                if (process == null) {
1456                    return;
1457                }
1458
1459                try {
1460                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1461                    String text = mContext.getString(R.string.heavy_weight_notification,
1462                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1463                    Notification notification = new Notification();
1464                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1465                    notification.when = 0;
1466                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1467                    notification.tickerText = text;
1468                    notification.defaults = 0; // please be quiet
1469                    notification.sound = null;
1470                    notification.vibrate = null;
1471                    notification.setLatestEventInfo(context, text,
1472                            mContext.getText(R.string.heavy_weight_notification_detail),
1473                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1474                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1475                                    new UserHandle(root.userId)));
1476
1477                    try {
1478                        int[] outId = new int[1];
1479                        inm.enqueueNotificationWithTag("android", "android", null,
1480                                R.string.heavy_weight_notification,
1481                                notification, outId, root.userId);
1482                    } catch (RuntimeException e) {
1483                        Slog.w(ActivityManagerService.TAG,
1484                                "Error showing notification for heavy-weight app", e);
1485                    } catch (RemoteException e) {
1486                    }
1487                } catch (NameNotFoundException e) {
1488                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1489                }
1490            } break;
1491            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1492                INotificationManager inm = NotificationManager.getService();
1493                if (inm == null) {
1494                    return;
1495                }
1496                try {
1497                    inm.cancelNotificationWithTag("android", null,
1498                            R.string.heavy_weight_notification,  msg.arg1);
1499                } catch (RuntimeException e) {
1500                    Slog.w(ActivityManagerService.TAG,
1501                            "Error canceling notification for service", e);
1502                } catch (RemoteException e) {
1503                }
1504            } break;
1505            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1506                synchronized (ActivityManagerService.this) {
1507                    checkExcessivePowerUsageLocked(true);
1508                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1509                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1510                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1511                }
1512            } break;
1513            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1514                synchronized (ActivityManagerService.this) {
1515                    ActivityRecord ar = (ActivityRecord)msg.obj;
1516                    if (mCompatModeDialog != null) {
1517                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1518                                ar.info.applicationInfo.packageName)) {
1519                            return;
1520                        }
1521                        mCompatModeDialog.dismiss();
1522                        mCompatModeDialog = null;
1523                    }
1524                    if (ar != null && false) {
1525                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1526                                ar.packageName)) {
1527                            int mode = mCompatModePackages.computeCompatModeLocked(
1528                                    ar.info.applicationInfo);
1529                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1530                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1531                                mCompatModeDialog = new CompatModeDialog(
1532                                        ActivityManagerService.this, mContext,
1533                                        ar.info.applicationInfo);
1534                                mCompatModeDialog.show();
1535                            }
1536                        }
1537                    }
1538                }
1539                break;
1540            }
1541            case DISPATCH_PROCESSES_CHANGED: {
1542                dispatchProcessesChanged();
1543                break;
1544            }
1545            case DISPATCH_PROCESS_DIED: {
1546                final int pid = msg.arg1;
1547                final int uid = msg.arg2;
1548                dispatchProcessDied(pid, uid);
1549                break;
1550            }
1551            case REPORT_MEM_USAGE_MSG: {
1552                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1553                Thread thread = new Thread() {
1554                    @Override public void run() {
1555                        final SparseArray<ProcessMemInfo> infoMap
1556                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1557                        for (int i=0, N=memInfos.size(); i<N; i++) {
1558                            ProcessMemInfo mi = memInfos.get(i);
1559                            infoMap.put(mi.pid, mi);
1560                        }
1561                        updateCpuStatsNow();
1562                        synchronized (mProcessCpuThread) {
1563                            final int N = mProcessCpuTracker.countStats();
1564                            for (int i=0; i<N; i++) {
1565                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1566                                if (st.vsize > 0) {
1567                                    long pss = Debug.getPss(st.pid, null);
1568                                    if (pss > 0) {
1569                                        if (infoMap.indexOfKey(st.pid) < 0) {
1570                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1571                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1572                                            mi.pss = pss;
1573                                            memInfos.add(mi);
1574                                        }
1575                                    }
1576                                }
1577                            }
1578                        }
1579
1580                        long totalPss = 0;
1581                        for (int i=0, N=memInfos.size(); i<N; i++) {
1582                            ProcessMemInfo mi = memInfos.get(i);
1583                            if (mi.pss == 0) {
1584                                mi.pss = Debug.getPss(mi.pid, null);
1585                            }
1586                            totalPss += mi.pss;
1587                        }
1588                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1589                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1590                                if (lhs.oomAdj != rhs.oomAdj) {
1591                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1592                                }
1593                                if (lhs.pss != rhs.pss) {
1594                                    return lhs.pss < rhs.pss ? 1 : -1;
1595                                }
1596                                return 0;
1597                            }
1598                        });
1599
1600                        StringBuilder tag = new StringBuilder(128);
1601                        StringBuilder stack = new StringBuilder(128);
1602                        tag.append("Low on memory -- ");
1603                        appendMemBucket(tag, totalPss, "total", false);
1604                        appendMemBucket(stack, totalPss, "total", true);
1605
1606                        StringBuilder logBuilder = new StringBuilder(1024);
1607                        logBuilder.append("Low on memory:\n");
1608
1609                        boolean firstLine = true;
1610                        int lastOomAdj = Integer.MIN_VALUE;
1611                        for (int i=0, N=memInfos.size(); i<N; i++) {
1612                            ProcessMemInfo mi = memInfos.get(i);
1613
1614                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1615                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1616                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1617                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1618                                if (lastOomAdj != mi.oomAdj) {
1619                                    lastOomAdj = mi.oomAdj;
1620                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1621                                        tag.append(" / ");
1622                                    }
1623                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1624                                        if (firstLine) {
1625                                            stack.append(":");
1626                                            firstLine = false;
1627                                        }
1628                                        stack.append("\n\t at ");
1629                                    } else {
1630                                        stack.append("$");
1631                                    }
1632                                } else {
1633                                    tag.append(" ");
1634                                    stack.append("$");
1635                                }
1636                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1637                                    appendMemBucket(tag, mi.pss, mi.name, false);
1638                                }
1639                                appendMemBucket(stack, mi.pss, mi.name, true);
1640                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1641                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1642                                    stack.append("(");
1643                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1644                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1645                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1646                                            stack.append(":");
1647                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1648                                        }
1649                                    }
1650                                    stack.append(")");
1651                                }
1652                            }
1653
1654                            logBuilder.append("  ");
1655                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1656                            logBuilder.append(' ');
1657                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1658                            logBuilder.append(' ');
1659                            ProcessList.appendRamKb(logBuilder, mi.pss);
1660                            logBuilder.append(" kB: ");
1661                            logBuilder.append(mi.name);
1662                            logBuilder.append(" (");
1663                            logBuilder.append(mi.pid);
1664                            logBuilder.append(") ");
1665                            logBuilder.append(mi.adjType);
1666                            logBuilder.append('\n');
1667                            if (mi.adjReason != null) {
1668                                logBuilder.append("                      ");
1669                                logBuilder.append(mi.adjReason);
1670                                logBuilder.append('\n');
1671                            }
1672                        }
1673
1674                        logBuilder.append("           ");
1675                        ProcessList.appendRamKb(logBuilder, totalPss);
1676                        logBuilder.append(" kB: TOTAL\n");
1677
1678                        long[] infos = new long[Debug.MEMINFO_COUNT];
1679                        Debug.getMemInfo(infos);
1680                        logBuilder.append("  MemInfo: ");
1681                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1682                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1683                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1684                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1685                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1686                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1687                            logBuilder.append("  ZRAM: ");
1688                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1689                            logBuilder.append(" kB RAM, ");
1690                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1691                            logBuilder.append(" kB swap total, ");
1692                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1693                            logBuilder.append(" kB swap free\n");
1694                        }
1695                        Slog.i(TAG, logBuilder.toString());
1696
1697                        StringBuilder dropBuilder = new StringBuilder(1024);
1698                        /*
1699                        StringWriter oomSw = new StringWriter();
1700                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1701                        StringWriter catSw = new StringWriter();
1702                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1703                        String[] emptyArgs = new String[] { };
1704                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1705                        oomPw.flush();
1706                        String oomString = oomSw.toString();
1707                        */
1708                        dropBuilder.append(stack);
1709                        dropBuilder.append('\n');
1710                        dropBuilder.append('\n');
1711                        dropBuilder.append(logBuilder);
1712                        dropBuilder.append('\n');
1713                        /*
1714                        dropBuilder.append(oomString);
1715                        dropBuilder.append('\n');
1716                        */
1717                        StringWriter catSw = new StringWriter();
1718                        synchronized (ActivityManagerService.this) {
1719                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1720                            String[] emptyArgs = new String[] { };
1721                            catPw.println();
1722                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1723                            catPw.println();
1724                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1725                                    false, false, null);
1726                            catPw.println();
1727                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1728                            catPw.flush();
1729                        }
1730                        dropBuilder.append(catSw.toString());
1731                        addErrorToDropBox("lowmem", null, "system_server", null,
1732                                null, tag.toString(), dropBuilder.toString(), null, null);
1733                        //Slog.i(TAG, "Sent to dropbox:");
1734                        //Slog.i(TAG, dropBuilder.toString());
1735                        synchronized (ActivityManagerService.this) {
1736                            long now = SystemClock.uptimeMillis();
1737                            if (mLastMemUsageReportTime < now) {
1738                                mLastMemUsageReportTime = now;
1739                            }
1740                        }
1741                    }
1742                };
1743                thread.start();
1744                break;
1745            }
1746            case REPORT_USER_SWITCH_MSG: {
1747                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1748                break;
1749            }
1750            case CONTINUE_USER_SWITCH_MSG: {
1751                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1752                break;
1753            }
1754            case USER_SWITCH_TIMEOUT_MSG: {
1755                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1756                break;
1757            }
1758            case IMMERSIVE_MODE_LOCK_MSG: {
1759                final boolean nextState = (msg.arg1 != 0);
1760                if (mUpdateLock.isHeld() != nextState) {
1761                    if (DEBUG_IMMERSIVE) {
1762                        final ActivityRecord r = (ActivityRecord) msg.obj;
1763                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1764                    }
1765                    if (nextState) {
1766                        mUpdateLock.acquire();
1767                    } else {
1768                        mUpdateLock.release();
1769                    }
1770                }
1771                break;
1772            }
1773            case PERSIST_URI_GRANTS_MSG: {
1774                writeGrantedUriPermissions();
1775                break;
1776            }
1777            case REQUEST_ALL_PSS_MSG: {
1778                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1779                break;
1780            }
1781            case START_PROFILES_MSG: {
1782                synchronized (ActivityManagerService.this) {
1783                    startProfilesLocked();
1784                }
1785                break;
1786            }
1787            case UPDATE_TIME: {
1788                synchronized (ActivityManagerService.this) {
1789                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1790                        ProcessRecord r = mLruProcesses.get(i);
1791                        if (r.thread != null) {
1792                            try {
1793                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1794                            } catch (RemoteException ex) {
1795                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1796                            }
1797                        }
1798                    }
1799                }
1800                break;
1801            }
1802            case SYSTEM_USER_START_MSG: {
1803                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1804                        Integer.toString(msg.arg1), msg.arg1);
1805                mSystemServiceManager.startUser(msg.arg1);
1806                break;
1807            }
1808            case SYSTEM_USER_CURRENT_MSG: {
1809                mBatteryStatsService.noteEvent(
1810                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1811                        Integer.toString(msg.arg2), msg.arg2);
1812                mBatteryStatsService.noteEvent(
1813                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1814                        Integer.toString(msg.arg1), msg.arg1);
1815                mSystemServiceManager.switchUser(msg.arg1);
1816                break;
1817            }
1818            case ENTER_ANIMATION_COMPLETE_MSG: {
1819                synchronized (ActivityManagerService.this) {
1820                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1821                    if (r != null && r.app != null && r.app.thread != null) {
1822                        try {
1823                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1824                        } catch (RemoteException e) {
1825                        }
1826                    }
1827                }
1828                break;
1829            }
1830            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1831                enableScreenAfterBoot();
1832                break;
1833            }
1834            }
1835        }
1836    };
1837
1838    static final int COLLECT_PSS_BG_MSG = 1;
1839
1840    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1841        @Override
1842        public void handleMessage(Message msg) {
1843            switch (msg.what) {
1844            case COLLECT_PSS_BG_MSG: {
1845                long start = SystemClock.uptimeMillis();
1846                MemInfoReader memInfo = null;
1847                synchronized (ActivityManagerService.this) {
1848                    if (mFullPssPending) {
1849                        mFullPssPending = false;
1850                        memInfo = new MemInfoReader();
1851                    }
1852                }
1853                if (memInfo != null) {
1854                    updateCpuStatsNow();
1855                    long nativeTotalPss = 0;
1856                    synchronized (mProcessCpuThread) {
1857                        final int N = mProcessCpuTracker.countStats();
1858                        for (int j=0; j<N; j++) {
1859                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1860                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1861                                // This is definitely an application process; skip it.
1862                                continue;
1863                            }
1864                            synchronized (mPidsSelfLocked) {
1865                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1866                                    // This is one of our own processes; skip it.
1867                                    continue;
1868                                }
1869                            }
1870                            nativeTotalPss += Debug.getPss(st.pid, null);
1871                        }
1872                    }
1873                    memInfo.readMemInfo();
1874                    synchronized (this) {
1875                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1876                                + (SystemClock.uptimeMillis()-start) + "ms");
1877                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1878                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1879                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1880                                        +memInfo.getSlabSizeKb(),
1881                                nativeTotalPss);
1882                    }
1883                }
1884
1885                int i=0, num=0;
1886                long[] tmp = new long[1];
1887                do {
1888                    ProcessRecord proc;
1889                    int procState;
1890                    int pid;
1891                    synchronized (ActivityManagerService.this) {
1892                        if (i >= mPendingPssProcesses.size()) {
1893                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1894                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1895                            mPendingPssProcesses.clear();
1896                            return;
1897                        }
1898                        proc = mPendingPssProcesses.get(i);
1899                        procState = proc.pssProcState;
1900                        if (proc.thread != null && procState == proc.setProcState) {
1901                            pid = proc.pid;
1902                        } else {
1903                            proc = null;
1904                            pid = 0;
1905                        }
1906                        i++;
1907                    }
1908                    if (proc != null) {
1909                        long pss = Debug.getPss(pid, tmp);
1910                        synchronized (ActivityManagerService.this) {
1911                            if (proc.thread != null && proc.setProcState == procState
1912                                    && proc.pid == pid) {
1913                                num++;
1914                                proc.lastPssTime = SystemClock.uptimeMillis();
1915                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1916                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1917                                        + ": " + pss + " lastPss=" + proc.lastPss
1918                                        + " state=" + ProcessList.makeProcStateString(procState));
1919                                if (proc.initialIdlePss == 0) {
1920                                    proc.initialIdlePss = pss;
1921                                }
1922                                proc.lastPss = pss;
1923                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1924                                    proc.lastCachedPss = pss;
1925                                }
1926                            }
1927                        }
1928                    }
1929                } while (true);
1930            }
1931            }
1932        }
1933    };
1934
1935    /**
1936     * Monitor for package changes and update our internal state.
1937     */
1938    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1939        @Override
1940        public void onPackageRemoved(String packageName, int uid) {
1941            // Remove all tasks with activities in the specified package from the list of recent tasks
1942            synchronized (ActivityManagerService.this) {
1943                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1944                    TaskRecord tr = mRecentTasks.get(i);
1945                    ComponentName cn = tr.intent.getComponent();
1946                    if (cn != null && cn.getPackageName().equals(packageName)) {
1947                        // If the package name matches, remove the task and kill the process
1948                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1949                    }
1950                }
1951            }
1952        }
1953
1954        @Override
1955        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1956            onPackageModified(packageName);
1957            return true;
1958        }
1959
1960        @Override
1961        public void onPackageModified(String packageName) {
1962            final PackageManager pm = mContext.getPackageManager();
1963            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1964                    new ArrayList<Pair<Intent, Integer>>();
1965            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1966            // Copy the list of recent tasks so that we don't hold onto the lock on
1967            // ActivityManagerService for long periods while checking if components exist.
1968            synchronized (ActivityManagerService.this) {
1969                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1970                    TaskRecord tr = mRecentTasks.get(i);
1971                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1972                }
1973            }
1974            // Check the recent tasks and filter out all tasks with components that no longer exist.
1975            Intent tmpI = new Intent();
1976            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1977                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1978                ComponentName cn = p.first.getComponent();
1979                if (cn != null && cn.getPackageName().equals(packageName)) {
1980                    try {
1981                        // Add the task to the list to remove if the component no longer exists
1982                        tmpI.setComponent(cn);
1983                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1984                            tasksToRemove.add(p.second);
1985                        }
1986                    } catch (Exception e) {}
1987                }
1988            }
1989            // Prune all the tasks with removed components from the list of recent tasks
1990            synchronized (ActivityManagerService.this) {
1991                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1992                    // Remove the task but don't kill the process (since other components in that
1993                    // package may still be running and in the background)
1994                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1995                }
1996            }
1997        }
1998
1999        @Override
2000        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2001            // Force stop the specified packages
2002            if (packages != null) {
2003                for (String pkg : packages) {
2004                    synchronized (ActivityManagerService.this) {
2005                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2006                                "finished booting")) {
2007                            return true;
2008                        }
2009                    }
2010                }
2011            }
2012            return false;
2013        }
2014    };
2015
2016    public void setSystemProcess() {
2017        try {
2018            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2019            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2020            ServiceManager.addService("meminfo", new MemBinder(this));
2021            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2022            ServiceManager.addService("dbinfo", new DbBinder(this));
2023            if (MONITOR_CPU_USAGE) {
2024                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2025            }
2026            ServiceManager.addService("permission", new PermissionController(this));
2027
2028            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2029                    "android", STOCK_PM_FLAGS);
2030            mSystemThread.installSystemApplicationInfo(info);
2031
2032            synchronized (this) {
2033                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2034                app.persistent = true;
2035                app.pid = MY_PID;
2036                app.maxAdj = ProcessList.SYSTEM_ADJ;
2037                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2038                mProcessNames.put(app.processName, app.uid, app);
2039                synchronized (mPidsSelfLocked) {
2040                    mPidsSelfLocked.put(app.pid, app);
2041                }
2042                updateLruProcessLocked(app, false, null);
2043                updateOomAdjLocked();
2044            }
2045        } catch (PackageManager.NameNotFoundException e) {
2046            throw new RuntimeException(
2047                    "Unable to find android system package", e);
2048        }
2049    }
2050
2051    public void setWindowManager(WindowManagerService wm) {
2052        mWindowManager = wm;
2053        mStackSupervisor.setWindowManager(wm);
2054    }
2055
2056    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2057        mUsageStatsService = usageStatsManager;
2058    }
2059
2060    public void startObservingNativeCrashes() {
2061        final NativeCrashListener ncl = new NativeCrashListener(this);
2062        ncl.start();
2063    }
2064
2065    public IAppOpsService getAppOpsService() {
2066        return mAppOpsService;
2067    }
2068
2069    static class MemBinder extends Binder {
2070        ActivityManagerService mActivityManagerService;
2071        MemBinder(ActivityManagerService activityManagerService) {
2072            mActivityManagerService = activityManagerService;
2073        }
2074
2075        @Override
2076        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2077            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2078                    != PackageManager.PERMISSION_GRANTED) {
2079                pw.println("Permission Denial: can't dump meminfo from from pid="
2080                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2081                        + " without permission " + android.Manifest.permission.DUMP);
2082                return;
2083            }
2084
2085            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2086        }
2087    }
2088
2089    static class GraphicsBinder extends Binder {
2090        ActivityManagerService mActivityManagerService;
2091        GraphicsBinder(ActivityManagerService activityManagerService) {
2092            mActivityManagerService = activityManagerService;
2093        }
2094
2095        @Override
2096        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2097            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2098                    != PackageManager.PERMISSION_GRANTED) {
2099                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2100                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2101                        + " without permission " + android.Manifest.permission.DUMP);
2102                return;
2103            }
2104
2105            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2106        }
2107    }
2108
2109    static class DbBinder extends Binder {
2110        ActivityManagerService mActivityManagerService;
2111        DbBinder(ActivityManagerService activityManagerService) {
2112            mActivityManagerService = activityManagerService;
2113        }
2114
2115        @Override
2116        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2117            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2118                    != PackageManager.PERMISSION_GRANTED) {
2119                pw.println("Permission Denial: can't dump dbinfo from from pid="
2120                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2121                        + " without permission " + android.Manifest.permission.DUMP);
2122                return;
2123            }
2124
2125            mActivityManagerService.dumpDbInfo(fd, pw, args);
2126        }
2127    }
2128
2129    static class CpuBinder extends Binder {
2130        ActivityManagerService mActivityManagerService;
2131        CpuBinder(ActivityManagerService activityManagerService) {
2132            mActivityManagerService = activityManagerService;
2133        }
2134
2135        @Override
2136        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2137            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2138                    != PackageManager.PERMISSION_GRANTED) {
2139                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2140                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2141                        + " without permission " + android.Manifest.permission.DUMP);
2142                return;
2143            }
2144
2145            synchronized (mActivityManagerService.mProcessCpuThread) {
2146                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2147                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2148                        SystemClock.uptimeMillis()));
2149            }
2150        }
2151    }
2152
2153    public static final class Lifecycle extends SystemService {
2154        private final ActivityManagerService mService;
2155
2156        public Lifecycle(Context context) {
2157            super(context);
2158            mService = new ActivityManagerService(context);
2159        }
2160
2161        @Override
2162        public void onStart() {
2163            mService.start();
2164        }
2165
2166        public ActivityManagerService getService() {
2167            return mService;
2168        }
2169    }
2170
2171    // Note: This method is invoked on the main thread but may need to attach various
2172    // handlers to other threads.  So take care to be explicit about the looper.
2173    public ActivityManagerService(Context systemContext) {
2174        mContext = systemContext;
2175        mFactoryTest = FactoryTest.getMode();
2176        mSystemThread = ActivityThread.currentActivityThread();
2177
2178        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2179
2180        mHandlerThread = new ServiceThread(TAG,
2181                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2182        mHandlerThread.start();
2183        mHandler = new MainHandler(mHandlerThread.getLooper());
2184
2185        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2186                "foreground", BROADCAST_FG_TIMEOUT, false);
2187        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2188                "background", BROADCAST_BG_TIMEOUT, true);
2189        mBroadcastQueues[0] = mFgBroadcastQueue;
2190        mBroadcastQueues[1] = mBgBroadcastQueue;
2191
2192        mServices = new ActiveServices(this);
2193        mProviderMap = new ProviderMap(this);
2194
2195        // TODO: Move creation of battery stats service outside of activity manager service.
2196        File dataDir = Environment.getDataDirectory();
2197        File systemDir = new File(dataDir, "system");
2198        systemDir.mkdirs();
2199        mBatteryStatsService = new BatteryStatsService(new File(
2200                systemDir, "batterystats.bin").toString(), mHandler);
2201        mBatteryStatsService.getActiveStatistics().readLocked();
2202        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2203        mOnBattery = DEBUG_POWER ? true
2204                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2205        mBatteryStatsService.getActiveStatistics().setCallback(this);
2206
2207        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2208
2209        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2210
2211        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2212
2213        // User 0 is the first and only user that runs at boot.
2214        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2215        mUserLru.add(Integer.valueOf(0));
2216        updateStartedUserArrayLocked();
2217
2218        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2219            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2220
2221        mConfiguration.setToDefaults();
2222        mConfiguration.setLocale(Locale.getDefault());
2223
2224        mConfigurationSeq = mConfiguration.seq = 1;
2225        mProcessCpuTracker.init();
2226
2227        mHasRecents = mContext.getResources().getBoolean(
2228                com.android.internal.R.bool.config_hasRecents);
2229
2230        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2231        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2232        mStackSupervisor = new ActivityStackSupervisor(this);
2233        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2234
2235        mProcessCpuThread = new Thread("CpuTracker") {
2236            @Override
2237            public void run() {
2238                while (true) {
2239                    try {
2240                        try {
2241                            synchronized(this) {
2242                                final long now = SystemClock.uptimeMillis();
2243                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2244                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2245                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2246                                //        + ", write delay=" + nextWriteDelay);
2247                                if (nextWriteDelay < nextCpuDelay) {
2248                                    nextCpuDelay = nextWriteDelay;
2249                                }
2250                                if (nextCpuDelay > 0) {
2251                                    mProcessCpuMutexFree.set(true);
2252                                    this.wait(nextCpuDelay);
2253                                }
2254                            }
2255                        } catch (InterruptedException e) {
2256                        }
2257                        updateCpuStatsNow();
2258                    } catch (Exception e) {
2259                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2260                    }
2261                }
2262            }
2263        };
2264
2265        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2266
2267        Watchdog.getInstance().addMonitor(this);
2268        Watchdog.getInstance().addThread(mHandler);
2269    }
2270
2271    public void setSystemServiceManager(SystemServiceManager mgr) {
2272        mSystemServiceManager = mgr;
2273    }
2274
2275    private void start() {
2276        Process.removeAllProcessGroups();
2277        mProcessCpuThread.start();
2278
2279        mBatteryStatsService.publish(mContext);
2280        mAppOpsService.publish(mContext);
2281        Slog.d("AppOps", "AppOpsService published");
2282        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2283    }
2284
2285    public void initPowerManagement() {
2286        mStackSupervisor.initPowerManagement();
2287        mBatteryStatsService.initPowerManagement();
2288    }
2289
2290    @Override
2291    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2292            throws RemoteException {
2293        if (code == SYSPROPS_TRANSACTION) {
2294            // We need to tell all apps about the system property change.
2295            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2296            synchronized(this) {
2297                final int NP = mProcessNames.getMap().size();
2298                for (int ip=0; ip<NP; ip++) {
2299                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2300                    final int NA = apps.size();
2301                    for (int ia=0; ia<NA; ia++) {
2302                        ProcessRecord app = apps.valueAt(ia);
2303                        if (app.thread != null) {
2304                            procs.add(app.thread.asBinder());
2305                        }
2306                    }
2307                }
2308            }
2309
2310            int N = procs.size();
2311            for (int i=0; i<N; i++) {
2312                Parcel data2 = Parcel.obtain();
2313                try {
2314                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2315                } catch (RemoteException e) {
2316                }
2317                data2.recycle();
2318            }
2319        }
2320        try {
2321            return super.onTransact(code, data, reply, flags);
2322        } catch (RuntimeException e) {
2323            // The activity manager only throws security exceptions, so let's
2324            // log all others.
2325            if (!(e instanceof SecurityException)) {
2326                Slog.wtf(TAG, "Activity Manager Crash", e);
2327            }
2328            throw e;
2329        }
2330    }
2331
2332    void updateCpuStats() {
2333        final long now = SystemClock.uptimeMillis();
2334        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2335            return;
2336        }
2337        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2338            synchronized (mProcessCpuThread) {
2339                mProcessCpuThread.notify();
2340            }
2341        }
2342    }
2343
2344    void updateCpuStatsNow() {
2345        synchronized (mProcessCpuThread) {
2346            mProcessCpuMutexFree.set(false);
2347            final long now = SystemClock.uptimeMillis();
2348            boolean haveNewCpuStats = false;
2349
2350            if (MONITOR_CPU_USAGE &&
2351                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2352                mLastCpuTime.set(now);
2353                haveNewCpuStats = true;
2354                mProcessCpuTracker.update();
2355                //Slog.i(TAG, mProcessCpu.printCurrentState());
2356                //Slog.i(TAG, "Total CPU usage: "
2357                //        + mProcessCpu.getTotalCpuPercent() + "%");
2358
2359                // Slog the cpu usage if the property is set.
2360                if ("true".equals(SystemProperties.get("events.cpu"))) {
2361                    int user = mProcessCpuTracker.getLastUserTime();
2362                    int system = mProcessCpuTracker.getLastSystemTime();
2363                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2364                    int irq = mProcessCpuTracker.getLastIrqTime();
2365                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2366                    int idle = mProcessCpuTracker.getLastIdleTime();
2367
2368                    int total = user + system + iowait + irq + softIrq + idle;
2369                    if (total == 0) total = 1;
2370
2371                    EventLog.writeEvent(EventLogTags.CPU,
2372                            ((user+system+iowait+irq+softIrq) * 100) / total,
2373                            (user * 100) / total,
2374                            (system * 100) / total,
2375                            (iowait * 100) / total,
2376                            (irq * 100) / total,
2377                            (softIrq * 100) / total);
2378                }
2379            }
2380
2381            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2382            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2383            synchronized(bstats) {
2384                synchronized(mPidsSelfLocked) {
2385                    if (haveNewCpuStats) {
2386                        if (mOnBattery) {
2387                            int perc = bstats.startAddingCpuLocked();
2388                            int totalUTime = 0;
2389                            int totalSTime = 0;
2390                            final int N = mProcessCpuTracker.countStats();
2391                            for (int i=0; i<N; i++) {
2392                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2393                                if (!st.working) {
2394                                    continue;
2395                                }
2396                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2397                                int otherUTime = (st.rel_utime*perc)/100;
2398                                int otherSTime = (st.rel_stime*perc)/100;
2399                                totalUTime += otherUTime;
2400                                totalSTime += otherSTime;
2401                                if (pr != null) {
2402                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2403                                    if (ps == null || !ps.isActive()) {
2404                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2405                                                pr.info.uid, pr.processName);
2406                                    }
2407                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2408                                            st.rel_stime-otherSTime);
2409                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2410                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2411                                } else {
2412                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2413                                    if (ps == null || !ps.isActive()) {
2414                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2415                                                bstats.mapUid(st.uid), st.name);
2416                                    }
2417                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2418                                            st.rel_stime-otherSTime);
2419                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2420                                }
2421                            }
2422                            bstats.finishAddingCpuLocked(perc, totalUTime,
2423                                    totalSTime, cpuSpeedTimes);
2424                        }
2425                    }
2426                }
2427
2428                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2429                    mLastWriteTime = now;
2430                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2431                }
2432            }
2433        }
2434    }
2435
2436    @Override
2437    public void batteryNeedsCpuUpdate() {
2438        updateCpuStatsNow();
2439    }
2440
2441    @Override
2442    public void batteryPowerChanged(boolean onBattery) {
2443        // When plugging in, update the CPU stats first before changing
2444        // the plug state.
2445        updateCpuStatsNow();
2446        synchronized (this) {
2447            synchronized(mPidsSelfLocked) {
2448                mOnBattery = DEBUG_POWER ? true : onBattery;
2449            }
2450        }
2451    }
2452
2453    /**
2454     * Initialize the application bind args. These are passed to each
2455     * process when the bindApplication() IPC is sent to the process. They're
2456     * lazily setup to make sure the services are running when they're asked for.
2457     */
2458    private HashMap<String, IBinder> getCommonServicesLocked() {
2459        if (mAppBindArgs == null) {
2460            mAppBindArgs = new HashMap<String, IBinder>();
2461
2462            // Setup the application init args
2463            mAppBindArgs.put("package", ServiceManager.getService("package"));
2464            mAppBindArgs.put("window", ServiceManager.getService("window"));
2465            mAppBindArgs.put(Context.ALARM_SERVICE,
2466                    ServiceManager.getService(Context.ALARM_SERVICE));
2467        }
2468        return mAppBindArgs;
2469    }
2470
2471    final void setFocusedActivityLocked(ActivityRecord r) {
2472        if (mFocusedActivity != r) {
2473            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2474            mFocusedActivity = r;
2475            if (r.task != null && r.task.voiceInteractor != null) {
2476                startRunningVoiceLocked();
2477            } else {
2478                finishRunningVoiceLocked();
2479            }
2480            mStackSupervisor.setFocusedStack(r);
2481            if (r != null) {
2482                mWindowManager.setFocusedApp(r.appToken, true);
2483            }
2484            applyUpdateLockStateLocked(r);
2485        }
2486    }
2487
2488    final void clearFocusedActivity(ActivityRecord r) {
2489        if (mFocusedActivity == r) {
2490            mFocusedActivity = null;
2491        }
2492    }
2493
2494    @Override
2495    public void setFocusedStack(int stackId) {
2496        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2497        synchronized (ActivityManagerService.this) {
2498            ActivityStack stack = mStackSupervisor.getStack(stackId);
2499            if (stack != null) {
2500                ActivityRecord r = stack.topRunningActivityLocked(null);
2501                if (r != null) {
2502                    setFocusedActivityLocked(r);
2503                }
2504            }
2505        }
2506    }
2507
2508    @Override
2509    public void notifyActivityDrawn(IBinder token) {
2510        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2511        synchronized (this) {
2512            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2513            if (r != null) {
2514                r.task.stack.notifyActivityDrawnLocked(r);
2515            }
2516        }
2517    }
2518
2519    final void applyUpdateLockStateLocked(ActivityRecord r) {
2520        // Modifications to the UpdateLock state are done on our handler, outside
2521        // the activity manager's locks.  The new state is determined based on the
2522        // state *now* of the relevant activity record.  The object is passed to
2523        // the handler solely for logging detail, not to be consulted/modified.
2524        final boolean nextState = r != null && r.immersive;
2525        mHandler.sendMessage(
2526                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2527    }
2528
2529    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2530        Message msg = Message.obtain();
2531        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2532        msg.obj = r.task.askedCompatMode ? null : r;
2533        mHandler.sendMessage(msg);
2534    }
2535
2536    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2537            String what, Object obj, ProcessRecord srcApp) {
2538        app.lastActivityTime = now;
2539
2540        if (app.activities.size() > 0) {
2541            // Don't want to touch dependent processes that are hosting activities.
2542            return index;
2543        }
2544
2545        int lrui = mLruProcesses.lastIndexOf(app);
2546        if (lrui < 0) {
2547            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2548                    + what + " " + obj + " from " + srcApp);
2549            return index;
2550        }
2551
2552        if (lrui >= index) {
2553            // Don't want to cause this to move dependent processes *back* in the
2554            // list as if they were less frequently used.
2555            return index;
2556        }
2557
2558        if (lrui >= mLruProcessActivityStart) {
2559            // Don't want to touch dependent processes that are hosting activities.
2560            return index;
2561        }
2562
2563        mLruProcesses.remove(lrui);
2564        if (index > 0) {
2565            index--;
2566        }
2567        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2568                + " in LRU list: " + app);
2569        mLruProcesses.add(index, app);
2570        return index;
2571    }
2572
2573    final void removeLruProcessLocked(ProcessRecord app) {
2574        int lrui = mLruProcesses.lastIndexOf(app);
2575        if (lrui >= 0) {
2576            if (lrui <= mLruProcessActivityStart) {
2577                mLruProcessActivityStart--;
2578            }
2579            if (lrui <= mLruProcessServiceStart) {
2580                mLruProcessServiceStart--;
2581            }
2582            mLruProcesses.remove(lrui);
2583        }
2584    }
2585
2586    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2587            ProcessRecord client) {
2588        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2589                || app.treatLikeActivity;
2590        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2591        if (!activityChange && hasActivity) {
2592            // The process has activities, so we are only allowing activity-based adjustments
2593            // to move it.  It should be kept in the front of the list with other
2594            // processes that have activities, and we don't want those to change their
2595            // order except due to activity operations.
2596            return;
2597        }
2598
2599        mLruSeq++;
2600        final long now = SystemClock.uptimeMillis();
2601        app.lastActivityTime = now;
2602
2603        // First a quick reject: if the app is already at the position we will
2604        // put it, then there is nothing to do.
2605        if (hasActivity) {
2606            final int N = mLruProcesses.size();
2607            if (N > 0 && mLruProcesses.get(N-1) == app) {
2608                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2609                return;
2610            }
2611        } else {
2612            if (mLruProcessServiceStart > 0
2613                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2614                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2615                return;
2616            }
2617        }
2618
2619        int lrui = mLruProcesses.lastIndexOf(app);
2620
2621        if (app.persistent && lrui >= 0) {
2622            // We don't care about the position of persistent processes, as long as
2623            // they are in the list.
2624            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2625            return;
2626        }
2627
2628        /* In progress: compute new position first, so we can avoid doing work
2629           if the process is not actually going to move.  Not yet working.
2630        int addIndex;
2631        int nextIndex;
2632        boolean inActivity = false, inService = false;
2633        if (hasActivity) {
2634            // Process has activities, put it at the very tipsy-top.
2635            addIndex = mLruProcesses.size();
2636            nextIndex = mLruProcessServiceStart;
2637            inActivity = true;
2638        } else if (hasService) {
2639            // Process has services, put it at the top of the service list.
2640            addIndex = mLruProcessActivityStart;
2641            nextIndex = mLruProcessServiceStart;
2642            inActivity = true;
2643            inService = true;
2644        } else  {
2645            // Process not otherwise of interest, it goes to the top of the non-service area.
2646            addIndex = mLruProcessServiceStart;
2647            if (client != null) {
2648                int clientIndex = mLruProcesses.lastIndexOf(client);
2649                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2650                        + app);
2651                if (clientIndex >= 0 && addIndex > clientIndex) {
2652                    addIndex = clientIndex;
2653                }
2654            }
2655            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2656        }
2657
2658        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2659                + mLruProcessActivityStart + "): " + app);
2660        */
2661
2662        if (lrui >= 0) {
2663            if (lrui < mLruProcessActivityStart) {
2664                mLruProcessActivityStart--;
2665            }
2666            if (lrui < mLruProcessServiceStart) {
2667                mLruProcessServiceStart--;
2668            }
2669            /*
2670            if (addIndex > lrui) {
2671                addIndex--;
2672            }
2673            if (nextIndex > lrui) {
2674                nextIndex--;
2675            }
2676            */
2677            mLruProcesses.remove(lrui);
2678        }
2679
2680        /*
2681        mLruProcesses.add(addIndex, app);
2682        if (inActivity) {
2683            mLruProcessActivityStart++;
2684        }
2685        if (inService) {
2686            mLruProcessActivityStart++;
2687        }
2688        */
2689
2690        int nextIndex;
2691        if (hasActivity) {
2692            final int N = mLruProcesses.size();
2693            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2694                // Process doesn't have activities, but has clients with
2695                // activities...  move it up, but one below the top (the top
2696                // should always have a real activity).
2697                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2698                mLruProcesses.add(N-1, app);
2699                // To keep it from spamming the LRU list (by making a bunch of clients),
2700                // we will push down any other entries owned by the app.
2701                final int uid = app.info.uid;
2702                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2703                    ProcessRecord subProc = mLruProcesses.get(i);
2704                    if (subProc.info.uid == uid) {
2705                        // We want to push this one down the list.  If the process after
2706                        // it is for the same uid, however, don't do so, because we don't
2707                        // want them internally to be re-ordered.
2708                        if (mLruProcesses.get(i-1).info.uid != uid) {
2709                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2710                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2711                            ProcessRecord tmp = mLruProcesses.get(i);
2712                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2713                            mLruProcesses.set(i-1, tmp);
2714                            i--;
2715                        }
2716                    } else {
2717                        // A gap, we can stop here.
2718                        break;
2719                    }
2720                }
2721            } else {
2722                // Process has activities, put it at the very tipsy-top.
2723                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2724                mLruProcesses.add(app);
2725            }
2726            nextIndex = mLruProcessServiceStart;
2727        } else if (hasService) {
2728            // Process has services, put it at the top of the service list.
2729            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2730            mLruProcesses.add(mLruProcessActivityStart, app);
2731            nextIndex = mLruProcessServiceStart;
2732            mLruProcessActivityStart++;
2733        } else  {
2734            // Process not otherwise of interest, it goes to the top of the non-service area.
2735            int index = mLruProcessServiceStart;
2736            if (client != null) {
2737                // If there is a client, don't allow the process to be moved up higher
2738                // in the list than that client.
2739                int clientIndex = mLruProcesses.lastIndexOf(client);
2740                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2741                        + " when updating " + app);
2742                if (clientIndex <= lrui) {
2743                    // Don't allow the client index restriction to push it down farther in the
2744                    // list than it already is.
2745                    clientIndex = lrui;
2746                }
2747                if (clientIndex >= 0 && index > clientIndex) {
2748                    index = clientIndex;
2749                }
2750            }
2751            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2752            mLruProcesses.add(index, app);
2753            nextIndex = index-1;
2754            mLruProcessActivityStart++;
2755            mLruProcessServiceStart++;
2756        }
2757
2758        // If the app is currently using a content provider or service,
2759        // bump those processes as well.
2760        for (int j=app.connections.size()-1; j>=0; j--) {
2761            ConnectionRecord cr = app.connections.valueAt(j);
2762            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2763                    && cr.binding.service.app != null
2764                    && cr.binding.service.app.lruSeq != mLruSeq
2765                    && !cr.binding.service.app.persistent) {
2766                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2767                        "service connection", cr, app);
2768            }
2769        }
2770        for (int j=app.conProviders.size()-1; j>=0; j--) {
2771            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2772            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2773                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2774                        "provider reference", cpr, app);
2775            }
2776        }
2777    }
2778
2779    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2780        if (uid == Process.SYSTEM_UID) {
2781            // The system gets to run in any process.  If there are multiple
2782            // processes with the same uid, just pick the first (this
2783            // should never happen).
2784            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2785            if (procs == null) return null;
2786            final int N = procs.size();
2787            for (int i = 0; i < N; i++) {
2788                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2789            }
2790        }
2791        ProcessRecord proc = mProcessNames.get(processName, uid);
2792        if (false && proc != null && !keepIfLarge
2793                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2794                && proc.lastCachedPss >= 4000) {
2795            // Turn this condition on to cause killing to happen regularly, for testing.
2796            if (proc.baseProcessTracker != null) {
2797                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2798            }
2799            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2800                    + "k from cached");
2801        } else if (proc != null && !keepIfLarge
2802                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2803                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2804            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2805            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2806                if (proc.baseProcessTracker != null) {
2807                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2808                }
2809                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2810                        + "k from cached");
2811            }
2812        }
2813        return proc;
2814    }
2815
2816    void ensurePackageDexOpt(String packageName) {
2817        IPackageManager pm = AppGlobals.getPackageManager();
2818        try {
2819            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2820                mDidDexOpt = true;
2821            }
2822        } catch (RemoteException e) {
2823        }
2824    }
2825
2826    boolean isNextTransitionForward() {
2827        int transit = mWindowManager.getPendingAppTransition();
2828        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2829                || transit == AppTransition.TRANSIT_TASK_OPEN
2830                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2831    }
2832
2833    final ProcessRecord startProcessLocked(String processName,
2834            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2835            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2836            boolean isolated, boolean keepIfLarge) {
2837        ProcessRecord app;
2838        if (!isolated) {
2839            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2840        } else {
2841            // If this is an isolated process, it can't re-use an existing process.
2842            app = null;
2843        }
2844        // We don't have to do anything more if:
2845        // (1) There is an existing application record; and
2846        // (2) The caller doesn't think it is dead, OR there is no thread
2847        //     object attached to it so we know it couldn't have crashed; and
2848        // (3) There is a pid assigned to it, so it is either starting or
2849        //     already running.
2850        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2851                + " app=" + app + " knownToBeDead=" + knownToBeDead
2852                + " thread=" + (app != null ? app.thread : null)
2853                + " pid=" + (app != null ? app.pid : -1));
2854        if (app != null && app.pid > 0) {
2855            if (!knownToBeDead || app.thread == null) {
2856                // We already have the app running, or are waiting for it to
2857                // come up (we have a pid but not yet its thread), so keep it.
2858                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2859                // If this is a new package in the process, add the package to the list
2860                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2861                return app;
2862            }
2863
2864            // An application record is attached to a previous process,
2865            // clean it up now.
2866            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2867            Process.killProcessGroup(app.info.uid, app.pid);
2868            handleAppDiedLocked(app, true, true);
2869        }
2870
2871        String hostingNameStr = hostingName != null
2872                ? hostingName.flattenToShortString() : null;
2873
2874        if (!isolated) {
2875            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2876                // If we are in the background, then check to see if this process
2877                // is bad.  If so, we will just silently fail.
2878                if (mBadProcesses.get(info.processName, info.uid) != null) {
2879                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2880                            + "/" + info.processName);
2881                    return null;
2882                }
2883            } else {
2884                // When the user is explicitly starting a process, then clear its
2885                // crash count so that we won't make it bad until they see at
2886                // least one crash dialog again, and make the process good again
2887                // if it had been bad.
2888                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2889                        + "/" + info.processName);
2890                mProcessCrashTimes.remove(info.processName, info.uid);
2891                if (mBadProcesses.get(info.processName, info.uid) != null) {
2892                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2893                            UserHandle.getUserId(info.uid), info.uid,
2894                            info.processName);
2895                    mBadProcesses.remove(info.processName, info.uid);
2896                    if (app != null) {
2897                        app.bad = false;
2898                    }
2899                }
2900            }
2901        }
2902
2903        if (app == null) {
2904            app = newProcessRecordLocked(info, processName, isolated);
2905            if (app == null) {
2906                Slog.w(TAG, "Failed making new process record for "
2907                        + processName + "/" + info.uid + " isolated=" + isolated);
2908                return null;
2909            }
2910            mProcessNames.put(processName, app.uid, app);
2911            if (isolated) {
2912                mIsolatedProcesses.put(app.uid, app);
2913            }
2914        } else {
2915            // If this is a new package in the process, add the package to the list
2916            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2917        }
2918
2919        // If the system is not ready yet, then hold off on starting this
2920        // process until it is.
2921        if (!mProcessesReady
2922                && !isAllowedWhileBooting(info)
2923                && !allowWhileBooting) {
2924            if (!mProcessesOnHold.contains(app)) {
2925                mProcessesOnHold.add(app);
2926            }
2927            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2928            return app;
2929        }
2930
2931        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2932        return (app.pid != 0) ? app : null;
2933    }
2934
2935    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2936        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2937    }
2938
2939    private final void startProcessLocked(ProcessRecord app,
2940            String hostingType, String hostingNameStr, String abiOverride) {
2941        if (app.pid > 0 && app.pid != MY_PID) {
2942            synchronized (mPidsSelfLocked) {
2943                mPidsSelfLocked.remove(app.pid);
2944                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2945            }
2946            app.setPid(0);
2947        }
2948
2949        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2950                "startProcessLocked removing on hold: " + app);
2951        mProcessesOnHold.remove(app);
2952
2953        updateCpuStats();
2954
2955        try {
2956            int uid = app.uid;
2957
2958            int[] gids = null;
2959            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2960            if (!app.isolated) {
2961                int[] permGids = null;
2962                try {
2963                    final PackageManager pm = mContext.getPackageManager();
2964                    permGids = pm.getPackageGids(app.info.packageName);
2965
2966                    if (Environment.isExternalStorageEmulated()) {
2967                        if (pm.checkPermission(
2968                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2969                                app.info.packageName) == PERMISSION_GRANTED) {
2970                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2971                        } else {
2972                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2973                        }
2974                    }
2975                } catch (PackageManager.NameNotFoundException e) {
2976                    Slog.w(TAG, "Unable to retrieve gids", e);
2977                }
2978
2979                /*
2980                 * Add shared application and profile GIDs so applications can share some
2981                 * resources like shared libraries and access user-wide resources
2982                 */
2983                if (permGids == null) {
2984                    gids = new int[2];
2985                } else {
2986                    gids = new int[permGids.length + 2];
2987                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2988                }
2989                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2990                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2991            }
2992            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2993                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2994                        && mTopComponent != null
2995                        && app.processName.equals(mTopComponent.getPackageName())) {
2996                    uid = 0;
2997                }
2998                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2999                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3000                    uid = 0;
3001                }
3002            }
3003            int debugFlags = 0;
3004            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3005                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3006                // Also turn on CheckJNI for debuggable apps. It's quite
3007                // awkward to turn on otherwise.
3008                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3009            }
3010            // Run the app in safe mode if its manifest requests so or the
3011            // system is booted in safe mode.
3012            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3013                mSafeMode == true) {
3014                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3015            }
3016            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3017                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3018            }
3019            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3020                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3021            }
3022            if ("1".equals(SystemProperties.get("debug.assert"))) {
3023                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3024            }
3025
3026            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3027            if (requiredAbi == null) {
3028                requiredAbi = Build.SUPPORTED_ABIS[0];
3029            }
3030
3031            // Start the process.  It will either succeed and return a result containing
3032            // the PID of the new process, or else throw a RuntimeException.
3033            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
3034                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3035                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
3036
3037            if (app.isolated) {
3038                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3039            }
3040            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3041
3042            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3043                    UserHandle.getUserId(uid), startResult.pid, uid,
3044                    app.processName, hostingType,
3045                    hostingNameStr != null ? hostingNameStr : "");
3046
3047            if (app.persistent) {
3048                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3049            }
3050
3051            StringBuilder buf = mStringBuilder;
3052            buf.setLength(0);
3053            buf.append("Start proc ");
3054            buf.append(app.processName);
3055            buf.append(" for ");
3056            buf.append(hostingType);
3057            if (hostingNameStr != null) {
3058                buf.append(" ");
3059                buf.append(hostingNameStr);
3060            }
3061            buf.append(": pid=");
3062            buf.append(startResult.pid);
3063            buf.append(" uid=");
3064            buf.append(uid);
3065            buf.append(" gids={");
3066            if (gids != null) {
3067                for (int gi=0; gi<gids.length; gi++) {
3068                    if (gi != 0) buf.append(", ");
3069                    buf.append(gids[gi]);
3070
3071                }
3072            }
3073            buf.append("}");
3074            if (requiredAbi != null) {
3075                buf.append(" abi=");
3076                buf.append(requiredAbi);
3077            }
3078            Slog.i(TAG, buf.toString());
3079            app.setPid(startResult.pid);
3080            app.usingWrapper = startResult.usingWrapper;
3081            app.removed = false;
3082            app.killedByAm = false;
3083            synchronized (mPidsSelfLocked) {
3084                this.mPidsSelfLocked.put(startResult.pid, app);
3085                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3086                msg.obj = app;
3087                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3088                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3089            }
3090        } catch (RuntimeException e) {
3091            // XXX do better error recovery.
3092            app.setPid(0);
3093            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3094            if (app.isolated) {
3095                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3096            }
3097            Slog.e(TAG, "Failure starting process " + app.processName, e);
3098        }
3099    }
3100
3101    void updateUsageStats(ActivityRecord component, boolean resumed) {
3102        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3103        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3104        if (resumed) {
3105            if (mUsageStatsService != null) {
3106                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3107                        System.currentTimeMillis(),
3108                        UsageStats.Event.MOVE_TO_FOREGROUND);
3109            }
3110            synchronized (stats) {
3111                stats.noteActivityResumedLocked(component.app.uid);
3112            }
3113        } else {
3114            if (mUsageStatsService != null) {
3115                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3116                        System.currentTimeMillis(),
3117                        UsageStats.Event.MOVE_TO_BACKGROUND);
3118            }
3119            synchronized (stats) {
3120                stats.noteActivityPausedLocked(component.app.uid);
3121            }
3122        }
3123    }
3124
3125    Intent getHomeIntent() {
3126        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3127        intent.setComponent(mTopComponent);
3128        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3129            intent.addCategory(Intent.CATEGORY_HOME);
3130        }
3131        return intent;
3132    }
3133
3134    boolean startHomeActivityLocked(int userId) {
3135        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3136                && mTopAction == null) {
3137            // We are running in factory test mode, but unable to find
3138            // the factory test app, so just sit around displaying the
3139            // error message and don't try to start anything.
3140            return false;
3141        }
3142        Intent intent = getHomeIntent();
3143        ActivityInfo aInfo =
3144            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3145        if (aInfo != null) {
3146            intent.setComponent(new ComponentName(
3147                    aInfo.applicationInfo.packageName, aInfo.name));
3148            // Don't do this if the home app is currently being
3149            // instrumented.
3150            aInfo = new ActivityInfo(aInfo);
3151            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3152            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3153                    aInfo.applicationInfo.uid, true);
3154            if (app == null || app.instrumentationClass == null) {
3155                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3156                mStackSupervisor.startHomeActivity(intent, aInfo);
3157            }
3158        }
3159
3160        return true;
3161    }
3162
3163    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3164        ActivityInfo ai = null;
3165        ComponentName comp = intent.getComponent();
3166        try {
3167            if (comp != null) {
3168                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3169            } else {
3170                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3171                        intent,
3172                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3173                            flags, userId);
3174
3175                if (info != null) {
3176                    ai = info.activityInfo;
3177                }
3178            }
3179        } catch (RemoteException e) {
3180            // ignore
3181        }
3182
3183        return ai;
3184    }
3185
3186    /**
3187     * Starts the "new version setup screen" if appropriate.
3188     */
3189    void startSetupActivityLocked() {
3190        // Only do this once per boot.
3191        if (mCheckedForSetup) {
3192            return;
3193        }
3194
3195        // We will show this screen if the current one is a different
3196        // version than the last one shown, and we are not running in
3197        // low-level factory test mode.
3198        final ContentResolver resolver = mContext.getContentResolver();
3199        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3200                Settings.Global.getInt(resolver,
3201                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3202            mCheckedForSetup = true;
3203
3204            // See if we should be showing the platform update setup UI.
3205            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3206            List<ResolveInfo> ris = mContext.getPackageManager()
3207                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3208
3209            // We don't allow third party apps to replace this.
3210            ResolveInfo ri = null;
3211            for (int i=0; ris != null && i<ris.size(); i++) {
3212                if ((ris.get(i).activityInfo.applicationInfo.flags
3213                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3214                    ri = ris.get(i);
3215                    break;
3216                }
3217            }
3218
3219            if (ri != null) {
3220                String vers = ri.activityInfo.metaData != null
3221                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3222                        : null;
3223                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3224                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3225                            Intent.METADATA_SETUP_VERSION);
3226                }
3227                String lastVers = Settings.Secure.getString(
3228                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3229                if (vers != null && !vers.equals(lastVers)) {
3230                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3231                    intent.setComponent(new ComponentName(
3232                            ri.activityInfo.packageName, ri.activityInfo.name));
3233                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3234                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3235                }
3236            }
3237        }
3238    }
3239
3240    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3241        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3242    }
3243
3244    void enforceNotIsolatedCaller(String caller) {
3245        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3246            throw new SecurityException("Isolated process not allowed to call " + caller);
3247        }
3248    }
3249
3250    @Override
3251    public int getFrontActivityScreenCompatMode() {
3252        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3253        synchronized (this) {
3254            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3255        }
3256    }
3257
3258    @Override
3259    public void setFrontActivityScreenCompatMode(int mode) {
3260        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3261                "setFrontActivityScreenCompatMode");
3262        synchronized (this) {
3263            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3264        }
3265    }
3266
3267    @Override
3268    public int getPackageScreenCompatMode(String packageName) {
3269        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3270        synchronized (this) {
3271            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3272        }
3273    }
3274
3275    @Override
3276    public void setPackageScreenCompatMode(String packageName, int mode) {
3277        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3278                "setPackageScreenCompatMode");
3279        synchronized (this) {
3280            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3281        }
3282    }
3283
3284    @Override
3285    public boolean getPackageAskScreenCompat(String packageName) {
3286        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3287        synchronized (this) {
3288            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3289        }
3290    }
3291
3292    @Override
3293    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3294        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3295                "setPackageAskScreenCompat");
3296        synchronized (this) {
3297            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3298        }
3299    }
3300
3301    private void dispatchProcessesChanged() {
3302        int N;
3303        synchronized (this) {
3304            N = mPendingProcessChanges.size();
3305            if (mActiveProcessChanges.length < N) {
3306                mActiveProcessChanges = new ProcessChangeItem[N];
3307            }
3308            mPendingProcessChanges.toArray(mActiveProcessChanges);
3309            mAvailProcessChanges.addAll(mPendingProcessChanges);
3310            mPendingProcessChanges.clear();
3311            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3312        }
3313
3314        int i = mProcessObservers.beginBroadcast();
3315        while (i > 0) {
3316            i--;
3317            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3318            if (observer != null) {
3319                try {
3320                    for (int j=0; j<N; j++) {
3321                        ProcessChangeItem item = mActiveProcessChanges[j];
3322                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3323                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3324                                    + item.pid + " uid=" + item.uid + ": "
3325                                    + item.foregroundActivities);
3326                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3327                                    item.foregroundActivities);
3328                        }
3329                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3330                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3331                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3332                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3333                        }
3334                    }
3335                } catch (RemoteException e) {
3336                }
3337            }
3338        }
3339        mProcessObservers.finishBroadcast();
3340    }
3341
3342    private void dispatchProcessDied(int pid, int uid) {
3343        int i = mProcessObservers.beginBroadcast();
3344        while (i > 0) {
3345            i--;
3346            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3347            if (observer != null) {
3348                try {
3349                    observer.onProcessDied(pid, uid);
3350                } catch (RemoteException e) {
3351                }
3352            }
3353        }
3354        mProcessObservers.finishBroadcast();
3355    }
3356
3357    @Override
3358    public final int startActivity(IApplicationThread caller, String callingPackage,
3359            Intent intent, String resolvedType, IBinder resultTo,
3360            String resultWho, int requestCode, int startFlags,
3361            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3362        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3363                resultWho, requestCode,
3364                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3365    }
3366
3367    @Override
3368    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3369            Intent intent, String resolvedType, IBinder resultTo,
3370            String resultWho, int requestCode, int startFlags,
3371            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3372        enforceNotIsolatedCaller("startActivity");
3373        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3374                false, ALLOW_FULL_ONLY, "startActivity", null);
3375        // TODO: Switch to user app stacks here.
3376        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3377                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3378                null, null, options, userId, null);
3379    }
3380
3381    @Override
3382    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3383            Intent intent, String resolvedType, IBinder resultTo,
3384            String resultWho, int requestCode, int startFlags, String profileFile,
3385            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3386        enforceNotIsolatedCaller("startActivityAndWait");
3387        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3388                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3389        WaitResult res = new WaitResult();
3390        // TODO: Switch to user app stacks here.
3391        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3392                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3393                res, null, options, userId, null);
3394        return res;
3395    }
3396
3397    @Override
3398    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3399            Intent intent, String resolvedType, IBinder resultTo,
3400            String resultWho, int requestCode, int startFlags, Configuration config,
3401            Bundle options, int userId) {
3402        enforceNotIsolatedCaller("startActivityWithConfig");
3403        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3404                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3405        // TODO: Switch to user app stacks here.
3406        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3407                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3408                null, null, null, config, options, userId, null);
3409        return ret;
3410    }
3411
3412    @Override
3413    public int startActivityIntentSender(IApplicationThread caller,
3414            IntentSender intent, Intent fillInIntent, String resolvedType,
3415            IBinder resultTo, String resultWho, int requestCode,
3416            int flagsMask, int flagsValues, Bundle options) {
3417        enforceNotIsolatedCaller("startActivityIntentSender");
3418        // Refuse possible leaked file descriptors
3419        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3420            throw new IllegalArgumentException("File descriptors passed in Intent");
3421        }
3422
3423        IIntentSender sender = intent.getTarget();
3424        if (!(sender instanceof PendingIntentRecord)) {
3425            throw new IllegalArgumentException("Bad PendingIntent object");
3426        }
3427
3428        PendingIntentRecord pir = (PendingIntentRecord)sender;
3429
3430        synchronized (this) {
3431            // If this is coming from the currently resumed activity, it is
3432            // effectively saying that app switches are allowed at this point.
3433            final ActivityStack stack = getFocusedStack();
3434            if (stack.mResumedActivity != null &&
3435                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3436                mAppSwitchesAllowedTime = 0;
3437            }
3438        }
3439        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3440                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3441        return ret;
3442    }
3443
3444    @Override
3445    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3446            Intent intent, String resolvedType, IVoiceInteractionSession session,
3447            IVoiceInteractor interactor, int startFlags, String profileFile,
3448            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3449        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3450                != PackageManager.PERMISSION_GRANTED) {
3451            String msg = "Permission Denial: startVoiceActivity() from pid="
3452                    + Binder.getCallingPid()
3453                    + ", uid=" + Binder.getCallingUid()
3454                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3455            Slog.w(TAG, msg);
3456            throw new SecurityException(msg);
3457        }
3458        if (session == null || interactor == null) {
3459            throw new NullPointerException("null session or interactor");
3460        }
3461        userId = handleIncomingUser(callingPid, callingUid, userId,
3462                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3463        // TODO: Switch to user app stacks here.
3464        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3465                resolvedType, session, interactor, null, null, 0, startFlags,
3466                profileFile, profileFd, null, null, options, userId, null);
3467    }
3468
3469    @Override
3470    public boolean startNextMatchingActivity(IBinder callingActivity,
3471            Intent intent, Bundle options) {
3472        // Refuse possible leaked file descriptors
3473        if (intent != null && intent.hasFileDescriptors() == true) {
3474            throw new IllegalArgumentException("File descriptors passed in Intent");
3475        }
3476
3477        synchronized (this) {
3478            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3479            if (r == null) {
3480                ActivityOptions.abort(options);
3481                return false;
3482            }
3483            if (r.app == null || r.app.thread == null) {
3484                // The caller is not running...  d'oh!
3485                ActivityOptions.abort(options);
3486                return false;
3487            }
3488            intent = new Intent(intent);
3489            // The caller is not allowed to change the data.
3490            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3491            // And we are resetting to find the next component...
3492            intent.setComponent(null);
3493
3494            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3495
3496            ActivityInfo aInfo = null;
3497            try {
3498                List<ResolveInfo> resolves =
3499                    AppGlobals.getPackageManager().queryIntentActivities(
3500                            intent, r.resolvedType,
3501                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3502                            UserHandle.getCallingUserId());
3503
3504                // Look for the original activity in the list...
3505                final int N = resolves != null ? resolves.size() : 0;
3506                for (int i=0; i<N; i++) {
3507                    ResolveInfo rInfo = resolves.get(i);
3508                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3509                            && rInfo.activityInfo.name.equals(r.info.name)) {
3510                        // We found the current one...  the next matching is
3511                        // after it.
3512                        i++;
3513                        if (i<N) {
3514                            aInfo = resolves.get(i).activityInfo;
3515                        }
3516                        if (debug) {
3517                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3518                                    + "/" + r.info.name);
3519                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3520                                    + "/" + aInfo.name);
3521                        }
3522                        break;
3523                    }
3524                }
3525            } catch (RemoteException e) {
3526            }
3527
3528            if (aInfo == null) {
3529                // Nobody who is next!
3530                ActivityOptions.abort(options);
3531                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3532                return false;
3533            }
3534
3535            intent.setComponent(new ComponentName(
3536                    aInfo.applicationInfo.packageName, aInfo.name));
3537            intent.setFlags(intent.getFlags()&~(
3538                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3539                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3540                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3541                    Intent.FLAG_ACTIVITY_NEW_TASK));
3542
3543            // Okay now we need to start the new activity, replacing the
3544            // currently running activity.  This is a little tricky because
3545            // we want to start the new one as if the current one is finished,
3546            // but not finish the current one first so that there is no flicker.
3547            // And thus...
3548            final boolean wasFinishing = r.finishing;
3549            r.finishing = true;
3550
3551            // Propagate reply information over to the new activity.
3552            final ActivityRecord resultTo = r.resultTo;
3553            final String resultWho = r.resultWho;
3554            final int requestCode = r.requestCode;
3555            r.resultTo = null;
3556            if (resultTo != null) {
3557                resultTo.removeResultsLocked(r, resultWho, requestCode);
3558            }
3559
3560            final long origId = Binder.clearCallingIdentity();
3561            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3562                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3563                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3564                    options, false, null, null);
3565            Binder.restoreCallingIdentity(origId);
3566
3567            r.finishing = wasFinishing;
3568            if (res != ActivityManager.START_SUCCESS) {
3569                return false;
3570            }
3571            return true;
3572        }
3573    }
3574
3575    @Override
3576    public final int startActivityFromRecents(int taskId, Bundle options) {
3577        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3578            String msg = "Permission Denial: startActivityFromRecents called without " +
3579                    START_TASKS_FROM_RECENTS;
3580            Slog.w(TAG, msg);
3581            throw new SecurityException(msg);
3582        }
3583        final int callingUid;
3584        final String callingPackage;
3585        final Intent intent;
3586        final int userId;
3587        synchronized (this) {
3588            final TaskRecord task = recentTaskForIdLocked(taskId);
3589            if (task == null) {
3590                throw new ActivityNotFoundException("Task " + taskId + " not found.");
3591            }
3592            callingUid = task.mCallingUid;
3593            callingPackage = task.mCallingPackage;
3594            intent = task.intent;
3595            userId = task.userId;
3596        }
3597        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3598                options, userId, null);
3599    }
3600
3601    final int startActivityInPackage(int uid, String callingPackage,
3602            Intent intent, String resolvedType, IBinder resultTo,
3603            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3604                    IActivityContainer container) {
3605
3606        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3607                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3608
3609        // TODO: Switch to user app stacks here.
3610        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3611                null, null, resultTo, resultWho, requestCode, startFlags,
3612                null, null, null, null, options, userId, container);
3613        return ret;
3614    }
3615
3616    @Override
3617    public final int startActivities(IApplicationThread caller, String callingPackage,
3618            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3619            int userId) {
3620        enforceNotIsolatedCaller("startActivities");
3621        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3622                false, ALLOW_FULL_ONLY, "startActivity", null);
3623        // TODO: Switch to user app stacks here.
3624        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3625                resolvedTypes, resultTo, options, userId);
3626        return ret;
3627    }
3628
3629    final int startActivitiesInPackage(int uid, String callingPackage,
3630            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3631            Bundle options, int userId) {
3632
3633        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3634                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3635        // TODO: Switch to user app stacks here.
3636        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3637                resultTo, options, userId);
3638        return ret;
3639    }
3640
3641    final void addRecentTaskLocked(TaskRecord task) {
3642        int N = mRecentTasks.size();
3643        // Quick case: check if the top-most recent task is the same.
3644        if (N > 0 && mRecentTasks.get(0) == task) {
3645            return;
3646        }
3647        // Another quick case: never add voice sessions.
3648        if (task.voiceSession != null) {
3649            return;
3650        }
3651        // Remove any existing entries that are the same kind of task.
3652        final Intent intent = task.intent;
3653        final boolean document = intent != null && intent.isDocument();
3654        final ComponentName comp = intent.getComponent();
3655
3656        int maxRecents = task.maxRecents - 1;
3657        for (int i=0; i<N; i++) {
3658            final TaskRecord tr = mRecentTasks.get(i);
3659            if (task != tr) {
3660                if (task.userId != tr.userId) {
3661                    continue;
3662                }
3663                if (i > MAX_RECENT_BITMAPS) {
3664                    tr.freeLastThumbnail();
3665                }
3666                final Intent trIntent = tr.intent;
3667                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3668                    (intent == null || !intent.filterEquals(trIntent))) {
3669                    continue;
3670                }
3671                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3672                if (document && trIsDocument) {
3673                    // These are the same document activity (not necessarily the same doc).
3674                    if (maxRecents > 0) {
3675                        --maxRecents;
3676                        continue;
3677                    }
3678                    // Hit the maximum number of documents for this task. Fall through
3679                    // and remove this document from recents.
3680                } else if (document || trIsDocument) {
3681                    // Only one of these is a document. Not the droid we're looking for.
3682                    continue;
3683                }
3684            }
3685
3686            // Either task and tr are the same or, their affinities match or their intents match
3687            // and neither of them is a document, or they are documents using the same activity
3688            // and their maxRecents has been reached.
3689            tr.disposeThumbnail();
3690            mRecentTasks.remove(i);
3691            if (task != tr) {
3692                tr.closeRecentsChain();
3693            }
3694            i--;
3695            N--;
3696            if (task.intent == null) {
3697                // If the new recent task we are adding is not fully
3698                // specified, then replace it with the existing recent task.
3699                task = tr;
3700            }
3701            notifyTaskPersisterLocked(tr, false);
3702        }
3703        if (N >= MAX_RECENT_TASKS) {
3704            final TaskRecord tr = mRecentTasks.remove(N - 1);
3705            tr.disposeThumbnail();
3706            tr.closeRecentsChain();
3707        }
3708        mRecentTasks.add(0, task);
3709    }
3710
3711    @Override
3712    public void reportActivityFullyDrawn(IBinder token) {
3713        synchronized (this) {
3714            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3715            if (r == null) {
3716                return;
3717            }
3718            r.reportFullyDrawnLocked();
3719        }
3720    }
3721
3722    @Override
3723    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3724        synchronized (this) {
3725            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3726            if (r == null) {
3727                return;
3728            }
3729            final long origId = Binder.clearCallingIdentity();
3730            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3731            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3732                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3733            if (config != null) {
3734                r.frozenBeforeDestroy = true;
3735                if (!updateConfigurationLocked(config, r, false, false)) {
3736                    mStackSupervisor.resumeTopActivitiesLocked();
3737                }
3738            }
3739            Binder.restoreCallingIdentity(origId);
3740        }
3741    }
3742
3743    @Override
3744    public int getRequestedOrientation(IBinder token) {
3745        synchronized (this) {
3746            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3747            if (r == null) {
3748                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3749            }
3750            return mWindowManager.getAppOrientation(r.appToken);
3751        }
3752    }
3753
3754    /**
3755     * This is the internal entry point for handling Activity.finish().
3756     *
3757     * @param token The Binder token referencing the Activity we want to finish.
3758     * @param resultCode Result code, if any, from this Activity.
3759     * @param resultData Result data (Intent), if any, from this Activity.
3760     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3761     *            the root Activity in the task.
3762     *
3763     * @return Returns true if the activity successfully finished, or false if it is still running.
3764     */
3765    @Override
3766    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3767            boolean finishTask) {
3768        // Refuse possible leaked file descriptors
3769        if (resultData != null && resultData.hasFileDescriptors() == true) {
3770            throw new IllegalArgumentException("File descriptors passed in Intent");
3771        }
3772
3773        synchronized(this) {
3774            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3775            if (r == null) {
3776                return true;
3777            }
3778            // Keep track of the root activity of the task before we finish it
3779            TaskRecord tr = r.task;
3780            ActivityRecord rootR = tr.getRootActivity();
3781            // Do not allow task to finish in Lock Task mode.
3782            if (tr == mStackSupervisor.mLockTaskModeTask) {
3783                if (rootR == r) {
3784                    mStackSupervisor.showLockTaskToast();
3785                    return false;
3786                }
3787            }
3788            if (mController != null) {
3789                // Find the first activity that is not finishing.
3790                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3791                if (next != null) {
3792                    // ask watcher if this is allowed
3793                    boolean resumeOK = true;
3794                    try {
3795                        resumeOK = mController.activityResuming(next.packageName);
3796                    } catch (RemoteException e) {
3797                        mController = null;
3798                        Watchdog.getInstance().setActivityController(null);
3799                    }
3800
3801                    if (!resumeOK) {
3802                        return false;
3803                    }
3804                }
3805            }
3806            final long origId = Binder.clearCallingIdentity();
3807            try {
3808                boolean res;
3809                if (finishTask && r == rootR) {
3810                    // If requested, remove the task that is associated to this activity only if it
3811                    // was the root activity in the task.  The result code and data is ignored because
3812                    // we don't support returning them across task boundaries.
3813                    res = removeTaskByIdLocked(tr.taskId, 0);
3814                } else {
3815                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3816                            resultData, "app-request", true);
3817                }
3818                return res;
3819            } finally {
3820                Binder.restoreCallingIdentity(origId);
3821            }
3822        }
3823    }
3824
3825    @Override
3826    public final void finishHeavyWeightApp() {
3827        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3828                != PackageManager.PERMISSION_GRANTED) {
3829            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3830                    + Binder.getCallingPid()
3831                    + ", uid=" + Binder.getCallingUid()
3832                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3833            Slog.w(TAG, msg);
3834            throw new SecurityException(msg);
3835        }
3836
3837        synchronized(this) {
3838            if (mHeavyWeightProcess == null) {
3839                return;
3840            }
3841
3842            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3843                    mHeavyWeightProcess.activities);
3844            for (int i=0; i<activities.size(); i++) {
3845                ActivityRecord r = activities.get(i);
3846                if (!r.finishing) {
3847                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3848                            null, "finish-heavy", true);
3849                }
3850            }
3851
3852            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3853                    mHeavyWeightProcess.userId, 0));
3854            mHeavyWeightProcess = null;
3855        }
3856    }
3857
3858    @Override
3859    public void crashApplication(int uid, int initialPid, String packageName,
3860            String message) {
3861        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3862                != PackageManager.PERMISSION_GRANTED) {
3863            String msg = "Permission Denial: crashApplication() from pid="
3864                    + Binder.getCallingPid()
3865                    + ", uid=" + Binder.getCallingUid()
3866                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3867            Slog.w(TAG, msg);
3868            throw new SecurityException(msg);
3869        }
3870
3871        synchronized(this) {
3872            ProcessRecord proc = null;
3873
3874            // Figure out which process to kill.  We don't trust that initialPid
3875            // still has any relation to current pids, so must scan through the
3876            // list.
3877            synchronized (mPidsSelfLocked) {
3878                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3879                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3880                    if (p.uid != uid) {
3881                        continue;
3882                    }
3883                    if (p.pid == initialPid) {
3884                        proc = p;
3885                        break;
3886                    }
3887                    if (p.pkgList.containsKey(packageName)) {
3888                        proc = p;
3889                    }
3890                }
3891            }
3892
3893            if (proc == null) {
3894                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3895                        + " initialPid=" + initialPid
3896                        + " packageName=" + packageName);
3897                return;
3898            }
3899
3900            if (proc.thread != null) {
3901                if (proc.pid == Process.myPid()) {
3902                    Log.w(TAG, "crashApplication: trying to crash self!");
3903                    return;
3904                }
3905                long ident = Binder.clearCallingIdentity();
3906                try {
3907                    proc.thread.scheduleCrash(message);
3908                } catch (RemoteException e) {
3909                }
3910                Binder.restoreCallingIdentity(ident);
3911            }
3912        }
3913    }
3914
3915    @Override
3916    public final void finishSubActivity(IBinder token, String resultWho,
3917            int requestCode) {
3918        synchronized(this) {
3919            final long origId = Binder.clearCallingIdentity();
3920            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3921            if (r != null) {
3922                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3923            }
3924            Binder.restoreCallingIdentity(origId);
3925        }
3926    }
3927
3928    @Override
3929    public boolean finishActivityAffinity(IBinder token) {
3930        synchronized(this) {
3931            final long origId = Binder.clearCallingIdentity();
3932            try {
3933                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3934
3935                ActivityRecord rootR = r.task.getRootActivity();
3936                // Do not allow task to finish in Lock Task mode.
3937                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3938                    if (rootR == r) {
3939                        mStackSupervisor.showLockTaskToast();
3940                        return false;
3941                    }
3942                }
3943                boolean res = false;
3944                if (r != null) {
3945                    res = r.task.stack.finishActivityAffinityLocked(r);
3946                }
3947                return res;
3948            } finally {
3949                Binder.restoreCallingIdentity(origId);
3950            }
3951        }
3952    }
3953
3954    @Override
3955    public void finishVoiceTask(IVoiceInteractionSession session) {
3956        synchronized(this) {
3957            final long origId = Binder.clearCallingIdentity();
3958            try {
3959                mStackSupervisor.finishVoiceTask(session);
3960            } finally {
3961                Binder.restoreCallingIdentity(origId);
3962            }
3963        }
3964
3965    }
3966
3967    @Override
3968    public boolean willActivityBeVisible(IBinder token) {
3969        synchronized(this) {
3970            ActivityStack stack = ActivityRecord.getStackLocked(token);
3971            if (stack != null) {
3972                return stack.willActivityBeVisibleLocked(token);
3973            }
3974            return false;
3975        }
3976    }
3977
3978    @Override
3979    public void overridePendingTransition(IBinder token, String packageName,
3980            int enterAnim, int exitAnim) {
3981        synchronized(this) {
3982            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3983            if (self == null) {
3984                return;
3985            }
3986
3987            final long origId = Binder.clearCallingIdentity();
3988
3989            if (self.state == ActivityState.RESUMED
3990                    || self.state == ActivityState.PAUSING) {
3991                mWindowManager.overridePendingAppTransition(packageName,
3992                        enterAnim, exitAnim, null);
3993            }
3994
3995            Binder.restoreCallingIdentity(origId);
3996        }
3997    }
3998
3999    /**
4000     * Main function for removing an existing process from the activity manager
4001     * as a result of that process going away.  Clears out all connections
4002     * to the process.
4003     */
4004    private final void handleAppDiedLocked(ProcessRecord app,
4005            boolean restarting, boolean allowRestart) {
4006        int pid = app.pid;
4007        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4008        if (!restarting) {
4009            removeLruProcessLocked(app);
4010            if (pid > 0) {
4011                ProcessList.remove(pid);
4012            }
4013        }
4014
4015        if (mProfileProc == app) {
4016            clearProfilerLocked();
4017        }
4018
4019        // Remove this application's activities from active lists.
4020        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4021
4022        app.activities.clear();
4023
4024        if (app.instrumentationClass != null) {
4025            Slog.w(TAG, "Crash of app " + app.processName
4026                  + " running instrumentation " + app.instrumentationClass);
4027            Bundle info = new Bundle();
4028            info.putString("shortMsg", "Process crashed.");
4029            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4030        }
4031
4032        if (!restarting) {
4033            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4034                // If there was nothing to resume, and we are not already
4035                // restarting this process, but there is a visible activity that
4036                // is hosted by the process...  then make sure all visible
4037                // activities are running, taking care of restarting this
4038                // process.
4039                if (hasVisibleActivities) {
4040                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4041                }
4042            }
4043        }
4044    }
4045
4046    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4047        IBinder threadBinder = thread.asBinder();
4048        // Find the application record.
4049        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4050            ProcessRecord rec = mLruProcesses.get(i);
4051            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4052                return i;
4053            }
4054        }
4055        return -1;
4056    }
4057
4058    final ProcessRecord getRecordForAppLocked(
4059            IApplicationThread thread) {
4060        if (thread == null) {
4061            return null;
4062        }
4063
4064        int appIndex = getLRURecordIndexForAppLocked(thread);
4065        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4066    }
4067
4068    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4069        // If there are no longer any background processes running,
4070        // and the app that died was not running instrumentation,
4071        // then tell everyone we are now low on memory.
4072        boolean haveBg = false;
4073        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4074            ProcessRecord rec = mLruProcesses.get(i);
4075            if (rec.thread != null
4076                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4077                haveBg = true;
4078                break;
4079            }
4080        }
4081
4082        if (!haveBg) {
4083            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4084            if (doReport) {
4085                long now = SystemClock.uptimeMillis();
4086                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4087                    doReport = false;
4088                } else {
4089                    mLastMemUsageReportTime = now;
4090                }
4091            }
4092            final ArrayList<ProcessMemInfo> memInfos
4093                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4094            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4095            long now = SystemClock.uptimeMillis();
4096            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4097                ProcessRecord rec = mLruProcesses.get(i);
4098                if (rec == dyingProc || rec.thread == null) {
4099                    continue;
4100                }
4101                if (doReport) {
4102                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4103                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4104                }
4105                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4106                    // The low memory report is overriding any current
4107                    // state for a GC request.  Make sure to do
4108                    // heavy/important/visible/foreground processes first.
4109                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4110                        rec.lastRequestedGc = 0;
4111                    } else {
4112                        rec.lastRequestedGc = rec.lastLowMemory;
4113                    }
4114                    rec.reportLowMemory = true;
4115                    rec.lastLowMemory = now;
4116                    mProcessesToGc.remove(rec);
4117                    addProcessToGcListLocked(rec);
4118                }
4119            }
4120            if (doReport) {
4121                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4122                mHandler.sendMessage(msg);
4123            }
4124            scheduleAppGcsLocked();
4125        }
4126    }
4127
4128    final void appDiedLocked(ProcessRecord app, int pid,
4129            IApplicationThread thread) {
4130
4131        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4132        synchronized (stats) {
4133            stats.noteProcessDiedLocked(app.info.uid, pid);
4134        }
4135
4136        Process.killProcessGroup(app.info.uid, pid);
4137
4138        // Clean up already done if the process has been re-started.
4139        if (app.pid == pid && app.thread != null &&
4140                app.thread.asBinder() == thread.asBinder()) {
4141            boolean doLowMem = app.instrumentationClass == null;
4142            boolean doOomAdj = doLowMem;
4143            if (!app.killedByAm) {
4144                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4145                        + ") has died.");
4146                mAllowLowerMemLevel = true;
4147            } else {
4148                // Note that we always want to do oom adj to update our state with the
4149                // new number of procs.
4150                mAllowLowerMemLevel = false;
4151                doLowMem = false;
4152            }
4153            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4154            if (DEBUG_CLEANUP) Slog.v(
4155                TAG, "Dying app: " + app + ", pid: " + pid
4156                + ", thread: " + thread.asBinder());
4157            handleAppDiedLocked(app, false, true);
4158
4159            if (doOomAdj) {
4160                updateOomAdjLocked();
4161            }
4162            if (doLowMem) {
4163                doLowMemReportIfNeededLocked(app);
4164            }
4165        } else if (app.pid != pid) {
4166            // A new process has already been started.
4167            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4168                    + ") has died and restarted (pid " + app.pid + ").");
4169            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4170        } else if (DEBUG_PROCESSES) {
4171            Slog.d(TAG, "Received spurious death notification for thread "
4172                    + thread.asBinder());
4173        }
4174    }
4175
4176    /**
4177     * If a stack trace dump file is configured, dump process stack traces.
4178     * @param clearTraces causes the dump file to be erased prior to the new
4179     *    traces being written, if true; when false, the new traces will be
4180     *    appended to any existing file content.
4181     * @param firstPids of dalvik VM processes to dump stack traces for first
4182     * @param lastPids of dalvik VM processes to dump stack traces for last
4183     * @param nativeProcs optional list of native process names to dump stack crawls
4184     * @return file containing stack traces, or null if no dump file is configured
4185     */
4186    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4187            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4188        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4189        if (tracesPath == null || tracesPath.length() == 0) {
4190            return null;
4191        }
4192
4193        File tracesFile = new File(tracesPath);
4194        try {
4195            File tracesDir = tracesFile.getParentFile();
4196            if (!tracesDir.exists()) {
4197                tracesFile.mkdirs();
4198                if (!SELinux.restorecon(tracesDir)) {
4199                    return null;
4200                }
4201            }
4202            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4203
4204            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4205            tracesFile.createNewFile();
4206            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4207        } catch (IOException e) {
4208            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4209            return null;
4210        }
4211
4212        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4213        return tracesFile;
4214    }
4215
4216    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4217            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4218        // Use a FileObserver to detect when traces finish writing.
4219        // The order of traces is considered important to maintain for legibility.
4220        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4221            @Override
4222            public synchronized void onEvent(int event, String path) { notify(); }
4223        };
4224
4225        try {
4226            observer.startWatching();
4227
4228            // First collect all of the stacks of the most important pids.
4229            if (firstPids != null) {
4230                try {
4231                    int num = firstPids.size();
4232                    for (int i = 0; i < num; i++) {
4233                        synchronized (observer) {
4234                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4235                            observer.wait(200);  // Wait for write-close, give up after 200msec
4236                        }
4237                    }
4238                } catch (InterruptedException e) {
4239                    Log.wtf(TAG, e);
4240                }
4241            }
4242
4243            // Next collect the stacks of the native pids
4244            if (nativeProcs != null) {
4245                int[] pids = Process.getPidsForCommands(nativeProcs);
4246                if (pids != null) {
4247                    for (int pid : pids) {
4248                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4249                    }
4250                }
4251            }
4252
4253            // Lastly, measure CPU usage.
4254            if (processCpuTracker != null) {
4255                processCpuTracker.init();
4256                System.gc();
4257                processCpuTracker.update();
4258                try {
4259                    synchronized (processCpuTracker) {
4260                        processCpuTracker.wait(500); // measure over 1/2 second.
4261                    }
4262                } catch (InterruptedException e) {
4263                }
4264                processCpuTracker.update();
4265
4266                // We'll take the stack crawls of just the top apps using CPU.
4267                final int N = processCpuTracker.countWorkingStats();
4268                int numProcs = 0;
4269                for (int i=0; i<N && numProcs<5; i++) {
4270                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4271                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4272                        numProcs++;
4273                        try {
4274                            synchronized (observer) {
4275                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4276                                observer.wait(200);  // Wait for write-close, give up after 200msec
4277                            }
4278                        } catch (InterruptedException e) {
4279                            Log.wtf(TAG, e);
4280                        }
4281
4282                    }
4283                }
4284            }
4285        } finally {
4286            observer.stopWatching();
4287        }
4288    }
4289
4290    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4291        if (true || IS_USER_BUILD) {
4292            return;
4293        }
4294        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4295        if (tracesPath == null || tracesPath.length() == 0) {
4296            return;
4297        }
4298
4299        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4300        StrictMode.allowThreadDiskWrites();
4301        try {
4302            final File tracesFile = new File(tracesPath);
4303            final File tracesDir = tracesFile.getParentFile();
4304            final File tracesTmp = new File(tracesDir, "__tmp__");
4305            try {
4306                if (!tracesDir.exists()) {
4307                    tracesFile.mkdirs();
4308                    if (!SELinux.restorecon(tracesDir.getPath())) {
4309                        return;
4310                    }
4311                }
4312                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4313
4314                if (tracesFile.exists()) {
4315                    tracesTmp.delete();
4316                    tracesFile.renameTo(tracesTmp);
4317                }
4318                StringBuilder sb = new StringBuilder();
4319                Time tobj = new Time();
4320                tobj.set(System.currentTimeMillis());
4321                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4322                sb.append(": ");
4323                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4324                sb.append(" since ");
4325                sb.append(msg);
4326                FileOutputStream fos = new FileOutputStream(tracesFile);
4327                fos.write(sb.toString().getBytes());
4328                if (app == null) {
4329                    fos.write("\n*** No application process!".getBytes());
4330                }
4331                fos.close();
4332                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4333            } catch (IOException e) {
4334                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4335                return;
4336            }
4337
4338            if (app != null) {
4339                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4340                firstPids.add(app.pid);
4341                dumpStackTraces(tracesPath, firstPids, null, null, null);
4342            }
4343
4344            File lastTracesFile = null;
4345            File curTracesFile = null;
4346            for (int i=9; i>=0; i--) {
4347                String name = String.format(Locale.US, "slow%02d.txt", i);
4348                curTracesFile = new File(tracesDir, name);
4349                if (curTracesFile.exists()) {
4350                    if (lastTracesFile != null) {
4351                        curTracesFile.renameTo(lastTracesFile);
4352                    } else {
4353                        curTracesFile.delete();
4354                    }
4355                }
4356                lastTracesFile = curTracesFile;
4357            }
4358            tracesFile.renameTo(curTracesFile);
4359            if (tracesTmp.exists()) {
4360                tracesTmp.renameTo(tracesFile);
4361            }
4362        } finally {
4363            StrictMode.setThreadPolicy(oldPolicy);
4364        }
4365    }
4366
4367    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4368            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4369        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4370        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4371
4372        if (mController != null) {
4373            try {
4374                // 0 == continue, -1 = kill process immediately
4375                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4376                if (res < 0 && app.pid != MY_PID) {
4377                    Process.killProcess(app.pid);
4378                    Process.killProcessGroup(app.info.uid, app.pid);
4379                }
4380            } catch (RemoteException e) {
4381                mController = null;
4382                Watchdog.getInstance().setActivityController(null);
4383            }
4384        }
4385
4386        long anrTime = SystemClock.uptimeMillis();
4387        if (MONITOR_CPU_USAGE) {
4388            updateCpuStatsNow();
4389        }
4390
4391        synchronized (this) {
4392            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4393            if (mShuttingDown) {
4394                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4395                return;
4396            } else if (app.notResponding) {
4397                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4398                return;
4399            } else if (app.crashing) {
4400                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4401                return;
4402            }
4403
4404            // In case we come through here for the same app before completing
4405            // this one, mark as anring now so we will bail out.
4406            app.notResponding = true;
4407
4408            // Log the ANR to the event log.
4409            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4410                    app.processName, app.info.flags, annotation);
4411
4412            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4413            firstPids.add(app.pid);
4414
4415            int parentPid = app.pid;
4416            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4417            if (parentPid != app.pid) firstPids.add(parentPid);
4418
4419            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4420
4421            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4422                ProcessRecord r = mLruProcesses.get(i);
4423                if (r != null && r.thread != null) {
4424                    int pid = r.pid;
4425                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4426                        if (r.persistent) {
4427                            firstPids.add(pid);
4428                        } else {
4429                            lastPids.put(pid, Boolean.TRUE);
4430                        }
4431                    }
4432                }
4433            }
4434        }
4435
4436        // Log the ANR to the main log.
4437        StringBuilder info = new StringBuilder();
4438        info.setLength(0);
4439        info.append("ANR in ").append(app.processName);
4440        if (activity != null && activity.shortComponentName != null) {
4441            info.append(" (").append(activity.shortComponentName).append(")");
4442        }
4443        info.append("\n");
4444        info.append("PID: ").append(app.pid).append("\n");
4445        if (annotation != null) {
4446            info.append("Reason: ").append(annotation).append("\n");
4447        }
4448        if (parent != null && parent != activity) {
4449            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4450        }
4451
4452        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4453
4454        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4455                NATIVE_STACKS_OF_INTEREST);
4456
4457        String cpuInfo = null;
4458        if (MONITOR_CPU_USAGE) {
4459            updateCpuStatsNow();
4460            synchronized (mProcessCpuThread) {
4461                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4462            }
4463            info.append(processCpuTracker.printCurrentLoad());
4464            info.append(cpuInfo);
4465        }
4466
4467        info.append(processCpuTracker.printCurrentState(anrTime));
4468
4469        Slog.e(TAG, info.toString());
4470        if (tracesFile == null) {
4471            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4472            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4473        }
4474
4475        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4476                cpuInfo, tracesFile, null);
4477
4478        if (mController != null) {
4479            try {
4480                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4481                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4482                if (res != 0) {
4483                    if (res < 0 && app.pid != MY_PID) {
4484                        Process.killProcess(app.pid);
4485                        Process.killProcessGroup(app.info.uid, app.pid);
4486                    } else {
4487                        synchronized (this) {
4488                            mServices.scheduleServiceTimeoutLocked(app);
4489                        }
4490                    }
4491                    return;
4492                }
4493            } catch (RemoteException e) {
4494                mController = null;
4495                Watchdog.getInstance().setActivityController(null);
4496            }
4497        }
4498
4499        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4500        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4501                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4502
4503        synchronized (this) {
4504            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4505                killUnneededProcessLocked(app, "background ANR");
4506                return;
4507            }
4508
4509            // Set the app's notResponding state, and look up the errorReportReceiver
4510            makeAppNotRespondingLocked(app,
4511                    activity != null ? activity.shortComponentName : null,
4512                    annotation != null ? "ANR " + annotation : "ANR",
4513                    info.toString());
4514
4515            // Bring up the infamous App Not Responding dialog
4516            Message msg = Message.obtain();
4517            HashMap<String, Object> map = new HashMap<String, Object>();
4518            msg.what = SHOW_NOT_RESPONDING_MSG;
4519            msg.obj = map;
4520            msg.arg1 = aboveSystem ? 1 : 0;
4521            map.put("app", app);
4522            if (activity != null) {
4523                map.put("activity", activity);
4524            }
4525
4526            mHandler.sendMessage(msg);
4527        }
4528    }
4529
4530    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4531        if (!mLaunchWarningShown) {
4532            mLaunchWarningShown = true;
4533            mHandler.post(new Runnable() {
4534                @Override
4535                public void run() {
4536                    synchronized (ActivityManagerService.this) {
4537                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4538                        d.show();
4539                        mHandler.postDelayed(new Runnable() {
4540                            @Override
4541                            public void run() {
4542                                synchronized (ActivityManagerService.this) {
4543                                    d.dismiss();
4544                                    mLaunchWarningShown = false;
4545                                }
4546                            }
4547                        }, 4000);
4548                    }
4549                }
4550            });
4551        }
4552    }
4553
4554    @Override
4555    public boolean clearApplicationUserData(final String packageName,
4556            final IPackageDataObserver observer, int userId) {
4557        enforceNotIsolatedCaller("clearApplicationUserData");
4558        int uid = Binder.getCallingUid();
4559        int pid = Binder.getCallingPid();
4560        userId = handleIncomingUser(pid, uid,
4561                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4562        long callingId = Binder.clearCallingIdentity();
4563        try {
4564            IPackageManager pm = AppGlobals.getPackageManager();
4565            int pkgUid = -1;
4566            synchronized(this) {
4567                try {
4568                    pkgUid = pm.getPackageUid(packageName, userId);
4569                } catch (RemoteException e) {
4570                }
4571                if (pkgUid == -1) {
4572                    Slog.w(TAG, "Invalid packageName: " + packageName);
4573                    if (observer != null) {
4574                        try {
4575                            observer.onRemoveCompleted(packageName, false);
4576                        } catch (RemoteException e) {
4577                            Slog.i(TAG, "Observer no longer exists.");
4578                        }
4579                    }
4580                    return false;
4581                }
4582                if (uid == pkgUid || checkComponentPermission(
4583                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4584                        pid, uid, -1, true)
4585                        == PackageManager.PERMISSION_GRANTED) {
4586                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4587                } else {
4588                    throw new SecurityException("PID " + pid + " does not have permission "
4589                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4590                                    + " of package " + packageName);
4591                }
4592            }
4593
4594            try {
4595                // Clear application user data
4596                pm.clearApplicationUserData(packageName, observer, userId);
4597
4598                // Remove all permissions granted from/to this package
4599                removeUriPermissionsForPackageLocked(packageName, userId, true);
4600
4601                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4602                        Uri.fromParts("package", packageName, null));
4603                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4604                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4605                        null, null, 0, null, null, null, false, false, userId);
4606            } catch (RemoteException e) {
4607            }
4608        } finally {
4609            Binder.restoreCallingIdentity(callingId);
4610        }
4611        return true;
4612    }
4613
4614    @Override
4615    public void killBackgroundProcesses(final String packageName, int userId) {
4616        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4617                != PackageManager.PERMISSION_GRANTED &&
4618                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4619                        != PackageManager.PERMISSION_GRANTED) {
4620            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4621                    + Binder.getCallingPid()
4622                    + ", uid=" + Binder.getCallingUid()
4623                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4624            Slog.w(TAG, msg);
4625            throw new SecurityException(msg);
4626        }
4627
4628        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4629                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4630        long callingId = Binder.clearCallingIdentity();
4631        try {
4632            IPackageManager pm = AppGlobals.getPackageManager();
4633            synchronized(this) {
4634                int appId = -1;
4635                try {
4636                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4637                } catch (RemoteException e) {
4638                }
4639                if (appId == -1) {
4640                    Slog.w(TAG, "Invalid packageName: " + packageName);
4641                    return;
4642                }
4643                killPackageProcessesLocked(packageName, appId, userId,
4644                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4645            }
4646        } finally {
4647            Binder.restoreCallingIdentity(callingId);
4648        }
4649    }
4650
4651    @Override
4652    public void killAllBackgroundProcesses() {
4653        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4654                != PackageManager.PERMISSION_GRANTED) {
4655            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4656                    + Binder.getCallingPid()
4657                    + ", uid=" + Binder.getCallingUid()
4658                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4659            Slog.w(TAG, msg);
4660            throw new SecurityException(msg);
4661        }
4662
4663        long callingId = Binder.clearCallingIdentity();
4664        try {
4665            synchronized(this) {
4666                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4667                final int NP = mProcessNames.getMap().size();
4668                for (int ip=0; ip<NP; ip++) {
4669                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4670                    final int NA = apps.size();
4671                    for (int ia=0; ia<NA; ia++) {
4672                        ProcessRecord app = apps.valueAt(ia);
4673                        if (app.persistent) {
4674                            // we don't kill persistent processes
4675                            continue;
4676                        }
4677                        if (app.removed) {
4678                            procs.add(app);
4679                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4680                            app.removed = true;
4681                            procs.add(app);
4682                        }
4683                    }
4684                }
4685
4686                int N = procs.size();
4687                for (int i=0; i<N; i++) {
4688                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4689                }
4690                mAllowLowerMemLevel = true;
4691                updateOomAdjLocked();
4692                doLowMemReportIfNeededLocked(null);
4693            }
4694        } finally {
4695            Binder.restoreCallingIdentity(callingId);
4696        }
4697    }
4698
4699    @Override
4700    public void forceStopPackage(final String packageName, int userId) {
4701        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4702                != PackageManager.PERMISSION_GRANTED) {
4703            String msg = "Permission Denial: forceStopPackage() from pid="
4704                    + Binder.getCallingPid()
4705                    + ", uid=" + Binder.getCallingUid()
4706                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4707            Slog.w(TAG, msg);
4708            throw new SecurityException(msg);
4709        }
4710        final int callingPid = Binder.getCallingPid();
4711        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4712                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4713        long callingId = Binder.clearCallingIdentity();
4714        try {
4715            IPackageManager pm = AppGlobals.getPackageManager();
4716            synchronized(this) {
4717                int[] users = userId == UserHandle.USER_ALL
4718                        ? getUsersLocked() : new int[] { userId };
4719                for (int user : users) {
4720                    int pkgUid = -1;
4721                    try {
4722                        pkgUid = pm.getPackageUid(packageName, user);
4723                    } catch (RemoteException e) {
4724                    }
4725                    if (pkgUid == -1) {
4726                        Slog.w(TAG, "Invalid packageName: " + packageName);
4727                        continue;
4728                    }
4729                    try {
4730                        pm.setPackageStoppedState(packageName, true, user);
4731                    } catch (RemoteException e) {
4732                    } catch (IllegalArgumentException e) {
4733                        Slog.w(TAG, "Failed trying to unstop package "
4734                                + packageName + ": " + e);
4735                    }
4736                    if (isUserRunningLocked(user, false)) {
4737                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4738                    }
4739                }
4740            }
4741        } finally {
4742            Binder.restoreCallingIdentity(callingId);
4743        }
4744    }
4745
4746    @Override
4747    public void addPackageDependency(String packageName) {
4748        synchronized (this) {
4749            int callingPid = Binder.getCallingPid();
4750            if (callingPid == Process.myPid()) {
4751                //  Yeah, um, no.
4752                Slog.w(TAG, "Can't addPackageDependency on system process");
4753                return;
4754            }
4755            ProcessRecord proc;
4756            synchronized (mPidsSelfLocked) {
4757                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4758            }
4759            if (proc != null) {
4760                if (proc.pkgDeps == null) {
4761                    proc.pkgDeps = new ArraySet<String>(1);
4762                }
4763                proc.pkgDeps.add(packageName);
4764            }
4765        }
4766    }
4767
4768    /*
4769     * The pkg name and app id have to be specified.
4770     */
4771    @Override
4772    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4773        if (pkg == null) {
4774            return;
4775        }
4776        // Make sure the uid is valid.
4777        if (appid < 0) {
4778            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4779            return;
4780        }
4781        int callerUid = Binder.getCallingUid();
4782        // Only the system server can kill an application
4783        if (callerUid == Process.SYSTEM_UID) {
4784            // Post an aysnc message to kill the application
4785            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4786            msg.arg1 = appid;
4787            msg.arg2 = 0;
4788            Bundle bundle = new Bundle();
4789            bundle.putString("pkg", pkg);
4790            bundle.putString("reason", reason);
4791            msg.obj = bundle;
4792            mHandler.sendMessage(msg);
4793        } else {
4794            throw new SecurityException(callerUid + " cannot kill pkg: " +
4795                    pkg);
4796        }
4797    }
4798
4799    @Override
4800    public void closeSystemDialogs(String reason) {
4801        enforceNotIsolatedCaller("closeSystemDialogs");
4802
4803        final int pid = Binder.getCallingPid();
4804        final int uid = Binder.getCallingUid();
4805        final long origId = Binder.clearCallingIdentity();
4806        try {
4807            synchronized (this) {
4808                // Only allow this from foreground processes, so that background
4809                // applications can't abuse it to prevent system UI from being shown.
4810                if (uid >= Process.FIRST_APPLICATION_UID) {
4811                    ProcessRecord proc;
4812                    synchronized (mPidsSelfLocked) {
4813                        proc = mPidsSelfLocked.get(pid);
4814                    }
4815                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4816                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4817                                + " from background process " + proc);
4818                        return;
4819                    }
4820                }
4821                closeSystemDialogsLocked(reason);
4822            }
4823        } finally {
4824            Binder.restoreCallingIdentity(origId);
4825        }
4826    }
4827
4828    void closeSystemDialogsLocked(String reason) {
4829        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4830        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4831                | Intent.FLAG_RECEIVER_FOREGROUND);
4832        if (reason != null) {
4833            intent.putExtra("reason", reason);
4834        }
4835        mWindowManager.closeSystemDialogs(reason);
4836
4837        mStackSupervisor.closeSystemDialogsLocked();
4838
4839        broadcastIntentLocked(null, null, intent, null,
4840                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4841                Process.SYSTEM_UID, UserHandle.USER_ALL);
4842    }
4843
4844    @Override
4845    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4846        enforceNotIsolatedCaller("getProcessMemoryInfo");
4847        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4848        for (int i=pids.length-1; i>=0; i--) {
4849            ProcessRecord proc;
4850            int oomAdj;
4851            synchronized (this) {
4852                synchronized (mPidsSelfLocked) {
4853                    proc = mPidsSelfLocked.get(pids[i]);
4854                    oomAdj = proc != null ? proc.setAdj : 0;
4855                }
4856            }
4857            infos[i] = new Debug.MemoryInfo();
4858            Debug.getMemoryInfo(pids[i], infos[i]);
4859            if (proc != null) {
4860                synchronized (this) {
4861                    if (proc.thread != null && proc.setAdj == oomAdj) {
4862                        // Record this for posterity if the process has been stable.
4863                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4864                                infos[i].getTotalUss(), false, proc.pkgList);
4865                    }
4866                }
4867            }
4868        }
4869        return infos;
4870    }
4871
4872    @Override
4873    public long[] getProcessPss(int[] pids) {
4874        enforceNotIsolatedCaller("getProcessPss");
4875        long[] pss = new long[pids.length];
4876        for (int i=pids.length-1; i>=0; i--) {
4877            ProcessRecord proc;
4878            int oomAdj;
4879            synchronized (this) {
4880                synchronized (mPidsSelfLocked) {
4881                    proc = mPidsSelfLocked.get(pids[i]);
4882                    oomAdj = proc != null ? proc.setAdj : 0;
4883                }
4884            }
4885            long[] tmpUss = new long[1];
4886            pss[i] = Debug.getPss(pids[i], tmpUss);
4887            if (proc != null) {
4888                synchronized (this) {
4889                    if (proc.thread != null && proc.setAdj == oomAdj) {
4890                        // Record this for posterity if the process has been stable.
4891                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4892                    }
4893                }
4894            }
4895        }
4896        return pss;
4897    }
4898
4899    @Override
4900    public void killApplicationProcess(String processName, int uid) {
4901        if (processName == null) {
4902            return;
4903        }
4904
4905        int callerUid = Binder.getCallingUid();
4906        // Only the system server can kill an application
4907        if (callerUid == Process.SYSTEM_UID) {
4908            synchronized (this) {
4909                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4910                if (app != null && app.thread != null) {
4911                    try {
4912                        app.thread.scheduleSuicide();
4913                    } catch (RemoteException e) {
4914                        // If the other end already died, then our work here is done.
4915                    }
4916                } else {
4917                    Slog.w(TAG, "Process/uid not found attempting kill of "
4918                            + processName + " / " + uid);
4919                }
4920            }
4921        } else {
4922            throw new SecurityException(callerUid + " cannot kill app process: " +
4923                    processName);
4924        }
4925    }
4926
4927    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4928        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4929                false, true, false, false, UserHandle.getUserId(uid), reason);
4930        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4931                Uri.fromParts("package", packageName, null));
4932        if (!mProcessesReady) {
4933            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4934                    | Intent.FLAG_RECEIVER_FOREGROUND);
4935        }
4936        intent.putExtra(Intent.EXTRA_UID, uid);
4937        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4938        broadcastIntentLocked(null, null, intent,
4939                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4940                false, false,
4941                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4942    }
4943
4944    private void forceStopUserLocked(int userId, String reason) {
4945        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4946        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4947        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4948                | Intent.FLAG_RECEIVER_FOREGROUND);
4949        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4950        broadcastIntentLocked(null, null, intent,
4951                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4952                false, false,
4953                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4954    }
4955
4956    private final boolean killPackageProcessesLocked(String packageName, int appId,
4957            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4958            boolean doit, boolean evenPersistent, String reason) {
4959        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4960
4961        // Remove all processes this package may have touched: all with the
4962        // same UID (except for the system or root user), and all whose name
4963        // matches the package name.
4964        final int NP = mProcessNames.getMap().size();
4965        for (int ip=0; ip<NP; ip++) {
4966            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4967            final int NA = apps.size();
4968            for (int ia=0; ia<NA; ia++) {
4969                ProcessRecord app = apps.valueAt(ia);
4970                if (app.persistent && !evenPersistent) {
4971                    // we don't kill persistent processes
4972                    continue;
4973                }
4974                if (app.removed) {
4975                    if (doit) {
4976                        procs.add(app);
4977                    }
4978                    continue;
4979                }
4980
4981                // Skip process if it doesn't meet our oom adj requirement.
4982                if (app.setAdj < minOomAdj) {
4983                    continue;
4984                }
4985
4986                // If no package is specified, we call all processes under the
4987                // give user id.
4988                if (packageName == null) {
4989                    if (app.userId != userId) {
4990                        continue;
4991                    }
4992                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4993                        continue;
4994                    }
4995                // Package has been specified, we want to hit all processes
4996                // that match it.  We need to qualify this by the processes
4997                // that are running under the specified app and user ID.
4998                } else {
4999                    final boolean isDep = app.pkgDeps != null
5000                            && app.pkgDeps.contains(packageName);
5001                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5002                        continue;
5003                    }
5004                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5005                        continue;
5006                    }
5007                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5008                        continue;
5009                    }
5010                }
5011
5012                // Process has passed all conditions, kill it!
5013                if (!doit) {
5014                    return true;
5015                }
5016                app.removed = true;
5017                procs.add(app);
5018            }
5019        }
5020
5021        int N = procs.size();
5022        for (int i=0; i<N; i++) {
5023            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5024        }
5025        updateOomAdjLocked();
5026        return N > 0;
5027    }
5028
5029    private final boolean forceStopPackageLocked(String name, int appId,
5030            boolean callerWillRestart, boolean purgeCache, boolean doit,
5031            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5032        int i;
5033        int N;
5034
5035        if (userId == UserHandle.USER_ALL && name == null) {
5036            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5037        }
5038
5039        if (appId < 0 && name != null) {
5040            try {
5041                appId = UserHandle.getAppId(
5042                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5043            } catch (RemoteException e) {
5044            }
5045        }
5046
5047        if (doit) {
5048            if (name != null) {
5049                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5050                        + " user=" + userId + ": " + reason);
5051            } else {
5052                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5053            }
5054
5055            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5056            for (int ip=pmap.size()-1; ip>=0; ip--) {
5057                SparseArray<Long> ba = pmap.valueAt(ip);
5058                for (i=ba.size()-1; i>=0; i--) {
5059                    boolean remove = false;
5060                    final int entUid = ba.keyAt(i);
5061                    if (name != null) {
5062                        if (userId == UserHandle.USER_ALL) {
5063                            if (UserHandle.getAppId(entUid) == appId) {
5064                                remove = true;
5065                            }
5066                        } else {
5067                            if (entUid == UserHandle.getUid(userId, appId)) {
5068                                remove = true;
5069                            }
5070                        }
5071                    } else if (UserHandle.getUserId(entUid) == userId) {
5072                        remove = true;
5073                    }
5074                    if (remove) {
5075                        ba.removeAt(i);
5076                    }
5077                }
5078                if (ba.size() == 0) {
5079                    pmap.removeAt(ip);
5080                }
5081            }
5082        }
5083
5084        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5085                -100, callerWillRestart, true, doit, evenPersistent,
5086                name == null ? ("stop user " + userId) : ("stop " + name));
5087
5088        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5089            if (!doit) {
5090                return true;
5091            }
5092            didSomething = true;
5093        }
5094
5095        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5096            if (!doit) {
5097                return true;
5098            }
5099            didSomething = true;
5100        }
5101
5102        if (name == null) {
5103            // Remove all sticky broadcasts from this user.
5104            mStickyBroadcasts.remove(userId);
5105        }
5106
5107        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5108        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5109                userId, providers)) {
5110            if (!doit) {
5111                return true;
5112            }
5113            didSomething = true;
5114        }
5115        N = providers.size();
5116        for (i=0; i<N; i++) {
5117            removeDyingProviderLocked(null, providers.get(i), true);
5118        }
5119
5120        // Remove transient permissions granted from/to this package/user
5121        removeUriPermissionsForPackageLocked(name, userId, false);
5122
5123        if (name == null || uninstalling) {
5124            // Remove pending intents.  For now we only do this when force
5125            // stopping users, because we have some problems when doing this
5126            // for packages -- app widgets are not currently cleaned up for
5127            // such packages, so they can be left with bad pending intents.
5128            if (mIntentSenderRecords.size() > 0) {
5129                Iterator<WeakReference<PendingIntentRecord>> it
5130                        = mIntentSenderRecords.values().iterator();
5131                while (it.hasNext()) {
5132                    WeakReference<PendingIntentRecord> wpir = it.next();
5133                    if (wpir == null) {
5134                        it.remove();
5135                        continue;
5136                    }
5137                    PendingIntentRecord pir = wpir.get();
5138                    if (pir == null) {
5139                        it.remove();
5140                        continue;
5141                    }
5142                    if (name == null) {
5143                        // Stopping user, remove all objects for the user.
5144                        if (pir.key.userId != userId) {
5145                            // Not the same user, skip it.
5146                            continue;
5147                        }
5148                    } else {
5149                        if (UserHandle.getAppId(pir.uid) != appId) {
5150                            // Different app id, skip it.
5151                            continue;
5152                        }
5153                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5154                            // Different user, skip it.
5155                            continue;
5156                        }
5157                        if (!pir.key.packageName.equals(name)) {
5158                            // Different package, skip it.
5159                            continue;
5160                        }
5161                    }
5162                    if (!doit) {
5163                        return true;
5164                    }
5165                    didSomething = true;
5166                    it.remove();
5167                    pir.canceled = true;
5168                    if (pir.key.activity != null) {
5169                        pir.key.activity.pendingResults.remove(pir.ref);
5170                    }
5171                }
5172            }
5173        }
5174
5175        if (doit) {
5176            if (purgeCache && name != null) {
5177                AttributeCache ac = AttributeCache.instance();
5178                if (ac != null) {
5179                    ac.removePackage(name);
5180                }
5181            }
5182            if (mBooted) {
5183                mStackSupervisor.resumeTopActivitiesLocked();
5184                mStackSupervisor.scheduleIdleLocked();
5185            }
5186        }
5187
5188        return didSomething;
5189    }
5190
5191    private final boolean removeProcessLocked(ProcessRecord app,
5192            boolean callerWillRestart, boolean allowRestart, String reason) {
5193        final String name = app.processName;
5194        final int uid = app.uid;
5195        if (DEBUG_PROCESSES) Slog.d(
5196            TAG, "Force removing proc " + app.toShortString() + " (" + name
5197            + "/" + uid + ")");
5198
5199        mProcessNames.remove(name, uid);
5200        mIsolatedProcesses.remove(app.uid);
5201        if (mHeavyWeightProcess == app) {
5202            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5203                    mHeavyWeightProcess.userId, 0));
5204            mHeavyWeightProcess = null;
5205        }
5206        boolean needRestart = false;
5207        if (app.pid > 0 && app.pid != MY_PID) {
5208            int pid = app.pid;
5209            synchronized (mPidsSelfLocked) {
5210                mPidsSelfLocked.remove(pid);
5211                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5212            }
5213            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5214            if (app.isolated) {
5215                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5216            }
5217            killUnneededProcessLocked(app, reason);
5218            Process.killProcessGroup(app.info.uid, app.pid);
5219            handleAppDiedLocked(app, true, allowRestart);
5220            removeLruProcessLocked(app);
5221
5222            if (app.persistent && !app.isolated) {
5223                if (!callerWillRestart) {
5224                    addAppLocked(app.info, false, null /* ABI override */);
5225                } else {
5226                    needRestart = true;
5227                }
5228            }
5229        } else {
5230            mRemovedProcesses.add(app);
5231        }
5232
5233        return needRestart;
5234    }
5235
5236    private final void processStartTimedOutLocked(ProcessRecord app) {
5237        final int pid = app.pid;
5238        boolean gone = false;
5239        synchronized (mPidsSelfLocked) {
5240            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5241            if (knownApp != null && knownApp.thread == null) {
5242                mPidsSelfLocked.remove(pid);
5243                gone = true;
5244            }
5245        }
5246
5247        if (gone) {
5248            Slog.w(TAG, "Process " + app + " failed to attach");
5249            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5250                    pid, app.uid, app.processName);
5251            mProcessNames.remove(app.processName, app.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            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5259            if (app.isolated) {
5260                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5261            }
5262            // Take care of any launching providers waiting for this process.
5263            checkAppInLaunchingProvidersLocked(app, true);
5264            // Take care of any services that are waiting for the process.
5265            mServices.processStartTimedOutLocked(app);
5266            killUnneededProcessLocked(app, "start timeout");
5267            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5268                Slog.w(TAG, "Unattached app died before backup, skipping");
5269                try {
5270                    IBackupManager bm = IBackupManager.Stub.asInterface(
5271                            ServiceManager.getService(Context.BACKUP_SERVICE));
5272                    bm.agentDisconnected(app.info.packageName);
5273                } catch (RemoteException e) {
5274                    // Can't happen; the backup manager is local
5275                }
5276            }
5277            if (isPendingBroadcastProcessLocked(pid)) {
5278                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5279                skipPendingBroadcastLocked(pid);
5280            }
5281        } else {
5282            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5283        }
5284    }
5285
5286    private final boolean attachApplicationLocked(IApplicationThread thread,
5287            int pid) {
5288
5289        // Find the application record that is being attached...  either via
5290        // the pid if we are running in multiple processes, or just pull the
5291        // next app record if we are emulating process with anonymous threads.
5292        ProcessRecord app;
5293        if (pid != MY_PID && pid >= 0) {
5294            synchronized (mPidsSelfLocked) {
5295                app = mPidsSelfLocked.get(pid);
5296            }
5297        } else {
5298            app = null;
5299        }
5300
5301        if (app == null) {
5302            Slog.w(TAG, "No pending application record for pid " + pid
5303                    + " (IApplicationThread " + thread + "); dropping process");
5304            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5305            if (pid > 0 && pid != MY_PID) {
5306                Process.killProcessQuiet(pid);
5307                //TODO: Process.killProcessGroup(app.info.uid, pid);
5308            } else {
5309                try {
5310                    thread.scheduleExit();
5311                } catch (Exception e) {
5312                    // Ignore exceptions.
5313                }
5314            }
5315            return false;
5316        }
5317
5318        // If this application record is still attached to a previous
5319        // process, clean it up now.
5320        if (app.thread != null) {
5321            handleAppDiedLocked(app, true, true);
5322        }
5323
5324        // Tell the process all about itself.
5325
5326        if (localLOGV) Slog.v(
5327                TAG, "Binding process pid " + pid + " to record " + app);
5328
5329        final String processName = app.processName;
5330        try {
5331            AppDeathRecipient adr = new AppDeathRecipient(
5332                    app, pid, thread);
5333            thread.asBinder().linkToDeath(adr, 0);
5334            app.deathRecipient = adr;
5335        } catch (RemoteException e) {
5336            app.resetPackageList(mProcessStats);
5337            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5338            return false;
5339        }
5340
5341        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5342
5343        app.makeActive(thread, mProcessStats);
5344        app.curAdj = app.setAdj = -100;
5345        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5346        app.forcingToForeground = null;
5347        updateProcessForegroundLocked(app, false, false);
5348        app.hasShownUi = false;
5349        app.debugging = false;
5350        app.cached = false;
5351
5352        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5353
5354        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5355        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5356
5357        if (!normalMode) {
5358            Slog.i(TAG, "Launching preboot mode app: " + app);
5359        }
5360
5361        if (localLOGV) Slog.v(
5362            TAG, "New app record " + app
5363            + " thread=" + thread.asBinder() + " pid=" + pid);
5364        try {
5365            int testMode = IApplicationThread.DEBUG_OFF;
5366            if (mDebugApp != null && mDebugApp.equals(processName)) {
5367                testMode = mWaitForDebugger
5368                    ? IApplicationThread.DEBUG_WAIT
5369                    : IApplicationThread.DEBUG_ON;
5370                app.debugging = true;
5371                if (mDebugTransient) {
5372                    mDebugApp = mOrigDebugApp;
5373                    mWaitForDebugger = mOrigWaitForDebugger;
5374                }
5375            }
5376            String profileFile = app.instrumentationProfileFile;
5377            ParcelFileDescriptor profileFd = null;
5378            boolean profileAutoStop = false;
5379            if (mProfileApp != null && mProfileApp.equals(processName)) {
5380                mProfileProc = app;
5381                profileFile = mProfileFile;
5382                profileFd = mProfileFd;
5383                profileAutoStop = mAutoStopProfiler;
5384            }
5385            boolean enableOpenGlTrace = false;
5386            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5387                enableOpenGlTrace = true;
5388                mOpenGlTraceApp = null;
5389            }
5390
5391            // If the app is being launched for restore or full backup, set it up specially
5392            boolean isRestrictedBackupMode = false;
5393            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5394                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5395                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5396                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5397            }
5398
5399            ensurePackageDexOpt(app.instrumentationInfo != null
5400                    ? app.instrumentationInfo.packageName
5401                    : app.info.packageName);
5402            if (app.instrumentationClass != null) {
5403                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5404            }
5405            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5406                    + processName + " with config " + mConfiguration);
5407            ApplicationInfo appInfo = app.instrumentationInfo != null
5408                    ? app.instrumentationInfo : app.info;
5409            app.compat = compatibilityInfoForPackageLocked(appInfo);
5410            if (profileFd != null) {
5411                profileFd = profileFd.dup();
5412            }
5413            thread.bindApplication(processName, appInfo, providers,
5414                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5415                    app.instrumentationArguments, app.instrumentationWatcher,
5416                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5417                    isRestrictedBackupMode || !normalMode, app.persistent,
5418                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5419                    mCoreSettingsObserver.getCoreSettingsLocked());
5420            updateLruProcessLocked(app, false, null);
5421            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5422        } catch (Exception e) {
5423            // todo: Yikes!  What should we do?  For now we will try to
5424            // start another process, but that could easily get us in
5425            // an infinite loop of restarting processes...
5426            Slog.w(TAG, "Exception thrown during bind!", e);
5427
5428            app.resetPackageList(mProcessStats);
5429            app.unlinkDeathRecipient();
5430            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5431            return false;
5432        }
5433
5434        // Remove this record from the list of starting applications.
5435        mPersistentStartingProcesses.remove(app);
5436        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5437                "Attach application locked removing on hold: " + app);
5438        mProcessesOnHold.remove(app);
5439
5440        boolean badApp = false;
5441        boolean didSomething = false;
5442
5443        // See if the top visible activity is waiting to run in this process...
5444        if (normalMode) {
5445            try {
5446                if (mStackSupervisor.attachApplicationLocked(app)) {
5447                    didSomething = true;
5448                }
5449            } catch (Exception e) {
5450                badApp = true;
5451            }
5452        }
5453
5454        // Find any services that should be running in this process...
5455        if (!badApp) {
5456            try {
5457                didSomething |= mServices.attachApplicationLocked(app, processName);
5458            } catch (Exception e) {
5459                badApp = true;
5460            }
5461        }
5462
5463        // Check if a next-broadcast receiver is in this process...
5464        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5465            try {
5466                didSomething |= sendPendingBroadcastsLocked(app);
5467            } catch (Exception e) {
5468                // If the app died trying to launch the receiver we declare it 'bad'
5469                badApp = true;
5470            }
5471        }
5472
5473        // Check whether the next backup agent is in this process...
5474        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5475            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5476            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5477            try {
5478                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5479                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5480                        mBackupTarget.backupMode);
5481            } catch (Exception e) {
5482                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5483                e.printStackTrace();
5484            }
5485        }
5486
5487        if (badApp) {
5488            // todo: Also need to kill application to deal with all
5489            // kinds of exceptions.
5490            handleAppDiedLocked(app, false, true);
5491            return false;
5492        }
5493
5494        if (!didSomething) {
5495            updateOomAdjLocked();
5496        }
5497
5498        return true;
5499    }
5500
5501    @Override
5502    public final void attachApplication(IApplicationThread thread) {
5503        synchronized (this) {
5504            int callingPid = Binder.getCallingPid();
5505            final long origId = Binder.clearCallingIdentity();
5506            attachApplicationLocked(thread, callingPid);
5507            Binder.restoreCallingIdentity(origId);
5508        }
5509    }
5510
5511    @Override
5512    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5513        final long origId = Binder.clearCallingIdentity();
5514        synchronized (this) {
5515            ActivityStack stack = ActivityRecord.getStackLocked(token);
5516            if (stack != null) {
5517                ActivityRecord r =
5518                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5519                if (stopProfiling) {
5520                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5521                        try {
5522                            mProfileFd.close();
5523                        } catch (IOException e) {
5524                        }
5525                        clearProfilerLocked();
5526                    }
5527                }
5528            }
5529        }
5530        Binder.restoreCallingIdentity(origId);
5531    }
5532
5533    void postEnableScreenAfterBootLocked() {
5534        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
5535    }
5536
5537    void enableScreenAfterBoot() {
5538        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5539                SystemClock.uptimeMillis());
5540        mWindowManager.enableScreenAfterBoot();
5541
5542        synchronized (this) {
5543            updateEventDispatchingLocked();
5544        }
5545    }
5546
5547    @Override
5548    public void showBootMessage(final CharSequence msg, final boolean always) {
5549        enforceNotIsolatedCaller("showBootMessage");
5550        mWindowManager.showBootMessage(msg, always);
5551    }
5552
5553    @Override
5554    public void dismissKeyguardOnNextActivity() {
5555        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5556        final long token = Binder.clearCallingIdentity();
5557        try {
5558            synchronized (this) {
5559                if (DEBUG_LOCKSCREEN) logLockScreen("");
5560                if (mLockScreenShown) {
5561                    mLockScreenShown = false;
5562                    comeOutOfSleepIfNeededLocked();
5563                }
5564                mStackSupervisor.setDismissKeyguard(true);
5565            }
5566        } finally {
5567            Binder.restoreCallingIdentity(token);
5568        }
5569    }
5570
5571    final void finishBooting() {
5572        // Register receivers to handle package update events
5573        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5574
5575        synchronized (this) {
5576            // Ensure that any processes we had put on hold are now started
5577            // up.
5578            final int NP = mProcessesOnHold.size();
5579            if (NP > 0) {
5580                ArrayList<ProcessRecord> procs =
5581                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5582                for (int ip=0; ip<NP; ip++) {
5583                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5584                            + procs.get(ip));
5585                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5586                }
5587            }
5588
5589            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5590                // Start looking for apps that are abusing wake locks.
5591                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5592                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5593                // Tell anyone interested that we are done booting!
5594                SystemProperties.set("sys.boot_completed", "1");
5595                SystemProperties.set("dev.bootcomplete", "1");
5596                for (int i=0; i<mStartedUsers.size(); i++) {
5597                    UserStartedState uss = mStartedUsers.valueAt(i);
5598                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5599                        uss.mState = UserStartedState.STATE_RUNNING;
5600                        final int userId = mStartedUsers.keyAt(i);
5601                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5602                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5603                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5604                        broadcastIntentLocked(null, null, intent, null,
5605                                new IIntentReceiver.Stub() {
5606                                    @Override
5607                                    public void performReceive(Intent intent, int resultCode,
5608                                            String data, Bundle extras, boolean ordered,
5609                                            boolean sticky, int sendingUser) {
5610                                        synchronized (ActivityManagerService.this) {
5611                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5612                                                    true, false);
5613                                        }
5614                                    }
5615                                },
5616                                0, null, null,
5617                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5618                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5619                                userId);
5620                    }
5621                }
5622                scheduleStartProfilesLocked();
5623            }
5624        }
5625    }
5626
5627    final void ensureBootCompleted() {
5628        boolean booting;
5629        boolean enableScreen;
5630        synchronized (this) {
5631            booting = mBooting;
5632            mBooting = false;
5633            enableScreen = !mBooted;
5634            mBooted = true;
5635        }
5636
5637        if (booting) {
5638            finishBooting();
5639        }
5640
5641        if (enableScreen) {
5642            enableScreenAfterBoot();
5643        }
5644    }
5645
5646    @Override
5647    public final void activityResumed(IBinder token) {
5648        final long origId = Binder.clearCallingIdentity();
5649        synchronized(this) {
5650            ActivityStack stack = ActivityRecord.getStackLocked(token);
5651            if (stack != null) {
5652                ActivityRecord.activityResumedLocked(token);
5653            }
5654        }
5655        Binder.restoreCallingIdentity(origId);
5656    }
5657
5658    @Override
5659    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5660        final long origId = Binder.clearCallingIdentity();
5661        synchronized(this) {
5662            ActivityStack stack = ActivityRecord.getStackLocked(token);
5663            if (stack != null) {
5664                stack.activityPausedLocked(token, false, persistentState);
5665            }
5666        }
5667        Binder.restoreCallingIdentity(origId);
5668    }
5669
5670    @Override
5671    public final void activityStopped(IBinder token, Bundle icicle,
5672            PersistableBundle persistentState, CharSequence description) {
5673        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5674
5675        // Refuse possible leaked file descriptors
5676        if (icicle != null && icicle.hasFileDescriptors()) {
5677            throw new IllegalArgumentException("File descriptors passed in Bundle");
5678        }
5679
5680        final long origId = Binder.clearCallingIdentity();
5681
5682        synchronized (this) {
5683            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5684            if (r != null) {
5685                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5686            }
5687        }
5688
5689        trimApplications();
5690
5691        Binder.restoreCallingIdentity(origId);
5692    }
5693
5694    @Override
5695    public final void activityDestroyed(IBinder token) {
5696        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5697        synchronized (this) {
5698            ActivityStack stack = ActivityRecord.getStackLocked(token);
5699            if (stack != null) {
5700                stack.activityDestroyedLocked(token);
5701            }
5702        }
5703    }
5704
5705    @Override
5706    public final void mediaResourcesReleased(IBinder token) {
5707        final long origId = Binder.clearCallingIdentity();
5708        try {
5709            synchronized (this) {
5710                ActivityStack stack = ActivityRecord.getStackLocked(token);
5711                if (stack != null) {
5712                    stack.mediaResourcesReleased(token);
5713                }
5714            }
5715        } finally {
5716            Binder.restoreCallingIdentity(origId);
5717        }
5718    }
5719
5720    @Override
5721    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5722        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5723    }
5724
5725    @Override
5726    public final void notifyEnterAnimationComplete(IBinder token) {
5727        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5728    }
5729
5730    @Override
5731    public String getCallingPackage(IBinder token) {
5732        synchronized (this) {
5733            ActivityRecord r = getCallingRecordLocked(token);
5734            return r != null ? r.info.packageName : null;
5735        }
5736    }
5737
5738    @Override
5739    public ComponentName getCallingActivity(IBinder token) {
5740        synchronized (this) {
5741            ActivityRecord r = getCallingRecordLocked(token);
5742            return r != null ? r.intent.getComponent() : null;
5743        }
5744    }
5745
5746    private ActivityRecord getCallingRecordLocked(IBinder token) {
5747        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5748        if (r == null) {
5749            return null;
5750        }
5751        return r.resultTo;
5752    }
5753
5754    @Override
5755    public ComponentName getActivityClassForToken(IBinder token) {
5756        synchronized(this) {
5757            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5758            if (r == null) {
5759                return null;
5760            }
5761            return r.intent.getComponent();
5762        }
5763    }
5764
5765    @Override
5766    public String getPackageForToken(IBinder token) {
5767        synchronized(this) {
5768            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5769            if (r == null) {
5770                return null;
5771            }
5772            return r.packageName;
5773        }
5774    }
5775
5776    @Override
5777    public IIntentSender getIntentSender(int type,
5778            String packageName, IBinder token, String resultWho,
5779            int requestCode, Intent[] intents, String[] resolvedTypes,
5780            int flags, Bundle options, int userId) {
5781        enforceNotIsolatedCaller("getIntentSender");
5782        // Refuse possible leaked file descriptors
5783        if (intents != null) {
5784            if (intents.length < 1) {
5785                throw new IllegalArgumentException("Intents array length must be >= 1");
5786            }
5787            for (int i=0; i<intents.length; i++) {
5788                Intent intent = intents[i];
5789                if (intent != null) {
5790                    if (intent.hasFileDescriptors()) {
5791                        throw new IllegalArgumentException("File descriptors passed in Intent");
5792                    }
5793                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5794                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5795                        throw new IllegalArgumentException(
5796                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5797                    }
5798                    intents[i] = new Intent(intent);
5799                }
5800            }
5801            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5802                throw new IllegalArgumentException(
5803                        "Intent array length does not match resolvedTypes length");
5804            }
5805        }
5806        if (options != null) {
5807            if (options.hasFileDescriptors()) {
5808                throw new IllegalArgumentException("File descriptors passed in options");
5809            }
5810        }
5811
5812        synchronized(this) {
5813            int callingUid = Binder.getCallingUid();
5814            int origUserId = userId;
5815            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5816                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5817                    ALLOW_NON_FULL, "getIntentSender", null);
5818            if (origUserId == UserHandle.USER_CURRENT) {
5819                // We don't want to evaluate this until the pending intent is
5820                // actually executed.  However, we do want to always do the
5821                // security checking for it above.
5822                userId = UserHandle.USER_CURRENT;
5823            }
5824            try {
5825                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5826                    int uid = AppGlobals.getPackageManager()
5827                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5828                    if (!UserHandle.isSameApp(callingUid, uid)) {
5829                        String msg = "Permission Denial: getIntentSender() from pid="
5830                            + Binder.getCallingPid()
5831                            + ", uid=" + Binder.getCallingUid()
5832                            + ", (need uid=" + uid + ")"
5833                            + " is not allowed to send as package " + packageName;
5834                        Slog.w(TAG, msg);
5835                        throw new SecurityException(msg);
5836                    }
5837                }
5838
5839                return getIntentSenderLocked(type, packageName, callingUid, userId,
5840                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5841
5842            } catch (RemoteException e) {
5843                throw new SecurityException(e);
5844            }
5845        }
5846    }
5847
5848    IIntentSender getIntentSenderLocked(int type, String packageName,
5849            int callingUid, int userId, IBinder token, String resultWho,
5850            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5851            Bundle options) {
5852        if (DEBUG_MU)
5853            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5854        ActivityRecord activity = null;
5855        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5856            activity = ActivityRecord.isInStackLocked(token);
5857            if (activity == null) {
5858                return null;
5859            }
5860            if (activity.finishing) {
5861                return null;
5862            }
5863        }
5864
5865        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5866        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5867        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5868        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5869                |PendingIntent.FLAG_UPDATE_CURRENT);
5870
5871        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5872                type, packageName, activity, resultWho,
5873                requestCode, intents, resolvedTypes, flags, options, userId);
5874        WeakReference<PendingIntentRecord> ref;
5875        ref = mIntentSenderRecords.get(key);
5876        PendingIntentRecord rec = ref != null ? ref.get() : null;
5877        if (rec != null) {
5878            if (!cancelCurrent) {
5879                if (updateCurrent) {
5880                    if (rec.key.requestIntent != null) {
5881                        rec.key.requestIntent.replaceExtras(intents != null ?
5882                                intents[intents.length - 1] : null);
5883                    }
5884                    if (intents != null) {
5885                        intents[intents.length-1] = rec.key.requestIntent;
5886                        rec.key.allIntents = intents;
5887                        rec.key.allResolvedTypes = resolvedTypes;
5888                    } else {
5889                        rec.key.allIntents = null;
5890                        rec.key.allResolvedTypes = null;
5891                    }
5892                }
5893                return rec;
5894            }
5895            rec.canceled = true;
5896            mIntentSenderRecords.remove(key);
5897        }
5898        if (noCreate) {
5899            return rec;
5900        }
5901        rec = new PendingIntentRecord(this, key, callingUid);
5902        mIntentSenderRecords.put(key, rec.ref);
5903        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5904            if (activity.pendingResults == null) {
5905                activity.pendingResults
5906                        = new HashSet<WeakReference<PendingIntentRecord>>();
5907            }
5908            activity.pendingResults.add(rec.ref);
5909        }
5910        return rec;
5911    }
5912
5913    @Override
5914    public void cancelIntentSender(IIntentSender sender) {
5915        if (!(sender instanceof PendingIntentRecord)) {
5916            return;
5917        }
5918        synchronized(this) {
5919            PendingIntentRecord rec = (PendingIntentRecord)sender;
5920            try {
5921                int uid = AppGlobals.getPackageManager()
5922                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5923                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5924                    String msg = "Permission Denial: cancelIntentSender() from pid="
5925                        + Binder.getCallingPid()
5926                        + ", uid=" + Binder.getCallingUid()
5927                        + " is not allowed to cancel packges "
5928                        + rec.key.packageName;
5929                    Slog.w(TAG, msg);
5930                    throw new SecurityException(msg);
5931                }
5932            } catch (RemoteException e) {
5933                throw new SecurityException(e);
5934            }
5935            cancelIntentSenderLocked(rec, true);
5936        }
5937    }
5938
5939    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5940        rec.canceled = true;
5941        mIntentSenderRecords.remove(rec.key);
5942        if (cleanActivity && rec.key.activity != null) {
5943            rec.key.activity.pendingResults.remove(rec.ref);
5944        }
5945    }
5946
5947    @Override
5948    public String getPackageForIntentSender(IIntentSender pendingResult) {
5949        if (!(pendingResult instanceof PendingIntentRecord)) {
5950            return null;
5951        }
5952        try {
5953            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5954            return res.key.packageName;
5955        } catch (ClassCastException e) {
5956        }
5957        return null;
5958    }
5959
5960    @Override
5961    public int getUidForIntentSender(IIntentSender sender) {
5962        if (sender instanceof PendingIntentRecord) {
5963            try {
5964                PendingIntentRecord res = (PendingIntentRecord)sender;
5965                return res.uid;
5966            } catch (ClassCastException e) {
5967            }
5968        }
5969        return -1;
5970    }
5971
5972    @Override
5973    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5974        if (!(pendingResult instanceof PendingIntentRecord)) {
5975            return false;
5976        }
5977        try {
5978            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5979            if (res.key.allIntents == null) {
5980                return false;
5981            }
5982            for (int i=0; i<res.key.allIntents.length; i++) {
5983                Intent intent = res.key.allIntents[i];
5984                if (intent.getPackage() != null && intent.getComponent() != null) {
5985                    return false;
5986                }
5987            }
5988            return true;
5989        } catch (ClassCastException e) {
5990        }
5991        return false;
5992    }
5993
5994    @Override
5995    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5996        if (!(pendingResult instanceof PendingIntentRecord)) {
5997            return false;
5998        }
5999        try {
6000            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6001            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6002                return true;
6003            }
6004            return false;
6005        } catch (ClassCastException e) {
6006        }
6007        return false;
6008    }
6009
6010    @Override
6011    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6012        if (!(pendingResult instanceof PendingIntentRecord)) {
6013            return null;
6014        }
6015        try {
6016            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6017            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6018        } catch (ClassCastException e) {
6019        }
6020        return null;
6021    }
6022
6023    @Override
6024    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6025        if (!(pendingResult instanceof PendingIntentRecord)) {
6026            return null;
6027        }
6028        try {
6029            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6030            Intent intent = res.key.requestIntent;
6031            if (intent != null) {
6032                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6033                        || res.lastTagPrefix.equals(prefix))) {
6034                    return res.lastTag;
6035                }
6036                res.lastTagPrefix = prefix;
6037                StringBuilder sb = new StringBuilder(128);
6038                if (prefix != null) {
6039                    sb.append(prefix);
6040                }
6041                if (intent.getAction() != null) {
6042                    sb.append(intent.getAction());
6043                } else if (intent.getComponent() != null) {
6044                    intent.getComponent().appendShortString(sb);
6045                } else {
6046                    sb.append("?");
6047                }
6048                return res.lastTag = sb.toString();
6049            }
6050        } catch (ClassCastException e) {
6051        }
6052        return null;
6053    }
6054
6055    @Override
6056    public void setProcessLimit(int max) {
6057        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6058                "setProcessLimit()");
6059        synchronized (this) {
6060            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6061            mProcessLimitOverride = max;
6062        }
6063        trimApplications();
6064    }
6065
6066    @Override
6067    public int getProcessLimit() {
6068        synchronized (this) {
6069            return mProcessLimitOverride;
6070        }
6071    }
6072
6073    void foregroundTokenDied(ForegroundToken token) {
6074        synchronized (ActivityManagerService.this) {
6075            synchronized (mPidsSelfLocked) {
6076                ForegroundToken cur
6077                    = mForegroundProcesses.get(token.pid);
6078                if (cur != token) {
6079                    return;
6080                }
6081                mForegroundProcesses.remove(token.pid);
6082                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6083                if (pr == null) {
6084                    return;
6085                }
6086                pr.forcingToForeground = null;
6087                updateProcessForegroundLocked(pr, false, false);
6088            }
6089            updateOomAdjLocked();
6090        }
6091    }
6092
6093    @Override
6094    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6095        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6096                "setProcessForeground()");
6097        synchronized(this) {
6098            boolean changed = false;
6099
6100            synchronized (mPidsSelfLocked) {
6101                ProcessRecord pr = mPidsSelfLocked.get(pid);
6102                if (pr == null && isForeground) {
6103                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6104                    return;
6105                }
6106                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6107                if (oldToken != null) {
6108                    oldToken.token.unlinkToDeath(oldToken, 0);
6109                    mForegroundProcesses.remove(pid);
6110                    if (pr != null) {
6111                        pr.forcingToForeground = null;
6112                    }
6113                    changed = true;
6114                }
6115                if (isForeground && token != null) {
6116                    ForegroundToken newToken = new ForegroundToken() {
6117                        @Override
6118                        public void binderDied() {
6119                            foregroundTokenDied(this);
6120                        }
6121                    };
6122                    newToken.pid = pid;
6123                    newToken.token = token;
6124                    try {
6125                        token.linkToDeath(newToken, 0);
6126                        mForegroundProcesses.put(pid, newToken);
6127                        pr.forcingToForeground = token;
6128                        changed = true;
6129                    } catch (RemoteException e) {
6130                        // If the process died while doing this, we will later
6131                        // do the cleanup with the process death link.
6132                    }
6133                }
6134            }
6135
6136            if (changed) {
6137                updateOomAdjLocked();
6138            }
6139        }
6140    }
6141
6142    // =========================================================
6143    // PERMISSIONS
6144    // =========================================================
6145
6146    static class PermissionController extends IPermissionController.Stub {
6147        ActivityManagerService mActivityManagerService;
6148        PermissionController(ActivityManagerService activityManagerService) {
6149            mActivityManagerService = activityManagerService;
6150        }
6151
6152        @Override
6153        public boolean checkPermission(String permission, int pid, int uid) {
6154            return mActivityManagerService.checkPermission(permission, pid,
6155                    uid) == PackageManager.PERMISSION_GRANTED;
6156        }
6157    }
6158
6159    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6160        @Override
6161        public int checkComponentPermission(String permission, int pid, int uid,
6162                int owningUid, boolean exported) {
6163            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6164                    owningUid, exported);
6165        }
6166
6167        @Override
6168        public Object getAMSLock() {
6169            return ActivityManagerService.this;
6170        }
6171    }
6172
6173    /**
6174     * This can be called with or without the global lock held.
6175     */
6176    int checkComponentPermission(String permission, int pid, int uid,
6177            int owningUid, boolean exported) {
6178        // We might be performing an operation on behalf of an indirect binder
6179        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6180        // client identity accordingly before proceeding.
6181        Identity tlsIdentity = sCallerIdentity.get();
6182        if (tlsIdentity != null) {
6183            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6184                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6185            uid = tlsIdentity.uid;
6186            pid = tlsIdentity.pid;
6187        }
6188
6189        if (pid == MY_PID) {
6190            return PackageManager.PERMISSION_GRANTED;
6191        }
6192
6193        return ActivityManager.checkComponentPermission(permission, uid,
6194                owningUid, exported);
6195    }
6196
6197    /**
6198     * As the only public entry point for permissions checking, this method
6199     * can enforce the semantic that requesting a check on a null global
6200     * permission is automatically denied.  (Internally a null permission
6201     * string is used when calling {@link #checkComponentPermission} in cases
6202     * when only uid-based security is needed.)
6203     *
6204     * This can be called with or without the global lock held.
6205     */
6206    @Override
6207    public int checkPermission(String permission, int pid, int uid) {
6208        if (permission == null) {
6209            return PackageManager.PERMISSION_DENIED;
6210        }
6211        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6212    }
6213
6214    /**
6215     * Binder IPC calls go through the public entry point.
6216     * This can be called with or without the global lock held.
6217     */
6218    int checkCallingPermission(String permission) {
6219        return checkPermission(permission,
6220                Binder.getCallingPid(),
6221                UserHandle.getAppId(Binder.getCallingUid()));
6222    }
6223
6224    /**
6225     * This can be called with or without the global lock held.
6226     */
6227    void enforceCallingPermission(String permission, String func) {
6228        if (checkCallingPermission(permission)
6229                == PackageManager.PERMISSION_GRANTED) {
6230            return;
6231        }
6232
6233        String msg = "Permission Denial: " + func + " from pid="
6234                + Binder.getCallingPid()
6235                + ", uid=" + Binder.getCallingUid()
6236                + " requires " + permission;
6237        Slog.w(TAG, msg);
6238        throw new SecurityException(msg);
6239    }
6240
6241    /**
6242     * Determine if UID is holding permissions required to access {@link Uri} in
6243     * the given {@link ProviderInfo}. Final permission checking is always done
6244     * in {@link ContentProvider}.
6245     */
6246    private final boolean checkHoldingPermissionsLocked(
6247            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6248        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6249                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6250        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6251            return false;
6252        }
6253        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6254    }
6255
6256    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6257            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6258        if (pi.applicationInfo.uid == uid) {
6259            return true;
6260        } else if (!pi.exported) {
6261            return false;
6262        }
6263
6264        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6265        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6266        try {
6267            // check if target holds top-level <provider> permissions
6268            if (!readMet && pi.readPermission != null && considerUidPermissions
6269                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6270                readMet = true;
6271            }
6272            if (!writeMet && pi.writePermission != null && considerUidPermissions
6273                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6274                writeMet = true;
6275            }
6276
6277            // track if unprotected read/write is allowed; any denied
6278            // <path-permission> below removes this ability
6279            boolean allowDefaultRead = pi.readPermission == null;
6280            boolean allowDefaultWrite = pi.writePermission == null;
6281
6282            // check if target holds any <path-permission> that match uri
6283            final PathPermission[] pps = pi.pathPermissions;
6284            if (pps != null) {
6285                final String path = grantUri.uri.getPath();
6286                int i = pps.length;
6287                while (i > 0 && (!readMet || !writeMet)) {
6288                    i--;
6289                    PathPermission pp = pps[i];
6290                    if (pp.match(path)) {
6291                        if (!readMet) {
6292                            final String pprperm = pp.getReadPermission();
6293                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6294                                    + pprperm + " for " + pp.getPath()
6295                                    + ": match=" + pp.match(path)
6296                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6297                            if (pprperm != null) {
6298                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6299                                        == PERMISSION_GRANTED) {
6300                                    readMet = true;
6301                                } else {
6302                                    allowDefaultRead = false;
6303                                }
6304                            }
6305                        }
6306                        if (!writeMet) {
6307                            final String ppwperm = pp.getWritePermission();
6308                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6309                                    + ppwperm + " for " + pp.getPath()
6310                                    + ": match=" + pp.match(path)
6311                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6312                            if (ppwperm != null) {
6313                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6314                                        == PERMISSION_GRANTED) {
6315                                    writeMet = true;
6316                                } else {
6317                                    allowDefaultWrite = false;
6318                                }
6319                            }
6320                        }
6321                    }
6322                }
6323            }
6324
6325            // grant unprotected <provider> read/write, if not blocked by
6326            // <path-permission> above
6327            if (allowDefaultRead) readMet = true;
6328            if (allowDefaultWrite) writeMet = true;
6329
6330        } catch (RemoteException e) {
6331            return false;
6332        }
6333
6334        return readMet && writeMet;
6335    }
6336
6337    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6338        ProviderInfo pi = null;
6339        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6340        if (cpr != null) {
6341            pi = cpr.info;
6342        } else {
6343            try {
6344                pi = AppGlobals.getPackageManager().resolveContentProvider(
6345                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6346            } catch (RemoteException ex) {
6347            }
6348        }
6349        return pi;
6350    }
6351
6352    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6353        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6354        if (targetUris != null) {
6355            return targetUris.get(grantUri);
6356        }
6357        return null;
6358    }
6359
6360    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6361            String targetPkg, int targetUid, GrantUri grantUri) {
6362        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6363        if (targetUris == null) {
6364            targetUris = Maps.newArrayMap();
6365            mGrantedUriPermissions.put(targetUid, targetUris);
6366        }
6367
6368        UriPermission perm = targetUris.get(grantUri);
6369        if (perm == null) {
6370            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6371            targetUris.put(grantUri, perm);
6372        }
6373
6374        return perm;
6375    }
6376
6377    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6378            final int modeFlags) {
6379        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6380        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6381                : UriPermission.STRENGTH_OWNED;
6382
6383        // Root gets to do everything.
6384        if (uid == 0) {
6385            return true;
6386        }
6387
6388        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6389        if (perms == null) return false;
6390
6391        // First look for exact match
6392        final UriPermission exactPerm = perms.get(grantUri);
6393        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6394            return true;
6395        }
6396
6397        // No exact match, look for prefixes
6398        final int N = perms.size();
6399        for (int i = 0; i < N; i++) {
6400            final UriPermission perm = perms.valueAt(i);
6401            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6402                    && perm.getStrength(modeFlags) >= minStrength) {
6403                return true;
6404            }
6405        }
6406
6407        return false;
6408    }
6409
6410    @Override
6411    public int checkUriPermission(Uri uri, int pid, int uid,
6412            final int modeFlags, int userId) {
6413        enforceNotIsolatedCaller("checkUriPermission");
6414
6415        // Another redirected-binder-call permissions check as in
6416        // {@link checkComponentPermission}.
6417        Identity tlsIdentity = sCallerIdentity.get();
6418        if (tlsIdentity != null) {
6419            uid = tlsIdentity.uid;
6420            pid = tlsIdentity.pid;
6421        }
6422
6423        // Our own process gets to do everything.
6424        if (pid == MY_PID) {
6425            return PackageManager.PERMISSION_GRANTED;
6426        }
6427        synchronized (this) {
6428            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6429                    ? PackageManager.PERMISSION_GRANTED
6430                    : PackageManager.PERMISSION_DENIED;
6431        }
6432    }
6433
6434    /**
6435     * Check if the targetPkg can be granted permission to access uri by
6436     * the callingUid using the given modeFlags.  Throws a security exception
6437     * if callingUid is not allowed to do this.  Returns the uid of the target
6438     * if the URI permission grant should be performed; returns -1 if it is not
6439     * needed (for example targetPkg already has permission to access the URI).
6440     * If you already know the uid of the target, you can supply it in
6441     * lastTargetUid else set that to -1.
6442     */
6443    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6444            final int modeFlags, int lastTargetUid) {
6445        if (!Intent.isAccessUriMode(modeFlags)) {
6446            return -1;
6447        }
6448
6449        if (targetPkg != null) {
6450            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6451                    "Checking grant " + targetPkg + " permission to " + grantUri);
6452        }
6453
6454        final IPackageManager pm = AppGlobals.getPackageManager();
6455
6456        // If this is not a content: uri, we can't do anything with it.
6457        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6458            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6459                    "Can't grant URI permission for non-content URI: " + grantUri);
6460            return -1;
6461        }
6462
6463        final String authority = grantUri.uri.getAuthority();
6464        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6465        if (pi == null) {
6466            Slog.w(TAG, "No content provider found for permission check: " +
6467                    grantUri.uri.toSafeString());
6468            return -1;
6469        }
6470
6471        int targetUid = lastTargetUid;
6472        if (targetUid < 0 && targetPkg != null) {
6473            try {
6474                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6475                if (targetUid < 0) {
6476                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6477                            "Can't grant URI permission no uid for: " + targetPkg);
6478                    return -1;
6479                }
6480            } catch (RemoteException ex) {
6481                return -1;
6482            }
6483        }
6484
6485        if (targetUid >= 0) {
6486            // First...  does the target actually need this permission?
6487            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6488                // No need to grant the target this permission.
6489                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6490                        "Target " + targetPkg + " already has full permission to " + grantUri);
6491                return -1;
6492            }
6493        } else {
6494            // First...  there is no target package, so can anyone access it?
6495            boolean allowed = pi.exported;
6496            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6497                if (pi.readPermission != null) {
6498                    allowed = false;
6499                }
6500            }
6501            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6502                if (pi.writePermission != null) {
6503                    allowed = false;
6504                }
6505            }
6506            if (allowed) {
6507                return -1;
6508            }
6509        }
6510
6511        /* There is a special cross user grant if:
6512         * - The target is on another user.
6513         * - Apps on the current user can access the uri without any uid permissions.
6514         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6515         * grant uri permissions.
6516         */
6517        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6518                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6519                modeFlags, false /*without considering the uid permissions*/);
6520
6521        // Second...  is the provider allowing granting of URI permissions?
6522        if (!specialCrossUserGrant) {
6523            if (!pi.grantUriPermissions) {
6524                throw new SecurityException("Provider " + pi.packageName
6525                        + "/" + pi.name
6526                        + " does not allow granting of Uri permissions (uri "
6527                        + grantUri + ")");
6528            }
6529            if (pi.uriPermissionPatterns != null) {
6530                final int N = pi.uriPermissionPatterns.length;
6531                boolean allowed = false;
6532                for (int i=0; i<N; i++) {
6533                    if (pi.uriPermissionPatterns[i] != null
6534                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6535                        allowed = true;
6536                        break;
6537                    }
6538                }
6539                if (!allowed) {
6540                    throw new SecurityException("Provider " + pi.packageName
6541                            + "/" + pi.name
6542                            + " does not allow granting of permission to path of Uri "
6543                            + grantUri);
6544                }
6545            }
6546        }
6547
6548        // Third...  does the caller itself have permission to access
6549        // this uri?
6550        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6551            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6552                // Require they hold a strong enough Uri permission
6553                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6554                    throw new SecurityException("Uid " + callingUid
6555                            + " does not have permission to uri " + grantUri);
6556                }
6557            }
6558        }
6559        return targetUid;
6560    }
6561
6562    @Override
6563    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6564            final int modeFlags, int userId) {
6565        enforceNotIsolatedCaller("checkGrantUriPermission");
6566        synchronized(this) {
6567            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6568                    new GrantUri(userId, uri, false), modeFlags, -1);
6569        }
6570    }
6571
6572    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6573            final int modeFlags, UriPermissionOwner owner) {
6574        if (!Intent.isAccessUriMode(modeFlags)) {
6575            return;
6576        }
6577
6578        // So here we are: the caller has the assumed permission
6579        // to the uri, and the target doesn't.  Let's now give this to
6580        // the target.
6581
6582        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6583                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6584
6585        final String authority = grantUri.uri.getAuthority();
6586        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6587        if (pi == null) {
6588            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6589            return;
6590        }
6591
6592        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6593            grantUri.prefix = true;
6594        }
6595        final UriPermission perm = findOrCreateUriPermissionLocked(
6596                pi.packageName, targetPkg, targetUid, grantUri);
6597        perm.grantModes(modeFlags, owner);
6598    }
6599
6600    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6601            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6602        if (targetPkg == null) {
6603            throw new NullPointerException("targetPkg");
6604        }
6605        int targetUid;
6606        final IPackageManager pm = AppGlobals.getPackageManager();
6607        try {
6608            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6609        } catch (RemoteException ex) {
6610            return;
6611        }
6612
6613        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6614                targetUid);
6615        if (targetUid < 0) {
6616            return;
6617        }
6618
6619        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6620                owner);
6621    }
6622
6623    static class NeededUriGrants extends ArrayList<GrantUri> {
6624        final String targetPkg;
6625        final int targetUid;
6626        final int flags;
6627
6628        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6629            this.targetPkg = targetPkg;
6630            this.targetUid = targetUid;
6631            this.flags = flags;
6632        }
6633    }
6634
6635    /**
6636     * Like checkGrantUriPermissionLocked, but takes an Intent.
6637     */
6638    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6639            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6640        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6641                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6642                + " clip=" + (intent != null ? intent.getClipData() : null)
6643                + " from " + intent + "; flags=0x"
6644                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6645
6646        if (targetPkg == null) {
6647            throw new NullPointerException("targetPkg");
6648        }
6649
6650        if (intent == null) {
6651            return null;
6652        }
6653        Uri data = intent.getData();
6654        ClipData clip = intent.getClipData();
6655        if (data == null && clip == null) {
6656            return null;
6657        }
6658        // Default userId for uris in the intent (if they don't specify it themselves)
6659        int contentUserHint = intent.getContentUserHint();
6660        if (contentUserHint == UserHandle.USER_CURRENT) {
6661            contentUserHint = UserHandle.getUserId(callingUid);
6662        }
6663        final IPackageManager pm = AppGlobals.getPackageManager();
6664        int targetUid;
6665        if (needed != null) {
6666            targetUid = needed.targetUid;
6667        } else {
6668            try {
6669                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6670            } catch (RemoteException ex) {
6671                return null;
6672            }
6673            if (targetUid < 0) {
6674                if (DEBUG_URI_PERMISSION) {
6675                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6676                            + " on user " + targetUserId);
6677                }
6678                return null;
6679            }
6680        }
6681        if (data != null) {
6682            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6683            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6684                    targetUid);
6685            if (targetUid > 0) {
6686                if (needed == null) {
6687                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6688                }
6689                needed.add(grantUri);
6690            }
6691        }
6692        if (clip != null) {
6693            for (int i=0; i<clip.getItemCount(); i++) {
6694                Uri uri = clip.getItemAt(i).getUri();
6695                if (uri != null) {
6696                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6697                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6698                            targetUid);
6699                    if (targetUid > 0) {
6700                        if (needed == null) {
6701                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6702                        }
6703                        needed.add(grantUri);
6704                    }
6705                } else {
6706                    Intent clipIntent = clip.getItemAt(i).getIntent();
6707                    if (clipIntent != null) {
6708                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6709                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6710                        if (newNeeded != null) {
6711                            needed = newNeeded;
6712                        }
6713                    }
6714                }
6715            }
6716        }
6717
6718        return needed;
6719    }
6720
6721    /**
6722     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6723     */
6724    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6725            UriPermissionOwner owner) {
6726        if (needed != null) {
6727            for (int i=0; i<needed.size(); i++) {
6728                GrantUri grantUri = needed.get(i);
6729                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6730                        grantUri, needed.flags, owner);
6731            }
6732        }
6733    }
6734
6735    void grantUriPermissionFromIntentLocked(int callingUid,
6736            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6737        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6738                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6739        if (needed == null) {
6740            return;
6741        }
6742
6743        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6744    }
6745
6746    @Override
6747    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6748            final int modeFlags, int userId) {
6749        enforceNotIsolatedCaller("grantUriPermission");
6750        GrantUri grantUri = new GrantUri(userId, uri, false);
6751        synchronized(this) {
6752            final ProcessRecord r = getRecordForAppLocked(caller);
6753            if (r == null) {
6754                throw new SecurityException("Unable to find app for caller "
6755                        + caller
6756                        + " when granting permission to uri " + grantUri);
6757            }
6758            if (targetPkg == null) {
6759                throw new IllegalArgumentException("null target");
6760            }
6761            if (grantUri == null) {
6762                throw new IllegalArgumentException("null uri");
6763            }
6764
6765            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6766                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6767                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6768                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6769
6770            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6771                    UserHandle.getUserId(r.uid));
6772        }
6773    }
6774
6775    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6776        if (perm.modeFlags == 0) {
6777            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6778                    perm.targetUid);
6779            if (perms != null) {
6780                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6781                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6782
6783                perms.remove(perm.uri);
6784                if (perms.isEmpty()) {
6785                    mGrantedUriPermissions.remove(perm.targetUid);
6786                }
6787            }
6788        }
6789    }
6790
6791    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6792        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6793
6794        final IPackageManager pm = AppGlobals.getPackageManager();
6795        final String authority = grantUri.uri.getAuthority();
6796        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6797        if (pi == null) {
6798            Slog.w(TAG, "No content provider found for permission revoke: "
6799                    + grantUri.toSafeString());
6800            return;
6801        }
6802
6803        // Does the caller have this permission on the URI?
6804        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6805            // Right now, if you are not the original owner of the permission,
6806            // you are not allowed to revoke it.
6807            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6808                throw new SecurityException("Uid " + callingUid
6809                        + " does not have permission to uri " + grantUri);
6810            //}
6811        }
6812
6813        boolean persistChanged = false;
6814
6815        // Go through all of the permissions and remove any that match.
6816        int N = mGrantedUriPermissions.size();
6817        for (int i = 0; i < N; i++) {
6818            final int targetUid = mGrantedUriPermissions.keyAt(i);
6819            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6820
6821            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6822                final UriPermission perm = it.next();
6823                if (perm.uri.sourceUserId == grantUri.sourceUserId
6824                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6825                    if (DEBUG_URI_PERMISSION)
6826                        Slog.v(TAG,
6827                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6828                    persistChanged |= perm.revokeModes(
6829                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6830                    if (perm.modeFlags == 0) {
6831                        it.remove();
6832                    }
6833                }
6834            }
6835
6836            if (perms.isEmpty()) {
6837                mGrantedUriPermissions.remove(targetUid);
6838                N--;
6839                i--;
6840            }
6841        }
6842
6843        if (persistChanged) {
6844            schedulePersistUriGrants();
6845        }
6846    }
6847
6848    @Override
6849    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6850            int userId) {
6851        enforceNotIsolatedCaller("revokeUriPermission");
6852        synchronized(this) {
6853            final ProcessRecord r = getRecordForAppLocked(caller);
6854            if (r == null) {
6855                throw new SecurityException("Unable to find app for caller "
6856                        + caller
6857                        + " when revoking permission to uri " + uri);
6858            }
6859            if (uri == null) {
6860                Slog.w(TAG, "revokeUriPermission: null uri");
6861                return;
6862            }
6863
6864            if (!Intent.isAccessUriMode(modeFlags)) {
6865                return;
6866            }
6867
6868            final IPackageManager pm = AppGlobals.getPackageManager();
6869            final String authority = uri.getAuthority();
6870            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6871            if (pi == null) {
6872                Slog.w(TAG, "No content provider found for permission revoke: "
6873                        + uri.toSafeString());
6874                return;
6875            }
6876
6877            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6878        }
6879    }
6880
6881    /**
6882     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6883     * given package.
6884     *
6885     * @param packageName Package name to match, or {@code null} to apply to all
6886     *            packages.
6887     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6888     *            to all users.
6889     * @param persistable If persistable grants should be removed.
6890     */
6891    private void removeUriPermissionsForPackageLocked(
6892            String packageName, int userHandle, boolean persistable) {
6893        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6894            throw new IllegalArgumentException("Must narrow by either package or user");
6895        }
6896
6897        boolean persistChanged = false;
6898
6899        int N = mGrantedUriPermissions.size();
6900        for (int i = 0; i < N; i++) {
6901            final int targetUid = mGrantedUriPermissions.keyAt(i);
6902            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6903
6904            // Only inspect grants matching user
6905            if (userHandle == UserHandle.USER_ALL
6906                    || userHandle == UserHandle.getUserId(targetUid)) {
6907                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6908                    final UriPermission perm = it.next();
6909
6910                    // Only inspect grants matching package
6911                    if (packageName == null || perm.sourcePkg.equals(packageName)
6912                            || perm.targetPkg.equals(packageName)) {
6913                        persistChanged |= perm.revokeModes(
6914                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6915
6916                        // Only remove when no modes remain; any persisted grants
6917                        // will keep this alive.
6918                        if (perm.modeFlags == 0) {
6919                            it.remove();
6920                        }
6921                    }
6922                }
6923
6924                if (perms.isEmpty()) {
6925                    mGrantedUriPermissions.remove(targetUid);
6926                    N--;
6927                    i--;
6928                }
6929            }
6930        }
6931
6932        if (persistChanged) {
6933            schedulePersistUriGrants();
6934        }
6935    }
6936
6937    @Override
6938    public IBinder newUriPermissionOwner(String name) {
6939        enforceNotIsolatedCaller("newUriPermissionOwner");
6940        synchronized(this) {
6941            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6942            return owner.getExternalTokenLocked();
6943        }
6944    }
6945
6946    @Override
6947    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6948            final int modeFlags, int sourceUserId, int targetUserId) {
6949        synchronized(this) {
6950            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6951            if (owner == null) {
6952                throw new IllegalArgumentException("Unknown owner: " + token);
6953            }
6954            if (fromUid != Binder.getCallingUid()) {
6955                if (Binder.getCallingUid() != Process.myUid()) {
6956                    // Only system code can grant URI permissions on behalf
6957                    // of other users.
6958                    throw new SecurityException("nice try");
6959                }
6960            }
6961            if (targetPkg == null) {
6962                throw new IllegalArgumentException("null target");
6963            }
6964            if (uri == null) {
6965                throw new IllegalArgumentException("null uri");
6966            }
6967
6968            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
6969                    modeFlags, owner, targetUserId);
6970        }
6971    }
6972
6973    @Override
6974    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6975        synchronized(this) {
6976            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6977            if (owner == null) {
6978                throw new IllegalArgumentException("Unknown owner: " + token);
6979            }
6980
6981            if (uri == null) {
6982                owner.removeUriPermissionsLocked(mode);
6983            } else {
6984                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6985            }
6986        }
6987    }
6988
6989    private void schedulePersistUriGrants() {
6990        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6991            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6992                    10 * DateUtils.SECOND_IN_MILLIS);
6993        }
6994    }
6995
6996    private void writeGrantedUriPermissions() {
6997        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6998
6999        // Snapshot permissions so we can persist without lock
7000        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7001        synchronized (this) {
7002            final int size = mGrantedUriPermissions.size();
7003            for (int i = 0; i < size; i++) {
7004                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7005                for (UriPermission perm : perms.values()) {
7006                    if (perm.persistedModeFlags != 0) {
7007                        persist.add(perm.snapshot());
7008                    }
7009                }
7010            }
7011        }
7012
7013        FileOutputStream fos = null;
7014        try {
7015            fos = mGrantFile.startWrite();
7016
7017            XmlSerializer out = new FastXmlSerializer();
7018            out.setOutput(fos, "utf-8");
7019            out.startDocument(null, true);
7020            out.startTag(null, TAG_URI_GRANTS);
7021            for (UriPermission.Snapshot perm : persist) {
7022                out.startTag(null, TAG_URI_GRANT);
7023                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7024                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7025                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7026                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7027                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7028                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7029                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7030                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7031                out.endTag(null, TAG_URI_GRANT);
7032            }
7033            out.endTag(null, TAG_URI_GRANTS);
7034            out.endDocument();
7035
7036            mGrantFile.finishWrite(fos);
7037        } catch (IOException e) {
7038            if (fos != null) {
7039                mGrantFile.failWrite(fos);
7040            }
7041        }
7042    }
7043
7044    private void readGrantedUriPermissionsLocked() {
7045        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7046
7047        final long now = System.currentTimeMillis();
7048
7049        FileInputStream fis = null;
7050        try {
7051            fis = mGrantFile.openRead();
7052            final XmlPullParser in = Xml.newPullParser();
7053            in.setInput(fis, null);
7054
7055            int type;
7056            while ((type = in.next()) != END_DOCUMENT) {
7057                final String tag = in.getName();
7058                if (type == START_TAG) {
7059                    if (TAG_URI_GRANT.equals(tag)) {
7060                        final int sourceUserId;
7061                        final int targetUserId;
7062                        final int userHandle = readIntAttribute(in,
7063                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7064                        if (userHandle != UserHandle.USER_NULL) {
7065                            // For backwards compatibility.
7066                            sourceUserId = userHandle;
7067                            targetUserId = userHandle;
7068                        } else {
7069                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7070                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7071                        }
7072                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7073                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7074                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7075                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7076                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7077                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7078
7079                        // Sanity check that provider still belongs to source package
7080                        final ProviderInfo pi = getProviderInfoLocked(
7081                                uri.getAuthority(), sourceUserId);
7082                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7083                            int targetUid = -1;
7084                            try {
7085                                targetUid = AppGlobals.getPackageManager()
7086                                        .getPackageUid(targetPkg, targetUserId);
7087                            } catch (RemoteException e) {
7088                            }
7089                            if (targetUid != -1) {
7090                                final UriPermission perm = findOrCreateUriPermissionLocked(
7091                                        sourcePkg, targetPkg, targetUid,
7092                                        new GrantUri(sourceUserId, uri, prefix));
7093                                perm.initPersistedModes(modeFlags, createdTime);
7094                            }
7095                        } else {
7096                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7097                                    + " but instead found " + pi);
7098                        }
7099                    }
7100                }
7101            }
7102        } catch (FileNotFoundException e) {
7103            // Missing grants is okay
7104        } catch (IOException e) {
7105            Log.wtf(TAG, "Failed reading Uri grants", e);
7106        } catch (XmlPullParserException e) {
7107            Log.wtf(TAG, "Failed reading Uri grants", e);
7108        } finally {
7109            IoUtils.closeQuietly(fis);
7110        }
7111    }
7112
7113    @Override
7114    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7115        enforceNotIsolatedCaller("takePersistableUriPermission");
7116
7117        Preconditions.checkFlagsArgument(modeFlags,
7118                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7119
7120        synchronized (this) {
7121            final int callingUid = Binder.getCallingUid();
7122            boolean persistChanged = false;
7123            GrantUri grantUri = new GrantUri(userId, uri, false);
7124
7125            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7126                    new GrantUri(userId, uri, false));
7127            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7128                    new GrantUri(userId, uri, true));
7129
7130            final boolean exactValid = (exactPerm != null)
7131                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7132            final boolean prefixValid = (prefixPerm != null)
7133                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7134
7135            if (!(exactValid || prefixValid)) {
7136                throw new SecurityException("No persistable permission grants found for UID "
7137                        + callingUid + " and Uri " + grantUri.toSafeString());
7138            }
7139
7140            if (exactValid) {
7141                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7142            }
7143            if (prefixValid) {
7144                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7145            }
7146
7147            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7148
7149            if (persistChanged) {
7150                schedulePersistUriGrants();
7151            }
7152        }
7153    }
7154
7155    @Override
7156    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7157        enforceNotIsolatedCaller("releasePersistableUriPermission");
7158
7159        Preconditions.checkFlagsArgument(modeFlags,
7160                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7161
7162        synchronized (this) {
7163            final int callingUid = Binder.getCallingUid();
7164            boolean persistChanged = false;
7165
7166            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7167                    new GrantUri(userId, uri, false));
7168            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7169                    new GrantUri(userId, uri, true));
7170            if (exactPerm == null && prefixPerm == null) {
7171                throw new SecurityException("No permission grants found for UID " + callingUid
7172                        + " and Uri " + uri.toSafeString());
7173            }
7174
7175            if (exactPerm != null) {
7176                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7177                removeUriPermissionIfNeededLocked(exactPerm);
7178            }
7179            if (prefixPerm != null) {
7180                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7181                removeUriPermissionIfNeededLocked(prefixPerm);
7182            }
7183
7184            if (persistChanged) {
7185                schedulePersistUriGrants();
7186            }
7187        }
7188    }
7189
7190    /**
7191     * Prune any older {@link UriPermission} for the given UID until outstanding
7192     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7193     *
7194     * @return if any mutations occured that require persisting.
7195     */
7196    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7197        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7198        if (perms == null) return false;
7199        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7200
7201        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7202        for (UriPermission perm : perms.values()) {
7203            if (perm.persistedModeFlags != 0) {
7204                persisted.add(perm);
7205            }
7206        }
7207
7208        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7209        if (trimCount <= 0) return false;
7210
7211        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7212        for (int i = 0; i < trimCount; i++) {
7213            final UriPermission perm = persisted.get(i);
7214
7215            if (DEBUG_URI_PERMISSION) {
7216                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7217            }
7218
7219            perm.releasePersistableModes(~0);
7220            removeUriPermissionIfNeededLocked(perm);
7221        }
7222
7223        return true;
7224    }
7225
7226    @Override
7227    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7228            String packageName, boolean incoming) {
7229        enforceNotIsolatedCaller("getPersistedUriPermissions");
7230        Preconditions.checkNotNull(packageName, "packageName");
7231
7232        final int callingUid = Binder.getCallingUid();
7233        final IPackageManager pm = AppGlobals.getPackageManager();
7234        try {
7235            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7236            if (packageUid != callingUid) {
7237                throw new SecurityException(
7238                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7239            }
7240        } catch (RemoteException e) {
7241            throw new SecurityException("Failed to verify package name ownership");
7242        }
7243
7244        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7245        synchronized (this) {
7246            if (incoming) {
7247                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7248                        callingUid);
7249                if (perms == null) {
7250                    Slog.w(TAG, "No permission grants found for " + packageName);
7251                } else {
7252                    for (UriPermission perm : perms.values()) {
7253                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7254                            result.add(perm.buildPersistedPublicApiObject());
7255                        }
7256                    }
7257                }
7258            } else {
7259                final int size = mGrantedUriPermissions.size();
7260                for (int i = 0; i < size; i++) {
7261                    final ArrayMap<GrantUri, UriPermission> perms =
7262                            mGrantedUriPermissions.valueAt(i);
7263                    for (UriPermission perm : perms.values()) {
7264                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7265                            result.add(perm.buildPersistedPublicApiObject());
7266                        }
7267                    }
7268                }
7269            }
7270        }
7271        return new ParceledListSlice<android.content.UriPermission>(result);
7272    }
7273
7274    @Override
7275    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7276        synchronized (this) {
7277            ProcessRecord app =
7278                who != null ? getRecordForAppLocked(who) : null;
7279            if (app == null) return;
7280
7281            Message msg = Message.obtain();
7282            msg.what = WAIT_FOR_DEBUGGER_MSG;
7283            msg.obj = app;
7284            msg.arg1 = waiting ? 1 : 0;
7285            mHandler.sendMessage(msg);
7286        }
7287    }
7288
7289    @Override
7290    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7291        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7292        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7293        outInfo.availMem = Process.getFreeMemory();
7294        outInfo.totalMem = Process.getTotalMemory();
7295        outInfo.threshold = homeAppMem;
7296        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7297        outInfo.hiddenAppThreshold = cachedAppMem;
7298        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7299                ProcessList.SERVICE_ADJ);
7300        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7301                ProcessList.VISIBLE_APP_ADJ);
7302        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7303                ProcessList.FOREGROUND_APP_ADJ);
7304    }
7305
7306    // =========================================================
7307    // TASK MANAGEMENT
7308    // =========================================================
7309
7310    @Override
7311    public List<IAppTask> getAppTasks() {
7312        final PackageManager pm = mContext.getPackageManager();
7313        int callingUid = Binder.getCallingUid();
7314        long ident = Binder.clearCallingIdentity();
7315
7316        // Compose the list of packages for this id to test against
7317        HashSet<String> packages = new HashSet<String>();
7318        String[] uidPackages = pm.getPackagesForUid(callingUid);
7319        for (int i = 0; i < uidPackages.length; i++) {
7320            packages.add(uidPackages[i]);
7321        }
7322
7323        synchronized(this) {
7324            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7325            try {
7326                if (localLOGV) Slog.v(TAG, "getAppTasks");
7327
7328                final int N = mRecentTasks.size();
7329                for (int i = 0; i < N; i++) {
7330                    TaskRecord tr = mRecentTasks.get(i);
7331                    // Skip tasks that are not created by the caller
7332                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7333                        ActivityManager.RecentTaskInfo taskInfo =
7334                                createRecentTaskInfoFromTaskRecord(tr);
7335                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7336                        list.add(taskImpl);
7337                    }
7338                }
7339            } finally {
7340                Binder.restoreCallingIdentity(ident);
7341            }
7342            return list;
7343        }
7344    }
7345
7346    @Override
7347    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7348        final int callingUid = Binder.getCallingUid();
7349        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7350
7351        synchronized(this) {
7352            if (localLOGV) Slog.v(
7353                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7354
7355            final boolean allowed = checkCallingPermission(
7356                    android.Manifest.permission.GET_TASKS)
7357                    == PackageManager.PERMISSION_GRANTED;
7358            if (!allowed) {
7359                Slog.w(TAG, "getTasks: caller " + callingUid
7360                        + " does not hold GET_TASKS; limiting output");
7361            }
7362
7363            // TODO: Improve with MRU list from all ActivityStacks.
7364            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7365        }
7366
7367        return list;
7368    }
7369
7370    TaskRecord getMostRecentTask() {
7371        return mRecentTasks.get(0);
7372    }
7373
7374    /**
7375     * Creates a new RecentTaskInfo from a TaskRecord.
7376     */
7377    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7378        // Update the task description to reflect any changes in the task stack
7379        tr.updateTaskDescription();
7380
7381        // Compose the recent task info
7382        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7383        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7384        rti.persistentId = tr.taskId;
7385        rti.baseIntent = new Intent(tr.getBaseIntent());
7386        rti.origActivity = tr.origActivity;
7387        rti.description = tr.lastDescription;
7388        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7389        rti.userId = tr.userId;
7390        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7391        rti.firstActiveTime = tr.firstActiveTime;
7392        rti.lastActiveTime = tr.lastActiveTime;
7393        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7394        return rti;
7395    }
7396
7397    @Override
7398    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7399        final int callingUid = Binder.getCallingUid();
7400        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7401                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7402
7403        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7404        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7405        synchronized (this) {
7406            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7407                    == PackageManager.PERMISSION_GRANTED;
7408            if (!allowed) {
7409                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7410                        + " does not hold GET_TASKS; limiting output");
7411            }
7412            final boolean detailed = checkCallingPermission(
7413                    android.Manifest.permission.GET_DETAILED_TASKS)
7414                    == PackageManager.PERMISSION_GRANTED;
7415
7416            IPackageManager pm = AppGlobals.getPackageManager();
7417
7418            final int N = mRecentTasks.size();
7419            ArrayList<ActivityManager.RecentTaskInfo> res
7420                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7421                            maxNum < N ? maxNum : N);
7422
7423            final Set<Integer> includedUsers;
7424            if (includeProfiles) {
7425                includedUsers = getProfileIdsLocked(userId);
7426            } else {
7427                includedUsers = new HashSet<Integer>();
7428            }
7429            includedUsers.add(Integer.valueOf(userId));
7430
7431            // Regroup affiliated tasks together.
7432            for (int i = 0; i < N; ) {
7433                TaskRecord task = mRecentTasks.remove(i);
7434                if (mTmpRecents.contains(task)) {
7435                    continue;
7436                }
7437                int affiliatedTaskId = task.mAffiliatedTaskId;
7438                while (true) {
7439                    TaskRecord next = task.mNextAffiliate;
7440                    if (next == null) {
7441                        break;
7442                    }
7443                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7444                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7445                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7446                        task.setNextAffiliate(null);
7447                        if (next.mPrevAffiliate == task) {
7448                            next.setPrevAffiliate(null);
7449                        }
7450                        break;
7451                    }
7452                    if (next.mPrevAffiliate != task) {
7453                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7454                                next.mPrevAffiliate + " task=" + task);
7455                        next.setPrevAffiliate(null);
7456                        break;
7457                    }
7458                    if (!mRecentTasks.contains(next)) {
7459                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7460                        task.setNextAffiliate(null);
7461                        if (next.mPrevAffiliate == task) {
7462                            next.setPrevAffiliate(null);
7463                        }
7464                        break;
7465                    }
7466                    task = next;
7467                }
7468                // task is now the end of the list
7469                do {
7470                    mRecentTasks.remove(task);
7471                    mRecentTasks.add(i++, task);
7472                    mTmpRecents.add(task);
7473                } while ((task = task.mPrevAffiliate) != null);
7474            }
7475            mTmpRecents.clear();
7476            // mRecentTasks is now in sorted, affiliated order.
7477
7478            for (int i=0; i<N && maxNum > 0; i++) {
7479                TaskRecord tr = mRecentTasks.get(i);
7480                // Only add calling user or related users recent tasks
7481                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7482
7483                // Return the entry if desired by the caller.  We always return
7484                // the first entry, because callers always expect this to be the
7485                // foreground app.  We may filter others if the caller has
7486                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7487                // we should exclude the entry.
7488
7489                if (i == 0
7490                        || withExcluded
7491                        || (tr.intent == null)
7492                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7493                                == 0)) {
7494                    if (!allowed) {
7495                        // If the caller doesn't have the GET_TASKS permission, then only
7496                        // allow them to see a small subset of tasks -- their own and home.
7497                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7498                            continue;
7499                        }
7500                    }
7501                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7502                        // Don't include auto remove tasks that are finished or finishing.
7503                        continue;
7504                    }
7505
7506                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7507                    if (!detailed) {
7508                        rti.baseIntent.replaceExtras((Bundle)null);
7509                    }
7510
7511                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7512                        // Check whether this activity is currently available.
7513                        try {
7514                            if (rti.origActivity != null) {
7515                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7516                                        == null) {
7517                                    continue;
7518                                }
7519                            } else if (rti.baseIntent != null) {
7520                                if (pm.queryIntentActivities(rti.baseIntent,
7521                                        null, 0, userId) == null) {
7522                                    continue;
7523                                }
7524                            }
7525                        } catch (RemoteException e) {
7526                            // Will never happen.
7527                        }
7528                    }
7529
7530                    res.add(rti);
7531                    maxNum--;
7532                }
7533            }
7534            return res;
7535        }
7536    }
7537
7538    private TaskRecord recentTaskForIdLocked(int id) {
7539        final int N = mRecentTasks.size();
7540            for (int i=0; i<N; i++) {
7541                TaskRecord tr = mRecentTasks.get(i);
7542                if (tr.taskId == id) {
7543                    return tr;
7544                }
7545            }
7546            return null;
7547    }
7548
7549    @Override
7550    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7551        synchronized (this) {
7552            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7553                    "getTaskThumbnail()");
7554            TaskRecord tr = recentTaskForIdLocked(id);
7555            if (tr != null) {
7556                return tr.getTaskThumbnailLocked();
7557            }
7558        }
7559        return null;
7560    }
7561
7562    @Override
7563    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7564        synchronized (this) {
7565            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7566            if (r != null) {
7567                r.taskDescription = td;
7568                r.task.updateTaskDescription();
7569            }
7570        }
7571    }
7572
7573    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7574        if (!pr.killedByAm) {
7575            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7576            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7577                    pr.processName, pr.setAdj, reason);
7578            pr.killedByAm = true;
7579            Process.killProcessQuiet(pr.pid);
7580            Process.killProcessGroup(pr.info.uid, pr.pid);
7581        }
7582    }
7583
7584    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7585        tr.disposeThumbnail();
7586        mRecentTasks.remove(tr);
7587        tr.closeRecentsChain();
7588        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7589        Intent baseIntent = new Intent(
7590                tr.intent != null ? tr.intent : tr.affinityIntent);
7591        ComponentName component = baseIntent.getComponent();
7592        if (component == null) {
7593            Slog.w(TAG, "Now component for base intent of task: " + tr);
7594            return;
7595        }
7596
7597        // Find any running services associated with this app.
7598        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7599
7600        if (killProcesses) {
7601            // Find any running processes associated with this app.
7602            final String pkg = component.getPackageName();
7603            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7604            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7605            for (int i=0; i<pmap.size(); i++) {
7606                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7607                for (int j=0; j<uids.size(); j++) {
7608                    ProcessRecord proc = uids.valueAt(j);
7609                    if (proc.userId != tr.userId) {
7610                        continue;
7611                    }
7612                    if (!proc.pkgList.containsKey(pkg)) {
7613                        continue;
7614                    }
7615                    procs.add(proc);
7616                }
7617            }
7618
7619            // Kill the running processes.
7620            for (int i=0; i<procs.size(); i++) {
7621                ProcessRecord pr = procs.get(i);
7622                if (pr == mHomeProcess) {
7623                    // Don't kill the home process along with tasks from the same package.
7624                    continue;
7625                }
7626                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7627                    killUnneededProcessLocked(pr, "remove task");
7628                } else {
7629                    pr.waitingToKill = "remove task";
7630                }
7631            }
7632        }
7633    }
7634
7635    /**
7636     * Removes the task with the specified task id.
7637     *
7638     * @param taskId Identifier of the task to be removed.
7639     * @param flags Additional operational flags.  May be 0 or
7640     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7641     * @return Returns true if the given task was found and removed.
7642     */
7643    private boolean removeTaskByIdLocked(int taskId, int flags) {
7644        TaskRecord tr = recentTaskForIdLocked(taskId);
7645        if (tr != null) {
7646            tr.removeTaskActivitiesLocked();
7647            cleanUpRemovedTaskLocked(tr, flags);
7648            if (tr.isPersistable) {
7649                notifyTaskPersisterLocked(null, true);
7650            }
7651            return true;
7652        }
7653        return false;
7654    }
7655
7656    @Override
7657    public boolean removeTask(int taskId, int flags) {
7658        synchronized (this) {
7659            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7660                    "removeTask()");
7661            long ident = Binder.clearCallingIdentity();
7662            try {
7663                return removeTaskByIdLocked(taskId, flags);
7664            } finally {
7665                Binder.restoreCallingIdentity(ident);
7666            }
7667        }
7668    }
7669
7670    /**
7671     * TODO: Add mController hook
7672     */
7673    @Override
7674    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7675        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7676                "moveTaskToFront()");
7677
7678        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7679        synchronized(this) {
7680            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7681                    Binder.getCallingUid(), "Task to front")) {
7682                ActivityOptions.abort(options);
7683                return;
7684            }
7685            final long origId = Binder.clearCallingIdentity();
7686            try {
7687                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7688                if (task == null) {
7689                    return;
7690                }
7691                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7692                    mStackSupervisor.showLockTaskToast();
7693                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7694                    return;
7695                }
7696                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7697                if (prev != null && prev.isRecentsActivity()) {
7698                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7699                }
7700                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7701            } finally {
7702                Binder.restoreCallingIdentity(origId);
7703            }
7704            ActivityOptions.abort(options);
7705        }
7706    }
7707
7708    @Override
7709    public void moveTaskToBack(int taskId) {
7710        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7711                "moveTaskToBack()");
7712
7713        synchronized(this) {
7714            TaskRecord tr = recentTaskForIdLocked(taskId);
7715            if (tr != null) {
7716                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7717                ActivityStack stack = tr.stack;
7718                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7719                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7720                            Binder.getCallingUid(), "Task to back")) {
7721                        return;
7722                    }
7723                }
7724                final long origId = Binder.clearCallingIdentity();
7725                try {
7726                    stack.moveTaskToBackLocked(taskId, null);
7727                } finally {
7728                    Binder.restoreCallingIdentity(origId);
7729                }
7730            }
7731        }
7732    }
7733
7734    /**
7735     * Moves an activity, and all of the other activities within the same task, to the bottom
7736     * of the history stack.  The activity's order within the task is unchanged.
7737     *
7738     * @param token A reference to the activity we wish to move
7739     * @param nonRoot If false then this only works if the activity is the root
7740     *                of a task; if true it will work for any activity in a task.
7741     * @return Returns true if the move completed, false if not.
7742     */
7743    @Override
7744    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7745        enforceNotIsolatedCaller("moveActivityTaskToBack");
7746        synchronized(this) {
7747            final long origId = Binder.clearCallingIdentity();
7748            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7749            if (taskId >= 0) {
7750                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7751            }
7752            Binder.restoreCallingIdentity(origId);
7753        }
7754        return false;
7755    }
7756
7757    @Override
7758    public void moveTaskBackwards(int task) {
7759        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7760                "moveTaskBackwards()");
7761
7762        synchronized(this) {
7763            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7764                    Binder.getCallingUid(), "Task backwards")) {
7765                return;
7766            }
7767            final long origId = Binder.clearCallingIdentity();
7768            moveTaskBackwardsLocked(task);
7769            Binder.restoreCallingIdentity(origId);
7770        }
7771    }
7772
7773    private final void moveTaskBackwardsLocked(int task) {
7774        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7775    }
7776
7777    @Override
7778    public IBinder getHomeActivityToken() throws RemoteException {
7779        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7780                "getHomeActivityToken()");
7781        synchronized (this) {
7782            return mStackSupervisor.getHomeActivityToken();
7783        }
7784    }
7785
7786    @Override
7787    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7788            IActivityContainerCallback callback) throws RemoteException {
7789        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7790                "createActivityContainer()");
7791        synchronized (this) {
7792            if (parentActivityToken == null) {
7793                throw new IllegalArgumentException("parent token must not be null");
7794            }
7795            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7796            if (r == null) {
7797                return null;
7798            }
7799            if (callback == null) {
7800                throw new IllegalArgumentException("callback must not be null");
7801            }
7802            return mStackSupervisor.createActivityContainer(r, callback);
7803        }
7804    }
7805
7806    @Override
7807    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7808        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7809                "deleteActivityContainer()");
7810        synchronized (this) {
7811            mStackSupervisor.deleteActivityContainer(container);
7812        }
7813    }
7814
7815    @Override
7816    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7817            throws RemoteException {
7818        synchronized (this) {
7819            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7820            if (stack != null) {
7821                return stack.mActivityContainer;
7822            }
7823            return null;
7824        }
7825    }
7826
7827    @Override
7828    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7829        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7830                "moveTaskToStack()");
7831        if (stackId == HOME_STACK_ID) {
7832            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7833                    new RuntimeException("here").fillInStackTrace());
7834        }
7835        synchronized (this) {
7836            long ident = Binder.clearCallingIdentity();
7837            try {
7838                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7839                        + stackId + " toTop=" + toTop);
7840                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7841            } finally {
7842                Binder.restoreCallingIdentity(ident);
7843            }
7844        }
7845    }
7846
7847    @Override
7848    public void resizeStack(int stackBoxId, Rect bounds) {
7849        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7850                "resizeStackBox()");
7851        long ident = Binder.clearCallingIdentity();
7852        try {
7853            mWindowManager.resizeStack(stackBoxId, bounds);
7854        } finally {
7855            Binder.restoreCallingIdentity(ident);
7856        }
7857    }
7858
7859    @Override
7860    public List<StackInfo> getAllStackInfos() {
7861        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7862                "getAllStackInfos()");
7863        long ident = Binder.clearCallingIdentity();
7864        try {
7865            synchronized (this) {
7866                return mStackSupervisor.getAllStackInfosLocked();
7867            }
7868        } finally {
7869            Binder.restoreCallingIdentity(ident);
7870        }
7871    }
7872
7873    @Override
7874    public StackInfo getStackInfo(int stackId) {
7875        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7876                "getStackInfo()");
7877        long ident = Binder.clearCallingIdentity();
7878        try {
7879            synchronized (this) {
7880                return mStackSupervisor.getStackInfoLocked(stackId);
7881            }
7882        } finally {
7883            Binder.restoreCallingIdentity(ident);
7884        }
7885    }
7886
7887    @Override
7888    public boolean isInHomeStack(int taskId) {
7889        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7890                "getStackInfo()");
7891        long ident = Binder.clearCallingIdentity();
7892        try {
7893            synchronized (this) {
7894                TaskRecord tr = recentTaskForIdLocked(taskId);
7895                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7896            }
7897        } finally {
7898            Binder.restoreCallingIdentity(ident);
7899        }
7900    }
7901
7902    @Override
7903    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7904        synchronized(this) {
7905            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7906        }
7907    }
7908
7909    private boolean isLockTaskAuthorized(String pkg) {
7910        final DevicePolicyManager dpm = (DevicePolicyManager)
7911                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7912        try {
7913            int uid = mContext.getPackageManager().getPackageUid(pkg,
7914                    Binder.getCallingUserHandle().getIdentifier());
7915            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7916        } catch (NameNotFoundException e) {
7917            return false;
7918        }
7919    }
7920
7921    void startLockTaskMode(TaskRecord task) {
7922        final String pkg;
7923        synchronized (this) {
7924            pkg = task.intent.getComponent().getPackageName();
7925        }
7926        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7927        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7928            final TaskRecord taskRecord = task;
7929            mHandler.post(new Runnable() {
7930                @Override
7931                public void run() {
7932                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7933                }
7934            });
7935            return;
7936        }
7937        long ident = Binder.clearCallingIdentity();
7938        try {
7939            synchronized (this) {
7940                // Since we lost lock on task, make sure it is still there.
7941                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7942                if (task != null) {
7943                    if (!isSystemInitiated
7944                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7945                        throw new IllegalArgumentException("Invalid task, not in foreground");
7946                    }
7947                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7948                }
7949            }
7950        } finally {
7951            Binder.restoreCallingIdentity(ident);
7952        }
7953    }
7954
7955    @Override
7956    public void startLockTaskMode(int taskId) {
7957        final TaskRecord task;
7958        long ident = Binder.clearCallingIdentity();
7959        try {
7960            synchronized (this) {
7961                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7962            }
7963        } finally {
7964            Binder.restoreCallingIdentity(ident);
7965        }
7966        if (task != null) {
7967            startLockTaskMode(task);
7968        }
7969    }
7970
7971    @Override
7972    public void startLockTaskMode(IBinder token) {
7973        final TaskRecord task;
7974        long ident = Binder.clearCallingIdentity();
7975        try {
7976            synchronized (this) {
7977                final ActivityRecord r = ActivityRecord.forToken(token);
7978                if (r == null) {
7979                    return;
7980                }
7981                task = r.task;
7982            }
7983        } finally {
7984            Binder.restoreCallingIdentity(ident);
7985        }
7986        if (task != null) {
7987            startLockTaskMode(task);
7988        }
7989    }
7990
7991    @Override
7992    public void startLockTaskModeOnCurrent() throws RemoteException {
7993        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7994        ActivityRecord r = null;
7995        synchronized (this) {
7996            r = mStackSupervisor.topRunningActivityLocked();
7997        }
7998        startLockTaskMode(r.task);
7999    }
8000
8001    @Override
8002    public void stopLockTaskMode() {
8003        // Verify that the user matches the package of the intent for the TaskRecord
8004        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8005        // and stopLockTaskMode.
8006        final int callingUid = Binder.getCallingUid();
8007        if (callingUid != Process.SYSTEM_UID) {
8008            try {
8009                String pkg =
8010                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8011                int uid = mContext.getPackageManager().getPackageUid(pkg,
8012                        Binder.getCallingUserHandle().getIdentifier());
8013                if (uid != callingUid) {
8014                    throw new SecurityException("Invalid uid, expected " + uid);
8015                }
8016            } catch (NameNotFoundException e) {
8017                Log.d(TAG, "stopLockTaskMode " + e);
8018                return;
8019            }
8020        }
8021        long ident = Binder.clearCallingIdentity();
8022        try {
8023            Log.d(TAG, "stopLockTaskMode");
8024            // Stop lock task
8025            synchronized (this) {
8026                mStackSupervisor.setLockTaskModeLocked(null, false);
8027            }
8028        } finally {
8029            Binder.restoreCallingIdentity(ident);
8030        }
8031    }
8032
8033    @Override
8034    public void stopLockTaskModeOnCurrent() throws RemoteException {
8035        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8036        long ident = Binder.clearCallingIdentity();
8037        try {
8038            stopLockTaskMode();
8039        } finally {
8040            Binder.restoreCallingIdentity(ident);
8041        }
8042    }
8043
8044    @Override
8045    public boolean isInLockTaskMode() {
8046        synchronized (this) {
8047            return mStackSupervisor.isInLockTaskMode();
8048        }
8049    }
8050
8051    // =========================================================
8052    // CONTENT PROVIDERS
8053    // =========================================================
8054
8055    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8056        List<ProviderInfo> providers = null;
8057        try {
8058            providers = AppGlobals.getPackageManager().
8059                queryContentProviders(app.processName, app.uid,
8060                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8061        } catch (RemoteException ex) {
8062        }
8063        if (DEBUG_MU)
8064            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8065        int userId = app.userId;
8066        if (providers != null) {
8067            int N = providers.size();
8068            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8069            for (int i=0; i<N; i++) {
8070                ProviderInfo cpi =
8071                    (ProviderInfo)providers.get(i);
8072                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8073                        cpi.name, cpi.flags);
8074                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8075                    // This is a singleton provider, but a user besides the
8076                    // default user is asking to initialize a process it runs
8077                    // in...  well, no, it doesn't actually run in this process,
8078                    // it runs in the process of the default user.  Get rid of it.
8079                    providers.remove(i);
8080                    N--;
8081                    i--;
8082                    continue;
8083                }
8084
8085                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8086                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8087                if (cpr == null) {
8088                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8089                    mProviderMap.putProviderByClass(comp, cpr);
8090                }
8091                if (DEBUG_MU)
8092                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8093                app.pubProviders.put(cpi.name, cpr);
8094                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8095                    // Don't add this if it is a platform component that is marked
8096                    // to run in multiple processes, because this is actually
8097                    // part of the framework so doesn't make sense to track as a
8098                    // separate apk in the process.
8099                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8100                            mProcessStats);
8101                }
8102                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8103            }
8104        }
8105        return providers;
8106    }
8107
8108    /**
8109     * Check if {@link ProcessRecord} has a possible chance at accessing the
8110     * given {@link ProviderInfo}. Final permission checking is always done
8111     * in {@link ContentProvider}.
8112     */
8113    private final String checkContentProviderPermissionLocked(
8114            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8115        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8116        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8117        boolean checkedGrants = false;
8118        if (checkUser) {
8119            // Looking for cross-user grants before enforcing the typical cross-users permissions
8120            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8121            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8122                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8123                    return null;
8124                }
8125                checkedGrants = true;
8126            }
8127            userId = handleIncomingUser(callingPid, callingUid, userId,
8128                    false, ALLOW_NON_FULL,
8129                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8130            if (userId != tmpTargetUserId) {
8131                // When we actually went to determine the final targer user ID, this ended
8132                // up different than our initial check for the authority.  This is because
8133                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8134                // SELF.  So we need to re-check the grants again.
8135                checkedGrants = false;
8136            }
8137        }
8138        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8139                cpi.applicationInfo.uid, cpi.exported)
8140                == PackageManager.PERMISSION_GRANTED) {
8141            return null;
8142        }
8143        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8144                cpi.applicationInfo.uid, cpi.exported)
8145                == PackageManager.PERMISSION_GRANTED) {
8146            return null;
8147        }
8148
8149        PathPermission[] pps = cpi.pathPermissions;
8150        if (pps != null) {
8151            int i = pps.length;
8152            while (i > 0) {
8153                i--;
8154                PathPermission pp = pps[i];
8155                String pprperm = pp.getReadPermission();
8156                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8157                        cpi.applicationInfo.uid, cpi.exported)
8158                        == PackageManager.PERMISSION_GRANTED) {
8159                    return null;
8160                }
8161                String ppwperm = pp.getWritePermission();
8162                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8163                        cpi.applicationInfo.uid, cpi.exported)
8164                        == PackageManager.PERMISSION_GRANTED) {
8165                    return null;
8166                }
8167            }
8168        }
8169        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8170            return null;
8171        }
8172
8173        String msg;
8174        if (!cpi.exported) {
8175            msg = "Permission Denial: opening provider " + cpi.name
8176                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8177                    + ", uid=" + callingUid + ") that is not exported from uid "
8178                    + cpi.applicationInfo.uid;
8179        } else {
8180            msg = "Permission Denial: opening provider " + cpi.name
8181                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8182                    + ", uid=" + callingUid + ") requires "
8183                    + cpi.readPermission + " or " + cpi.writePermission;
8184        }
8185        Slog.w(TAG, msg);
8186        return msg;
8187    }
8188
8189    /**
8190     * Returns if the ContentProvider has granted a uri to callingUid
8191     */
8192    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8193        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8194        if (perms != null) {
8195            for (int i=perms.size()-1; i>=0; i--) {
8196                GrantUri grantUri = perms.keyAt(i);
8197                if (grantUri.sourceUserId == userId || !checkUser) {
8198                    if (matchesProvider(grantUri.uri, cpi)) {
8199                        return true;
8200                    }
8201                }
8202            }
8203        }
8204        return false;
8205    }
8206
8207    /**
8208     * Returns true if the uri authority is one of the authorities specified in the provider.
8209     */
8210    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8211        String uriAuth = uri.getAuthority();
8212        String cpiAuth = cpi.authority;
8213        if (cpiAuth.indexOf(';') == -1) {
8214            return cpiAuth.equals(uriAuth);
8215        }
8216        String[] cpiAuths = cpiAuth.split(";");
8217        int length = cpiAuths.length;
8218        for (int i = 0; i < length; i++) {
8219            if (cpiAuths[i].equals(uriAuth)) return true;
8220        }
8221        return false;
8222    }
8223
8224    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8225            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8226        if (r != null) {
8227            for (int i=0; i<r.conProviders.size(); i++) {
8228                ContentProviderConnection conn = r.conProviders.get(i);
8229                if (conn.provider == cpr) {
8230                    if (DEBUG_PROVIDER) Slog.v(TAG,
8231                            "Adding provider requested by "
8232                            + r.processName + " from process "
8233                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8234                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8235                    if (stable) {
8236                        conn.stableCount++;
8237                        conn.numStableIncs++;
8238                    } else {
8239                        conn.unstableCount++;
8240                        conn.numUnstableIncs++;
8241                    }
8242                    return conn;
8243                }
8244            }
8245            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8246            if (stable) {
8247                conn.stableCount = 1;
8248                conn.numStableIncs = 1;
8249            } else {
8250                conn.unstableCount = 1;
8251                conn.numUnstableIncs = 1;
8252            }
8253            cpr.connections.add(conn);
8254            r.conProviders.add(conn);
8255            return conn;
8256        }
8257        cpr.addExternalProcessHandleLocked(externalProcessToken);
8258        return null;
8259    }
8260
8261    boolean decProviderCountLocked(ContentProviderConnection conn,
8262            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8263        if (conn != null) {
8264            cpr = conn.provider;
8265            if (DEBUG_PROVIDER) Slog.v(TAG,
8266                    "Removing provider requested by "
8267                    + conn.client.processName + " from process "
8268                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8269                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8270            if (stable) {
8271                conn.stableCount--;
8272            } else {
8273                conn.unstableCount--;
8274            }
8275            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8276                cpr.connections.remove(conn);
8277                conn.client.conProviders.remove(conn);
8278                return true;
8279            }
8280            return false;
8281        }
8282        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8283        return false;
8284    }
8285
8286    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8287            String name, IBinder token, boolean stable, int userId) {
8288        ContentProviderRecord cpr;
8289        ContentProviderConnection conn = null;
8290        ProviderInfo cpi = null;
8291
8292        synchronized(this) {
8293            ProcessRecord r = null;
8294            if (caller != null) {
8295                r = getRecordForAppLocked(caller);
8296                if (r == null) {
8297                    throw new SecurityException(
8298                            "Unable to find app for caller " + caller
8299                          + " (pid=" + Binder.getCallingPid()
8300                          + ") when getting content provider " + name);
8301                }
8302            }
8303
8304            boolean checkCrossUser = true;
8305
8306            // First check if this content provider has been published...
8307            cpr = mProviderMap.getProviderByName(name, userId);
8308            // If that didn't work, check if it exists for user 0 and then
8309            // verify that it's a singleton provider before using it.
8310            if (cpr == null && userId != UserHandle.USER_OWNER) {
8311                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8312                if (cpr != null) {
8313                    cpi = cpr.info;
8314                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8315                            cpi.name, cpi.flags)
8316                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8317                        userId = UserHandle.USER_OWNER;
8318                        checkCrossUser = false;
8319                    } else {
8320                        cpr = null;
8321                        cpi = null;
8322                    }
8323                }
8324            }
8325
8326            boolean providerRunning = cpr != null;
8327            if (providerRunning) {
8328                cpi = cpr.info;
8329                String msg;
8330                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8331                        != null) {
8332                    throw new SecurityException(msg);
8333                }
8334
8335                if (r != null && cpr.canRunHere(r)) {
8336                    // This provider has been published or is in the process
8337                    // of being published...  but it is also allowed to run
8338                    // in the caller's process, so don't make a connection
8339                    // and just let the caller instantiate its own instance.
8340                    ContentProviderHolder holder = cpr.newHolder(null);
8341                    // don't give caller the provider object, it needs
8342                    // to make its own.
8343                    holder.provider = null;
8344                    return holder;
8345                }
8346
8347                final long origId = Binder.clearCallingIdentity();
8348
8349                // In this case the provider instance already exists, so we can
8350                // return it right away.
8351                conn = incProviderCountLocked(r, cpr, token, stable);
8352                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8353                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8354                        // If this is a perceptible app accessing the provider,
8355                        // make sure to count it as being accessed and thus
8356                        // back up on the LRU list.  This is good because
8357                        // content providers are often expensive to start.
8358                        updateLruProcessLocked(cpr.proc, false, null);
8359                    }
8360                }
8361
8362                if (cpr.proc != null) {
8363                    if (false) {
8364                        if (cpr.name.flattenToShortString().equals(
8365                                "com.android.providers.calendar/.CalendarProvider2")) {
8366                            Slog.v(TAG, "****************** KILLING "
8367                                + cpr.name.flattenToShortString());
8368                            Process.killProcess(cpr.proc.pid);
8369                        }
8370                    }
8371                    boolean success = updateOomAdjLocked(cpr.proc);
8372                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8373                    // NOTE: there is still a race here where a signal could be
8374                    // pending on the process even though we managed to update its
8375                    // adj level.  Not sure what to do about this, but at least
8376                    // the race is now smaller.
8377                    if (!success) {
8378                        // Uh oh...  it looks like the provider's process
8379                        // has been killed on us.  We need to wait for a new
8380                        // process to be started, and make sure its death
8381                        // doesn't kill our process.
8382                        Slog.i(TAG,
8383                                "Existing provider " + cpr.name.flattenToShortString()
8384                                + " is crashing; detaching " + r);
8385                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8386                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8387                        if (!lastRef) {
8388                            // This wasn't the last ref our process had on
8389                            // the provider...  we have now been killed, bail.
8390                            return null;
8391                        }
8392                        providerRunning = false;
8393                        conn = null;
8394                    }
8395                }
8396
8397                Binder.restoreCallingIdentity(origId);
8398            }
8399
8400            boolean singleton;
8401            if (!providerRunning) {
8402                try {
8403                    cpi = AppGlobals.getPackageManager().
8404                        resolveContentProvider(name,
8405                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8406                } catch (RemoteException ex) {
8407                }
8408                if (cpi == null) {
8409                    return null;
8410                }
8411                // If the provider is a singleton AND
8412                // (it's a call within the same user || the provider is a
8413                // privileged app)
8414                // Then allow connecting to the singleton provider
8415                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8416                        cpi.name, cpi.flags)
8417                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8418                if (singleton) {
8419                    userId = UserHandle.USER_OWNER;
8420                }
8421                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8422
8423                String msg;
8424                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8425                        != null) {
8426                    throw new SecurityException(msg);
8427                }
8428
8429                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8430                        && !cpi.processName.equals("system")) {
8431                    // If this content provider does not run in the system
8432                    // process, and the system is not yet ready to run other
8433                    // processes, then fail fast instead of hanging.
8434                    throw new IllegalArgumentException(
8435                            "Attempt to launch content provider before system ready");
8436                }
8437
8438                // Make sure that the user who owns this provider is started.  If not,
8439                // we don't want to allow it to run.
8440                if (mStartedUsers.get(userId) == null) {
8441                    Slog.w(TAG, "Unable to launch app "
8442                            + cpi.applicationInfo.packageName + "/"
8443                            + cpi.applicationInfo.uid + " for provider "
8444                            + name + ": user " + userId + " is stopped");
8445                    return null;
8446                }
8447
8448                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8449                cpr = mProviderMap.getProviderByClass(comp, userId);
8450                final boolean firstClass = cpr == null;
8451                if (firstClass) {
8452                    try {
8453                        ApplicationInfo ai =
8454                            AppGlobals.getPackageManager().
8455                                getApplicationInfo(
8456                                        cpi.applicationInfo.packageName,
8457                                        STOCK_PM_FLAGS, userId);
8458                        if (ai == null) {
8459                            Slog.w(TAG, "No package info for content provider "
8460                                    + cpi.name);
8461                            return null;
8462                        }
8463                        ai = getAppInfoForUser(ai, userId);
8464                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8465                    } catch (RemoteException ex) {
8466                        // pm is in same process, this will never happen.
8467                    }
8468                }
8469
8470                if (r != null && cpr.canRunHere(r)) {
8471                    // If this is a multiprocess provider, then just return its
8472                    // info and allow the caller to instantiate it.  Only do
8473                    // this if the provider is the same user as the caller's
8474                    // process, or can run as root (so can be in any process).
8475                    return cpr.newHolder(null);
8476                }
8477
8478                if (DEBUG_PROVIDER) {
8479                    RuntimeException e = new RuntimeException("here");
8480                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8481                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8482                }
8483
8484                // This is single process, and our app is now connecting to it.
8485                // See if we are already in the process of launching this
8486                // provider.
8487                final int N = mLaunchingProviders.size();
8488                int i;
8489                for (i=0; i<N; i++) {
8490                    if (mLaunchingProviders.get(i) == cpr) {
8491                        break;
8492                    }
8493                }
8494
8495                // If the provider is not already being launched, then get it
8496                // started.
8497                if (i >= N) {
8498                    final long origId = Binder.clearCallingIdentity();
8499
8500                    try {
8501                        // Content provider is now in use, its package can't be stopped.
8502                        try {
8503                            AppGlobals.getPackageManager().setPackageStoppedState(
8504                                    cpr.appInfo.packageName, false, userId);
8505                        } catch (RemoteException e) {
8506                        } catch (IllegalArgumentException e) {
8507                            Slog.w(TAG, "Failed trying to unstop package "
8508                                    + cpr.appInfo.packageName + ": " + e);
8509                        }
8510
8511                        // Use existing process if already started
8512                        ProcessRecord proc = getProcessRecordLocked(
8513                                cpi.processName, cpr.appInfo.uid, false);
8514                        if (proc != null && proc.thread != null) {
8515                            if (DEBUG_PROVIDER) {
8516                                Slog.d(TAG, "Installing in existing process " + proc);
8517                            }
8518                            proc.pubProviders.put(cpi.name, cpr);
8519                            try {
8520                                proc.thread.scheduleInstallProvider(cpi);
8521                            } catch (RemoteException e) {
8522                            }
8523                        } else {
8524                            proc = startProcessLocked(cpi.processName,
8525                                    cpr.appInfo, false, 0, "content provider",
8526                                    new ComponentName(cpi.applicationInfo.packageName,
8527                                            cpi.name), false, false, false);
8528                            if (proc == null) {
8529                                Slog.w(TAG, "Unable to launch app "
8530                                        + cpi.applicationInfo.packageName + "/"
8531                                        + cpi.applicationInfo.uid + " for provider "
8532                                        + name + ": process is bad");
8533                                return null;
8534                            }
8535                        }
8536                        cpr.launchingApp = proc;
8537                        mLaunchingProviders.add(cpr);
8538                    } finally {
8539                        Binder.restoreCallingIdentity(origId);
8540                    }
8541                }
8542
8543                // Make sure the provider is published (the same provider class
8544                // may be published under multiple names).
8545                if (firstClass) {
8546                    mProviderMap.putProviderByClass(comp, cpr);
8547                }
8548
8549                mProviderMap.putProviderByName(name, cpr);
8550                conn = incProviderCountLocked(r, cpr, token, stable);
8551                if (conn != null) {
8552                    conn.waiting = true;
8553                }
8554            }
8555        }
8556
8557        // Wait for the provider to be published...
8558        synchronized (cpr) {
8559            while (cpr.provider == null) {
8560                if (cpr.launchingApp == null) {
8561                    Slog.w(TAG, "Unable to launch app "
8562                            + cpi.applicationInfo.packageName + "/"
8563                            + cpi.applicationInfo.uid + " for provider "
8564                            + name + ": launching app became null");
8565                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8566                            UserHandle.getUserId(cpi.applicationInfo.uid),
8567                            cpi.applicationInfo.packageName,
8568                            cpi.applicationInfo.uid, name);
8569                    return null;
8570                }
8571                try {
8572                    if (DEBUG_MU) {
8573                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8574                                + cpr.launchingApp);
8575                    }
8576                    if (conn != null) {
8577                        conn.waiting = true;
8578                    }
8579                    cpr.wait();
8580                } catch (InterruptedException ex) {
8581                } finally {
8582                    if (conn != null) {
8583                        conn.waiting = false;
8584                    }
8585                }
8586            }
8587        }
8588        return cpr != null ? cpr.newHolder(conn) : null;
8589    }
8590
8591    @Override
8592    public final ContentProviderHolder getContentProvider(
8593            IApplicationThread caller, String name, int userId, boolean stable) {
8594        enforceNotIsolatedCaller("getContentProvider");
8595        if (caller == null) {
8596            String msg = "null IApplicationThread when getting content provider "
8597                    + name;
8598            Slog.w(TAG, msg);
8599            throw new SecurityException(msg);
8600        }
8601        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8602        // with cross-user grant.
8603        return getContentProviderImpl(caller, name, null, stable, userId);
8604    }
8605
8606    public ContentProviderHolder getContentProviderExternal(
8607            String name, int userId, IBinder token) {
8608        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8609            "Do not have permission in call getContentProviderExternal()");
8610        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8611                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8612        return getContentProviderExternalUnchecked(name, token, userId);
8613    }
8614
8615    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8616            IBinder token, int userId) {
8617        return getContentProviderImpl(null, name, token, true, userId);
8618    }
8619
8620    /**
8621     * Drop a content provider from a ProcessRecord's bookkeeping
8622     */
8623    public void removeContentProvider(IBinder connection, boolean stable) {
8624        enforceNotIsolatedCaller("removeContentProvider");
8625        long ident = Binder.clearCallingIdentity();
8626        try {
8627            synchronized (this) {
8628                ContentProviderConnection conn;
8629                try {
8630                    conn = (ContentProviderConnection)connection;
8631                } catch (ClassCastException e) {
8632                    String msg ="removeContentProvider: " + connection
8633                            + " not a ContentProviderConnection";
8634                    Slog.w(TAG, msg);
8635                    throw new IllegalArgumentException(msg);
8636                }
8637                if (conn == null) {
8638                    throw new NullPointerException("connection is null");
8639                }
8640                if (decProviderCountLocked(conn, null, null, stable)) {
8641                    updateOomAdjLocked();
8642                }
8643            }
8644        } finally {
8645            Binder.restoreCallingIdentity(ident);
8646        }
8647    }
8648
8649    public void removeContentProviderExternal(String name, IBinder token) {
8650        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8651            "Do not have permission in call removeContentProviderExternal()");
8652        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8653    }
8654
8655    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8656        synchronized (this) {
8657            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8658            if(cpr == null) {
8659                //remove from mProvidersByClass
8660                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8661                return;
8662            }
8663
8664            //update content provider record entry info
8665            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8666            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8667            if (localCpr.hasExternalProcessHandles()) {
8668                if (localCpr.removeExternalProcessHandleLocked(token)) {
8669                    updateOomAdjLocked();
8670                } else {
8671                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8672                            + " with no external reference for token: "
8673                            + token + ".");
8674                }
8675            } else {
8676                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8677                        + " with no external references.");
8678            }
8679        }
8680    }
8681
8682    public final void publishContentProviders(IApplicationThread caller,
8683            List<ContentProviderHolder> providers) {
8684        if (providers == null) {
8685            return;
8686        }
8687
8688        enforceNotIsolatedCaller("publishContentProviders");
8689        synchronized (this) {
8690            final ProcessRecord r = getRecordForAppLocked(caller);
8691            if (DEBUG_MU)
8692                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8693            if (r == null) {
8694                throw new SecurityException(
8695                        "Unable to find app for caller " + caller
8696                      + " (pid=" + Binder.getCallingPid()
8697                      + ") when publishing content providers");
8698            }
8699
8700            final long origId = Binder.clearCallingIdentity();
8701
8702            final int N = providers.size();
8703            for (int i=0; i<N; i++) {
8704                ContentProviderHolder src = providers.get(i);
8705                if (src == null || src.info == null || src.provider == null) {
8706                    continue;
8707                }
8708                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8709                if (DEBUG_MU)
8710                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8711                if (dst != null) {
8712                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8713                    mProviderMap.putProviderByClass(comp, dst);
8714                    String names[] = dst.info.authority.split(";");
8715                    for (int j = 0; j < names.length; j++) {
8716                        mProviderMap.putProviderByName(names[j], dst);
8717                    }
8718
8719                    int NL = mLaunchingProviders.size();
8720                    int j;
8721                    for (j=0; j<NL; j++) {
8722                        if (mLaunchingProviders.get(j) == dst) {
8723                            mLaunchingProviders.remove(j);
8724                            j--;
8725                            NL--;
8726                        }
8727                    }
8728                    synchronized (dst) {
8729                        dst.provider = src.provider;
8730                        dst.proc = r;
8731                        dst.notifyAll();
8732                    }
8733                    updateOomAdjLocked(r);
8734                }
8735            }
8736
8737            Binder.restoreCallingIdentity(origId);
8738        }
8739    }
8740
8741    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8742        ContentProviderConnection conn;
8743        try {
8744            conn = (ContentProviderConnection)connection;
8745        } catch (ClassCastException e) {
8746            String msg ="refContentProvider: " + connection
8747                    + " not a ContentProviderConnection";
8748            Slog.w(TAG, msg);
8749            throw new IllegalArgumentException(msg);
8750        }
8751        if (conn == null) {
8752            throw new NullPointerException("connection is null");
8753        }
8754
8755        synchronized (this) {
8756            if (stable > 0) {
8757                conn.numStableIncs += stable;
8758            }
8759            stable = conn.stableCount + stable;
8760            if (stable < 0) {
8761                throw new IllegalStateException("stableCount < 0: " + stable);
8762            }
8763
8764            if (unstable > 0) {
8765                conn.numUnstableIncs += unstable;
8766            }
8767            unstable = conn.unstableCount + unstable;
8768            if (unstable < 0) {
8769                throw new IllegalStateException("unstableCount < 0: " + unstable);
8770            }
8771
8772            if ((stable+unstable) <= 0) {
8773                throw new IllegalStateException("ref counts can't go to zero here: stable="
8774                        + stable + " unstable=" + unstable);
8775            }
8776            conn.stableCount = stable;
8777            conn.unstableCount = unstable;
8778            return !conn.dead;
8779        }
8780    }
8781
8782    public void unstableProviderDied(IBinder connection) {
8783        ContentProviderConnection conn;
8784        try {
8785            conn = (ContentProviderConnection)connection;
8786        } catch (ClassCastException e) {
8787            String msg ="refContentProvider: " + connection
8788                    + " not a ContentProviderConnection";
8789            Slog.w(TAG, msg);
8790            throw new IllegalArgumentException(msg);
8791        }
8792        if (conn == null) {
8793            throw new NullPointerException("connection is null");
8794        }
8795
8796        // Safely retrieve the content provider associated with the connection.
8797        IContentProvider provider;
8798        synchronized (this) {
8799            provider = conn.provider.provider;
8800        }
8801
8802        if (provider == null) {
8803            // Um, yeah, we're way ahead of you.
8804            return;
8805        }
8806
8807        // Make sure the caller is being honest with us.
8808        if (provider.asBinder().pingBinder()) {
8809            // Er, no, still looks good to us.
8810            synchronized (this) {
8811                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8812                        + " says " + conn + " died, but we don't agree");
8813                return;
8814            }
8815        }
8816
8817        // Well look at that!  It's dead!
8818        synchronized (this) {
8819            if (conn.provider.provider != provider) {
8820                // But something changed...  good enough.
8821                return;
8822            }
8823
8824            ProcessRecord proc = conn.provider.proc;
8825            if (proc == null || proc.thread == null) {
8826                // Seems like the process is already cleaned up.
8827                return;
8828            }
8829
8830            // As far as we're concerned, this is just like receiving a
8831            // death notification...  just a bit prematurely.
8832            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8833                    + ") early provider death");
8834            final long ident = Binder.clearCallingIdentity();
8835            try {
8836                appDiedLocked(proc, proc.pid, proc.thread);
8837            } finally {
8838                Binder.restoreCallingIdentity(ident);
8839            }
8840        }
8841    }
8842
8843    @Override
8844    public void appNotRespondingViaProvider(IBinder connection) {
8845        enforceCallingPermission(
8846                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8847
8848        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8849        if (conn == null) {
8850            Slog.w(TAG, "ContentProviderConnection is null");
8851            return;
8852        }
8853
8854        final ProcessRecord host = conn.provider.proc;
8855        if (host == null) {
8856            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8857            return;
8858        }
8859
8860        final long token = Binder.clearCallingIdentity();
8861        try {
8862            appNotResponding(host, null, null, false, "ContentProvider not responding");
8863        } finally {
8864            Binder.restoreCallingIdentity(token);
8865        }
8866    }
8867
8868    public final void installSystemProviders() {
8869        List<ProviderInfo> providers;
8870        synchronized (this) {
8871            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8872            providers = generateApplicationProvidersLocked(app);
8873            if (providers != null) {
8874                for (int i=providers.size()-1; i>=0; i--) {
8875                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8876                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8877                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8878                                + ": not system .apk");
8879                        providers.remove(i);
8880                    }
8881                }
8882            }
8883        }
8884        if (providers != null) {
8885            mSystemThread.installSystemProviders(providers);
8886        }
8887
8888        mCoreSettingsObserver = new CoreSettingsObserver(this);
8889
8890        //mUsageStatsService.monitorPackages();
8891    }
8892
8893    /**
8894     * Allows app to retrieve the MIME type of a URI without having permission
8895     * to access its content provider.
8896     *
8897     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8898     *
8899     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8900     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8901     */
8902    public String getProviderMimeType(Uri uri, int userId) {
8903        enforceNotIsolatedCaller("getProviderMimeType");
8904        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8905                userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null);
8906        final String name = uri.getAuthority();
8907        final long ident = Binder.clearCallingIdentity();
8908        ContentProviderHolder holder = null;
8909
8910        try {
8911            holder = getContentProviderExternalUnchecked(name, null, userId);
8912            if (holder != null) {
8913                return holder.provider.getType(uri);
8914            }
8915        } catch (RemoteException e) {
8916            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8917            return null;
8918        } finally {
8919            if (holder != null) {
8920                removeContentProviderExternalUnchecked(name, null, userId);
8921            }
8922            Binder.restoreCallingIdentity(ident);
8923        }
8924
8925        return null;
8926    }
8927
8928    // =========================================================
8929    // GLOBAL MANAGEMENT
8930    // =========================================================
8931
8932    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8933            boolean isolated) {
8934        String proc = customProcess != null ? customProcess : info.processName;
8935        BatteryStatsImpl.Uid.Proc ps = null;
8936        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8937        int uid = info.uid;
8938        if (isolated) {
8939            int userId = UserHandle.getUserId(uid);
8940            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8941            while (true) {
8942                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8943                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8944                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8945                }
8946                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8947                mNextIsolatedProcessUid++;
8948                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8949                    // No process for this uid, use it.
8950                    break;
8951                }
8952                stepsLeft--;
8953                if (stepsLeft <= 0) {
8954                    return null;
8955                }
8956            }
8957        }
8958        return new ProcessRecord(stats, info, proc, uid);
8959    }
8960
8961    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8962            String abiOverride) {
8963        ProcessRecord app;
8964        if (!isolated) {
8965            app = getProcessRecordLocked(info.processName, info.uid, true);
8966        } else {
8967            app = null;
8968        }
8969
8970        if (app == null) {
8971            app = newProcessRecordLocked(info, null, isolated);
8972            mProcessNames.put(info.processName, app.uid, app);
8973            if (isolated) {
8974                mIsolatedProcesses.put(app.uid, app);
8975            }
8976            updateLruProcessLocked(app, false, null);
8977            updateOomAdjLocked();
8978        }
8979
8980        // This package really, really can not be stopped.
8981        try {
8982            AppGlobals.getPackageManager().setPackageStoppedState(
8983                    info.packageName, false, UserHandle.getUserId(app.uid));
8984        } catch (RemoteException e) {
8985        } catch (IllegalArgumentException e) {
8986            Slog.w(TAG, "Failed trying to unstop package "
8987                    + info.packageName + ": " + e);
8988        }
8989
8990        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8991                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8992            app.persistent = true;
8993            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8994        }
8995        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8996            mPersistentStartingProcesses.add(app);
8997            startProcessLocked(app, "added application", app.processName,
8998                    abiOverride);
8999        }
9000
9001        return app;
9002    }
9003
9004    public void unhandledBack() {
9005        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9006                "unhandledBack()");
9007
9008        synchronized(this) {
9009            final long origId = Binder.clearCallingIdentity();
9010            try {
9011                getFocusedStack().unhandledBackLocked();
9012            } finally {
9013                Binder.restoreCallingIdentity(origId);
9014            }
9015        }
9016    }
9017
9018    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9019        enforceNotIsolatedCaller("openContentUri");
9020        final int userId = UserHandle.getCallingUserId();
9021        String name = uri.getAuthority();
9022        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9023        ParcelFileDescriptor pfd = null;
9024        if (cph != null) {
9025            // We record the binder invoker's uid in thread-local storage before
9026            // going to the content provider to open the file.  Later, in the code
9027            // that handles all permissions checks, we look for this uid and use
9028            // that rather than the Activity Manager's own uid.  The effect is that
9029            // we do the check against the caller's permissions even though it looks
9030            // to the content provider like the Activity Manager itself is making
9031            // the request.
9032            sCallerIdentity.set(new Identity(
9033                    Binder.getCallingPid(), Binder.getCallingUid()));
9034            try {
9035                pfd = cph.provider.openFile(null, uri, "r", null);
9036            } catch (FileNotFoundException e) {
9037                // do nothing; pfd will be returned null
9038            } finally {
9039                // Ensure that whatever happens, we clean up the identity state
9040                sCallerIdentity.remove();
9041            }
9042
9043            // We've got the fd now, so we're done with the provider.
9044            removeContentProviderExternalUnchecked(name, null, userId);
9045        } else {
9046            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9047        }
9048        return pfd;
9049    }
9050
9051    // Actually is sleeping or shutting down or whatever else in the future
9052    // is an inactive state.
9053    public boolean isSleepingOrShuttingDown() {
9054        return mSleeping || mShuttingDown;
9055    }
9056
9057    public boolean isSleeping() {
9058        return mSleeping;
9059    }
9060
9061    void goingToSleep() {
9062        synchronized(this) {
9063            mWentToSleep = true;
9064            updateEventDispatchingLocked();
9065            goToSleepIfNeededLocked();
9066        }
9067    }
9068
9069    void finishRunningVoiceLocked() {
9070        if (mRunningVoice) {
9071            mRunningVoice = false;
9072            goToSleepIfNeededLocked();
9073        }
9074    }
9075
9076    void goToSleepIfNeededLocked() {
9077        if (mWentToSleep && !mRunningVoice) {
9078            if (!mSleeping) {
9079                mSleeping = true;
9080                mStackSupervisor.goingToSleepLocked();
9081
9082                // Initialize the wake times of all processes.
9083                checkExcessivePowerUsageLocked(false);
9084                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9085                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9086                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9087            }
9088        }
9089    }
9090
9091    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9092        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9093            // Never persist the home stack.
9094            return;
9095        }
9096        mTaskPersister.wakeup(task, flush);
9097    }
9098
9099    @Override
9100    public boolean shutdown(int timeout) {
9101        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9102                != PackageManager.PERMISSION_GRANTED) {
9103            throw new SecurityException("Requires permission "
9104                    + android.Manifest.permission.SHUTDOWN);
9105        }
9106
9107        boolean timedout = false;
9108
9109        synchronized(this) {
9110            mShuttingDown = true;
9111            updateEventDispatchingLocked();
9112            timedout = mStackSupervisor.shutdownLocked(timeout);
9113        }
9114
9115        mAppOpsService.shutdown();
9116        if (mUsageStatsService != null) {
9117            mUsageStatsService.prepareShutdown();
9118        }
9119        mBatteryStatsService.shutdown();
9120        synchronized (this) {
9121            mProcessStats.shutdownLocked();
9122        }
9123        notifyTaskPersisterLocked(null, true);
9124
9125        return timedout;
9126    }
9127
9128    public final void activitySlept(IBinder token) {
9129        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9130
9131        final long origId = Binder.clearCallingIdentity();
9132
9133        synchronized (this) {
9134            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9135            if (r != null) {
9136                mStackSupervisor.activitySleptLocked(r);
9137            }
9138        }
9139
9140        Binder.restoreCallingIdentity(origId);
9141    }
9142
9143    void logLockScreen(String msg) {
9144        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9145                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9146                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9147                mStackSupervisor.mDismissKeyguardOnNextActivity);
9148    }
9149
9150    private void comeOutOfSleepIfNeededLocked() {
9151        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9152            if (mSleeping) {
9153                mSleeping = false;
9154                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9155            }
9156        }
9157    }
9158
9159    void wakingUp() {
9160        synchronized(this) {
9161            mWentToSleep = false;
9162            updateEventDispatchingLocked();
9163            comeOutOfSleepIfNeededLocked();
9164        }
9165    }
9166
9167    void startRunningVoiceLocked() {
9168        if (!mRunningVoice) {
9169            mRunningVoice = true;
9170            comeOutOfSleepIfNeededLocked();
9171        }
9172    }
9173
9174    private void updateEventDispatchingLocked() {
9175        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9176    }
9177
9178    public void setLockScreenShown(boolean shown) {
9179        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9180                != PackageManager.PERMISSION_GRANTED) {
9181            throw new SecurityException("Requires permission "
9182                    + android.Manifest.permission.DEVICE_POWER);
9183        }
9184
9185        synchronized(this) {
9186            long ident = Binder.clearCallingIdentity();
9187            try {
9188                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9189                mLockScreenShown = shown;
9190                comeOutOfSleepIfNeededLocked();
9191            } finally {
9192                Binder.restoreCallingIdentity(ident);
9193            }
9194        }
9195    }
9196
9197    @Override
9198    public void stopAppSwitches() {
9199        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9200                != PackageManager.PERMISSION_GRANTED) {
9201            throw new SecurityException("Requires permission "
9202                    + android.Manifest.permission.STOP_APP_SWITCHES);
9203        }
9204
9205        synchronized(this) {
9206            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9207                    + APP_SWITCH_DELAY_TIME;
9208            mDidAppSwitch = false;
9209            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9210            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9211            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9212        }
9213    }
9214
9215    public void resumeAppSwitches() {
9216        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9217                != PackageManager.PERMISSION_GRANTED) {
9218            throw new SecurityException("Requires permission "
9219                    + android.Manifest.permission.STOP_APP_SWITCHES);
9220        }
9221
9222        synchronized(this) {
9223            // Note that we don't execute any pending app switches... we will
9224            // let those wait until either the timeout, or the next start
9225            // activity request.
9226            mAppSwitchesAllowedTime = 0;
9227        }
9228    }
9229
9230    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9231            String name) {
9232        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9233            return true;
9234        }
9235
9236        final int perm = checkComponentPermission(
9237                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9238                callingUid, -1, true);
9239        if (perm == PackageManager.PERMISSION_GRANTED) {
9240            return true;
9241        }
9242
9243        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9244        return false;
9245    }
9246
9247    public void setDebugApp(String packageName, boolean waitForDebugger,
9248            boolean persistent) {
9249        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9250                "setDebugApp()");
9251
9252        long ident = Binder.clearCallingIdentity();
9253        try {
9254            // Note that this is not really thread safe if there are multiple
9255            // callers into it at the same time, but that's not a situation we
9256            // care about.
9257            if (persistent) {
9258                final ContentResolver resolver = mContext.getContentResolver();
9259                Settings.Global.putString(
9260                    resolver, Settings.Global.DEBUG_APP,
9261                    packageName);
9262                Settings.Global.putInt(
9263                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9264                    waitForDebugger ? 1 : 0);
9265            }
9266
9267            synchronized (this) {
9268                if (!persistent) {
9269                    mOrigDebugApp = mDebugApp;
9270                    mOrigWaitForDebugger = mWaitForDebugger;
9271                }
9272                mDebugApp = packageName;
9273                mWaitForDebugger = waitForDebugger;
9274                mDebugTransient = !persistent;
9275                if (packageName != null) {
9276                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9277                            false, UserHandle.USER_ALL, "set debug app");
9278                }
9279            }
9280        } finally {
9281            Binder.restoreCallingIdentity(ident);
9282        }
9283    }
9284
9285    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9286        synchronized (this) {
9287            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9288            if (!isDebuggable) {
9289                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9290                    throw new SecurityException("Process not debuggable: " + app.packageName);
9291                }
9292            }
9293
9294            mOpenGlTraceApp = processName;
9295        }
9296    }
9297
9298    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9299            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9300        synchronized (this) {
9301            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9302            if (!isDebuggable) {
9303                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9304                    throw new SecurityException("Process not debuggable: " + app.packageName);
9305                }
9306            }
9307            mProfileApp = processName;
9308            mProfileFile = profileFile;
9309            if (mProfileFd != null) {
9310                try {
9311                    mProfileFd.close();
9312                } catch (IOException e) {
9313                }
9314                mProfileFd = null;
9315            }
9316            mProfileFd = profileFd;
9317            mProfileType = 0;
9318            mAutoStopProfiler = autoStopProfiler;
9319        }
9320    }
9321
9322    @Override
9323    public void setAlwaysFinish(boolean enabled) {
9324        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9325                "setAlwaysFinish()");
9326
9327        Settings.Global.putInt(
9328                mContext.getContentResolver(),
9329                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9330
9331        synchronized (this) {
9332            mAlwaysFinishActivities = enabled;
9333        }
9334    }
9335
9336    @Override
9337    public void setActivityController(IActivityController controller) {
9338        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9339                "setActivityController()");
9340        synchronized (this) {
9341            mController = controller;
9342            Watchdog.getInstance().setActivityController(controller);
9343        }
9344    }
9345
9346    @Override
9347    public void setUserIsMonkey(boolean userIsMonkey) {
9348        synchronized (this) {
9349            synchronized (mPidsSelfLocked) {
9350                final int callingPid = Binder.getCallingPid();
9351                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9352                if (precessRecord == null) {
9353                    throw new SecurityException("Unknown process: " + callingPid);
9354                }
9355                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9356                    throw new SecurityException("Only an instrumentation process "
9357                            + "with a UiAutomation can call setUserIsMonkey");
9358                }
9359            }
9360            mUserIsMonkey = userIsMonkey;
9361        }
9362    }
9363
9364    @Override
9365    public boolean isUserAMonkey() {
9366        synchronized (this) {
9367            // If there is a controller also implies the user is a monkey.
9368            return (mUserIsMonkey || mController != null);
9369        }
9370    }
9371
9372    public void requestBugReport() {
9373        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9374        SystemProperties.set("ctl.start", "bugreport");
9375    }
9376
9377    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9378        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9379    }
9380
9381    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9382        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9383            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9384        }
9385        return KEY_DISPATCHING_TIMEOUT;
9386    }
9387
9388    @Override
9389    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9390        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9391                != PackageManager.PERMISSION_GRANTED) {
9392            throw new SecurityException("Requires permission "
9393                    + android.Manifest.permission.FILTER_EVENTS);
9394        }
9395        ProcessRecord proc;
9396        long timeout;
9397        synchronized (this) {
9398            synchronized (mPidsSelfLocked) {
9399                proc = mPidsSelfLocked.get(pid);
9400            }
9401            timeout = getInputDispatchingTimeoutLocked(proc);
9402        }
9403
9404        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9405            return -1;
9406        }
9407
9408        return timeout;
9409    }
9410
9411    /**
9412     * Handle input dispatching timeouts.
9413     * Returns whether input dispatching should be aborted or not.
9414     */
9415    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9416            final ActivityRecord activity, final ActivityRecord parent,
9417            final boolean aboveSystem, String reason) {
9418        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9419                != PackageManager.PERMISSION_GRANTED) {
9420            throw new SecurityException("Requires permission "
9421                    + android.Manifest.permission.FILTER_EVENTS);
9422        }
9423
9424        final String annotation;
9425        if (reason == null) {
9426            annotation = "Input dispatching timed out";
9427        } else {
9428            annotation = "Input dispatching timed out (" + reason + ")";
9429        }
9430
9431        if (proc != null) {
9432            synchronized (this) {
9433                if (proc.debugging) {
9434                    return false;
9435                }
9436
9437                if (mDidDexOpt) {
9438                    // Give more time since we were dexopting.
9439                    mDidDexOpt = false;
9440                    return false;
9441                }
9442
9443                if (proc.instrumentationClass != null) {
9444                    Bundle info = new Bundle();
9445                    info.putString("shortMsg", "keyDispatchingTimedOut");
9446                    info.putString("longMsg", annotation);
9447                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9448                    return true;
9449                }
9450            }
9451            mHandler.post(new Runnable() {
9452                @Override
9453                public void run() {
9454                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9455                }
9456            });
9457        }
9458
9459        return true;
9460    }
9461
9462    public Bundle getAssistContextExtras(int requestType) {
9463        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9464                "getAssistContextExtras()");
9465        PendingAssistExtras pae;
9466        Bundle extras = new Bundle();
9467        synchronized (this) {
9468            ActivityRecord activity = getFocusedStack().mResumedActivity;
9469            if (activity == null) {
9470                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9471                return null;
9472            }
9473            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9474            if (activity.app == null || activity.app.thread == null) {
9475                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9476                return extras;
9477            }
9478            if (activity.app.pid == Binder.getCallingPid()) {
9479                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9480                return extras;
9481            }
9482            pae = new PendingAssistExtras(activity);
9483            try {
9484                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9485                        requestType);
9486                mPendingAssistExtras.add(pae);
9487                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9488            } catch (RemoteException e) {
9489                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9490                return extras;
9491            }
9492        }
9493        synchronized (pae) {
9494            while (!pae.haveResult) {
9495                try {
9496                    pae.wait();
9497                } catch (InterruptedException e) {
9498                }
9499            }
9500            if (pae.result != null) {
9501                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9502            }
9503        }
9504        synchronized (this) {
9505            mPendingAssistExtras.remove(pae);
9506            mHandler.removeCallbacks(pae);
9507        }
9508        return extras;
9509    }
9510
9511    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9512        PendingAssistExtras pae = (PendingAssistExtras)token;
9513        synchronized (pae) {
9514            pae.result = extras;
9515            pae.haveResult = true;
9516            pae.notifyAll();
9517        }
9518    }
9519
9520    public void registerProcessObserver(IProcessObserver observer) {
9521        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9522                "registerProcessObserver()");
9523        synchronized (this) {
9524            mProcessObservers.register(observer);
9525        }
9526    }
9527
9528    @Override
9529    public void unregisterProcessObserver(IProcessObserver observer) {
9530        synchronized (this) {
9531            mProcessObservers.unregister(observer);
9532        }
9533    }
9534
9535    @Override
9536    public boolean convertFromTranslucent(IBinder token) {
9537        final long origId = Binder.clearCallingIdentity();
9538        try {
9539            synchronized (this) {
9540                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9541                if (r == null) {
9542                    return false;
9543                }
9544                if (r.changeWindowTranslucency(true)) {
9545                    mWindowManager.setAppFullscreen(token, true);
9546                    r.task.stack.releaseMediaResources();
9547                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9548                    return true;
9549                }
9550                return false;
9551            }
9552        } finally {
9553            Binder.restoreCallingIdentity(origId);
9554        }
9555    }
9556
9557    @Override
9558    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9559        final long origId = Binder.clearCallingIdentity();
9560        try {
9561            synchronized (this) {
9562                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9563                if (r == null) {
9564                    return false;
9565                }
9566                int index = r.task.mActivities.lastIndexOf(r);
9567                if (index > 0) {
9568                    ActivityRecord under = r.task.mActivities.get(index - 1);
9569                    under.returningOptions = options;
9570                }
9571                if (r.changeWindowTranslucency(false)) {
9572                    r.task.stack.convertToTranslucent(r);
9573                    mWindowManager.setAppFullscreen(token, false);
9574                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9575                    return true;
9576                } else {
9577                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9578                    return false;
9579                }
9580            }
9581        } finally {
9582            Binder.restoreCallingIdentity(origId);
9583        }
9584    }
9585
9586    @Override
9587    public boolean setMediaPlaying(IBinder token, boolean playing) {
9588        final long origId = Binder.clearCallingIdentity();
9589        try {
9590            synchronized (this) {
9591                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9592                if (r != null) {
9593                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9594                }
9595            }
9596            return false;
9597        } finally {
9598            Binder.restoreCallingIdentity(origId);
9599        }
9600    }
9601
9602    @Override
9603    public boolean isBackgroundMediaPlaying(IBinder token) {
9604        final long origId = Binder.clearCallingIdentity();
9605        try {
9606            synchronized (this) {
9607                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9608                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9609                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9610                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9611                return playing;
9612            }
9613        } finally {
9614            Binder.restoreCallingIdentity(origId);
9615        }
9616    }
9617
9618    @Override
9619    public ActivityOptions getActivityOptions(IBinder token) {
9620        final long origId = Binder.clearCallingIdentity();
9621        try {
9622            synchronized (this) {
9623                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9624                if (r != null) {
9625                    final ActivityOptions activityOptions = r.pendingOptions;
9626                    r.pendingOptions = null;
9627                    return activityOptions;
9628                }
9629                return null;
9630            }
9631        } finally {
9632            Binder.restoreCallingIdentity(origId);
9633        }
9634    }
9635
9636    @Override
9637    public void setImmersive(IBinder token, boolean immersive) {
9638        synchronized(this) {
9639            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9640            if (r == null) {
9641                throw new IllegalArgumentException();
9642            }
9643            r.immersive = immersive;
9644
9645            // update associated state if we're frontmost
9646            if (r == mFocusedActivity) {
9647                if (DEBUG_IMMERSIVE) {
9648                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9649                }
9650                applyUpdateLockStateLocked(r);
9651            }
9652        }
9653    }
9654
9655    @Override
9656    public boolean isImmersive(IBinder token) {
9657        synchronized (this) {
9658            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9659            if (r == null) {
9660                throw new IllegalArgumentException();
9661            }
9662            return r.immersive;
9663        }
9664    }
9665
9666    public boolean isTopActivityImmersive() {
9667        enforceNotIsolatedCaller("startActivity");
9668        synchronized (this) {
9669            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9670            return (r != null) ? r.immersive : false;
9671        }
9672    }
9673
9674    @Override
9675    public boolean isTopOfTask(IBinder token) {
9676        synchronized (this) {
9677            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9678            if (r == null) {
9679                throw new IllegalArgumentException();
9680            }
9681            return r.task.getTopActivity() == r;
9682        }
9683    }
9684
9685    public final void enterSafeMode() {
9686        synchronized(this) {
9687            // It only makes sense to do this before the system is ready
9688            // and started launching other packages.
9689            if (!mSystemReady) {
9690                try {
9691                    AppGlobals.getPackageManager().enterSafeMode();
9692                } catch (RemoteException e) {
9693                }
9694            }
9695
9696            mSafeMode = true;
9697        }
9698    }
9699
9700    public final void showSafeModeOverlay() {
9701        View v = LayoutInflater.from(mContext).inflate(
9702                com.android.internal.R.layout.safe_mode, null);
9703        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9704        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9705        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9706        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9707        lp.gravity = Gravity.BOTTOM | Gravity.START;
9708        lp.format = v.getBackground().getOpacity();
9709        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9710                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9711        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9712        ((WindowManager)mContext.getSystemService(
9713                Context.WINDOW_SERVICE)).addView(v, lp);
9714    }
9715
9716    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9717        if (!(sender instanceof PendingIntentRecord)) {
9718            return;
9719        }
9720        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9721        synchronized (stats) {
9722            if (mBatteryStatsService.isOnBattery()) {
9723                mBatteryStatsService.enforceCallingPermission();
9724                PendingIntentRecord rec = (PendingIntentRecord)sender;
9725                int MY_UID = Binder.getCallingUid();
9726                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9727                BatteryStatsImpl.Uid.Pkg pkg =
9728                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9729                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9730                pkg.incWakeupsLocked();
9731            }
9732        }
9733    }
9734
9735    public boolean killPids(int[] pids, String pReason, boolean secure) {
9736        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9737            throw new SecurityException("killPids only available to the system");
9738        }
9739        String reason = (pReason == null) ? "Unknown" : pReason;
9740        // XXX Note: don't acquire main activity lock here, because the window
9741        // manager calls in with its locks held.
9742
9743        boolean killed = false;
9744        synchronized (mPidsSelfLocked) {
9745            int[] types = new int[pids.length];
9746            int worstType = 0;
9747            for (int i=0; i<pids.length; i++) {
9748                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9749                if (proc != null) {
9750                    int type = proc.setAdj;
9751                    types[i] = type;
9752                    if (type > worstType) {
9753                        worstType = type;
9754                    }
9755                }
9756            }
9757
9758            // If the worst oom_adj is somewhere in the cached proc LRU range,
9759            // then constrain it so we will kill all cached procs.
9760            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9761                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9762                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9763            }
9764
9765            // If this is not a secure call, don't let it kill processes that
9766            // are important.
9767            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9768                worstType = ProcessList.SERVICE_ADJ;
9769            }
9770
9771            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9772            for (int i=0; i<pids.length; i++) {
9773                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9774                if (proc == null) {
9775                    continue;
9776                }
9777                int adj = proc.setAdj;
9778                if (adj >= worstType && !proc.killedByAm) {
9779                    killUnneededProcessLocked(proc, reason);
9780                    killed = true;
9781                }
9782            }
9783        }
9784        return killed;
9785    }
9786
9787    @Override
9788    public void killUid(int uid, String reason) {
9789        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9790            throw new SecurityException("killUid only available to the system");
9791        }
9792        synchronized (this) {
9793            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9794                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9795                    reason != null ? reason : "kill uid");
9796        }
9797    }
9798
9799    @Override
9800    public boolean killProcessesBelowForeground(String reason) {
9801        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9802            throw new SecurityException("killProcessesBelowForeground() only available to system");
9803        }
9804
9805        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9806    }
9807
9808    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9809        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9810            throw new SecurityException("killProcessesBelowAdj() only available to system");
9811        }
9812
9813        boolean killed = false;
9814        synchronized (mPidsSelfLocked) {
9815            final int size = mPidsSelfLocked.size();
9816            for (int i = 0; i < size; i++) {
9817                final int pid = mPidsSelfLocked.keyAt(i);
9818                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9819                if (proc == null) continue;
9820
9821                final int adj = proc.setAdj;
9822                if (adj > belowAdj && !proc.killedByAm) {
9823                    killUnneededProcessLocked(proc, reason);
9824                    killed = true;
9825                }
9826            }
9827        }
9828        return killed;
9829    }
9830
9831    @Override
9832    public void hang(final IBinder who, boolean allowRestart) {
9833        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9834                != PackageManager.PERMISSION_GRANTED) {
9835            throw new SecurityException("Requires permission "
9836                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9837        }
9838
9839        final IBinder.DeathRecipient death = new DeathRecipient() {
9840            @Override
9841            public void binderDied() {
9842                synchronized (this) {
9843                    notifyAll();
9844                }
9845            }
9846        };
9847
9848        try {
9849            who.linkToDeath(death, 0);
9850        } catch (RemoteException e) {
9851            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9852            return;
9853        }
9854
9855        synchronized (this) {
9856            Watchdog.getInstance().setAllowRestart(allowRestart);
9857            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9858            synchronized (death) {
9859                while (who.isBinderAlive()) {
9860                    try {
9861                        death.wait();
9862                    } catch (InterruptedException e) {
9863                    }
9864                }
9865            }
9866            Watchdog.getInstance().setAllowRestart(true);
9867        }
9868    }
9869
9870    @Override
9871    public void restart() {
9872        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9873                != PackageManager.PERMISSION_GRANTED) {
9874            throw new SecurityException("Requires permission "
9875                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9876        }
9877
9878        Log.i(TAG, "Sending shutdown broadcast...");
9879
9880        BroadcastReceiver br = new BroadcastReceiver() {
9881            @Override public void onReceive(Context context, Intent intent) {
9882                // Now the broadcast is done, finish up the low-level shutdown.
9883                Log.i(TAG, "Shutting down activity manager...");
9884                shutdown(10000);
9885                Log.i(TAG, "Shutdown complete, restarting!");
9886                Process.killProcess(Process.myPid());
9887                System.exit(10);
9888            }
9889        };
9890
9891        // First send the high-level shut down broadcast.
9892        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9893        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9894        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9895        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9896        mContext.sendOrderedBroadcastAsUser(intent,
9897                UserHandle.ALL, null, br, mHandler, 0, null, null);
9898        */
9899        br.onReceive(mContext, intent);
9900    }
9901
9902    private long getLowRamTimeSinceIdle(long now) {
9903        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9904    }
9905
9906    @Override
9907    public void performIdleMaintenance() {
9908        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9909                != PackageManager.PERMISSION_GRANTED) {
9910            throw new SecurityException("Requires permission "
9911                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9912        }
9913
9914        synchronized (this) {
9915            final long now = SystemClock.uptimeMillis();
9916            final long timeSinceLastIdle = now - mLastIdleTime;
9917            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9918            mLastIdleTime = now;
9919            mLowRamTimeSinceLastIdle = 0;
9920            if (mLowRamStartTime != 0) {
9921                mLowRamStartTime = now;
9922            }
9923
9924            StringBuilder sb = new StringBuilder(128);
9925            sb.append("Idle maintenance over ");
9926            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9927            sb.append(" low RAM for ");
9928            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9929            Slog.i(TAG, sb.toString());
9930
9931            // If at least 1/3 of our time since the last idle period has been spent
9932            // with RAM low, then we want to kill processes.
9933            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9934
9935            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9936                ProcessRecord proc = mLruProcesses.get(i);
9937                if (proc.notCachedSinceIdle) {
9938                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9939                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9940                        if (doKilling && proc.initialIdlePss != 0
9941                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9942                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9943                                    + " from " + proc.initialIdlePss + ")");
9944                        }
9945                    }
9946                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9947                    proc.notCachedSinceIdle = true;
9948                    proc.initialIdlePss = 0;
9949                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9950                            isSleeping(), now);
9951                }
9952            }
9953
9954            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9955            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9956        }
9957    }
9958
9959    private void retrieveSettings() {
9960        final ContentResolver resolver = mContext.getContentResolver();
9961        String debugApp = Settings.Global.getString(
9962            resolver, Settings.Global.DEBUG_APP);
9963        boolean waitForDebugger = Settings.Global.getInt(
9964            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9965        boolean alwaysFinishActivities = Settings.Global.getInt(
9966            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9967        boolean forceRtl = Settings.Global.getInt(
9968                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9969        // Transfer any global setting for forcing RTL layout, into a System Property
9970        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9971
9972        Configuration configuration = new Configuration();
9973        Settings.System.getConfiguration(resolver, configuration);
9974        if (forceRtl) {
9975            // This will take care of setting the correct layout direction flags
9976            configuration.setLayoutDirection(configuration.locale);
9977        }
9978
9979        synchronized (this) {
9980            mDebugApp = mOrigDebugApp = debugApp;
9981            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9982            mAlwaysFinishActivities = alwaysFinishActivities;
9983            // This happens before any activities are started, so we can
9984            // change mConfiguration in-place.
9985            updateConfigurationLocked(configuration, null, false, true);
9986            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9987        }
9988    }
9989
9990    public boolean testIsSystemReady() {
9991        // no need to synchronize(this) just to read & return the value
9992        return mSystemReady;
9993    }
9994
9995    private static File getCalledPreBootReceiversFile() {
9996        File dataDir = Environment.getDataDirectory();
9997        File systemDir = new File(dataDir, "system");
9998        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
9999        return fname;
10000    }
10001
10002    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10003        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10004        File file = getCalledPreBootReceiversFile();
10005        FileInputStream fis = null;
10006        try {
10007            fis = new FileInputStream(file);
10008            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10009            int fvers = dis.readInt();
10010            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10011                String vers = dis.readUTF();
10012                String codename = dis.readUTF();
10013                String build = dis.readUTF();
10014                if (android.os.Build.VERSION.RELEASE.equals(vers)
10015                        && android.os.Build.VERSION.CODENAME.equals(codename)
10016                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10017                    int num = dis.readInt();
10018                    while (num > 0) {
10019                        num--;
10020                        String pkg = dis.readUTF();
10021                        String cls = dis.readUTF();
10022                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10023                    }
10024                }
10025            }
10026        } catch (FileNotFoundException e) {
10027        } catch (IOException e) {
10028            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10029        } finally {
10030            if (fis != null) {
10031                try {
10032                    fis.close();
10033                } catch (IOException e) {
10034                }
10035            }
10036        }
10037        return lastDoneReceivers;
10038    }
10039
10040    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10041        File file = getCalledPreBootReceiversFile();
10042        FileOutputStream fos = null;
10043        DataOutputStream dos = null;
10044        try {
10045            fos = new FileOutputStream(file);
10046            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10047            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10048            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10049            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10050            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10051            dos.writeInt(list.size());
10052            for (int i=0; i<list.size(); i++) {
10053                dos.writeUTF(list.get(i).getPackageName());
10054                dos.writeUTF(list.get(i).getClassName());
10055            }
10056        } catch (IOException e) {
10057            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10058            file.delete();
10059        } finally {
10060            FileUtils.sync(fos);
10061            if (dos != null) {
10062                try {
10063                    dos.close();
10064                } catch (IOException e) {
10065                    // TODO Auto-generated catch block
10066                    e.printStackTrace();
10067                }
10068            }
10069        }
10070    }
10071
10072    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10073            ArrayList<ComponentName> doneReceivers, int userId) {
10074        boolean waitingUpdate = false;
10075        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10076        List<ResolveInfo> ris = null;
10077        try {
10078            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10079                    intent, null, 0, userId);
10080        } catch (RemoteException e) {
10081        }
10082        if (ris != null) {
10083            for (int i=ris.size()-1; i>=0; i--) {
10084                if ((ris.get(i).activityInfo.applicationInfo.flags
10085                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10086                    ris.remove(i);
10087                }
10088            }
10089            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10090
10091            // For User 0, load the version number. When delivering to a new user, deliver
10092            // to all receivers.
10093            if (userId == UserHandle.USER_OWNER) {
10094                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10095                for (int i=0; i<ris.size(); i++) {
10096                    ActivityInfo ai = ris.get(i).activityInfo;
10097                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10098                    if (lastDoneReceivers.contains(comp)) {
10099                        // We already did the pre boot receiver for this app with the current
10100                        // platform version, so don't do it again...
10101                        ris.remove(i);
10102                        i--;
10103                        // ...however, do keep it as one that has been done, so we don't
10104                        // forget about it when rewriting the file of last done receivers.
10105                        doneReceivers.add(comp);
10106                    }
10107                }
10108            }
10109
10110            // If primary user, send broadcast to all available users, else just to userId
10111            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10112                    : new int[] { userId };
10113            for (int i = 0; i < ris.size(); i++) {
10114                ActivityInfo ai = ris.get(i).activityInfo;
10115                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10116                doneReceivers.add(comp);
10117                intent.setComponent(comp);
10118                for (int j=0; j<users.length; j++) {
10119                    IIntentReceiver finisher = null;
10120                    // On last receiver and user, set up a completion callback
10121                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10122                        finisher = new IIntentReceiver.Stub() {
10123                            public void performReceive(Intent intent, int resultCode,
10124                                    String data, Bundle extras, boolean ordered,
10125                                    boolean sticky, int sendingUser) {
10126                                // The raw IIntentReceiver interface is called
10127                                // with the AM lock held, so redispatch to
10128                                // execute our code without the lock.
10129                                mHandler.post(onFinishCallback);
10130                            }
10131                        };
10132                    }
10133                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10134                            + " for user " + users[j]);
10135                    broadcastIntentLocked(null, null, intent, null, finisher,
10136                            0, null, null, null, AppOpsManager.OP_NONE,
10137                            true, false, MY_PID, Process.SYSTEM_UID,
10138                            users[j]);
10139                    if (finisher != null) {
10140                        waitingUpdate = true;
10141                    }
10142                }
10143            }
10144        }
10145
10146        return waitingUpdate;
10147    }
10148
10149    public void systemReady(final Runnable goingCallback) {
10150        synchronized(this) {
10151            if (mSystemReady) {
10152                // If we're done calling all the receivers, run the next "boot phase" passed in
10153                // by the SystemServer
10154                if (goingCallback != null) {
10155                    goingCallback.run();
10156                }
10157                return;
10158            }
10159
10160            // Make sure we have the current profile info, since it is needed for
10161            // security checks.
10162            updateCurrentProfileIdsLocked();
10163
10164            if (mRecentTasks == null) {
10165                mRecentTasks = mTaskPersister.restoreTasksLocked();
10166                if (!mRecentTasks.isEmpty()) {
10167                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10168                }
10169                mTaskPersister.startPersisting();
10170            }
10171
10172            // Check to see if there are any update receivers to run.
10173            if (!mDidUpdate) {
10174                if (mWaitingUpdate) {
10175                    return;
10176                }
10177                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10178                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10179                    public void run() {
10180                        synchronized (ActivityManagerService.this) {
10181                            mDidUpdate = true;
10182                        }
10183                        writeLastDonePreBootReceivers(doneReceivers);
10184                        showBootMessage(mContext.getText(
10185                                R.string.android_upgrading_complete),
10186                                false);
10187                        systemReady(goingCallback);
10188                    }
10189                }, doneReceivers, UserHandle.USER_OWNER);
10190
10191                if (mWaitingUpdate) {
10192                    return;
10193                }
10194                mDidUpdate = true;
10195            }
10196
10197            mAppOpsService.systemReady();
10198            mSystemReady = true;
10199        }
10200
10201        ArrayList<ProcessRecord> procsToKill = null;
10202        synchronized(mPidsSelfLocked) {
10203            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10204                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10205                if (!isAllowedWhileBooting(proc.info)){
10206                    if (procsToKill == null) {
10207                        procsToKill = new ArrayList<ProcessRecord>();
10208                    }
10209                    procsToKill.add(proc);
10210                }
10211            }
10212        }
10213
10214        synchronized(this) {
10215            if (procsToKill != null) {
10216                for (int i=procsToKill.size()-1; i>=0; i--) {
10217                    ProcessRecord proc = procsToKill.get(i);
10218                    Slog.i(TAG, "Removing system update proc: " + proc);
10219                    removeProcessLocked(proc, true, false, "system update done");
10220                }
10221            }
10222
10223            // Now that we have cleaned up any update processes, we
10224            // are ready to start launching real processes and know that
10225            // we won't trample on them any more.
10226            mProcessesReady = true;
10227        }
10228
10229        Slog.i(TAG, "System now ready");
10230        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10231            SystemClock.uptimeMillis());
10232
10233        synchronized(this) {
10234            // Make sure we have no pre-ready processes sitting around.
10235
10236            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10237                ResolveInfo ri = mContext.getPackageManager()
10238                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10239                                STOCK_PM_FLAGS);
10240                CharSequence errorMsg = null;
10241                if (ri != null) {
10242                    ActivityInfo ai = ri.activityInfo;
10243                    ApplicationInfo app = ai.applicationInfo;
10244                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10245                        mTopAction = Intent.ACTION_FACTORY_TEST;
10246                        mTopData = null;
10247                        mTopComponent = new ComponentName(app.packageName,
10248                                ai.name);
10249                    } else {
10250                        errorMsg = mContext.getResources().getText(
10251                                com.android.internal.R.string.factorytest_not_system);
10252                    }
10253                } else {
10254                    errorMsg = mContext.getResources().getText(
10255                            com.android.internal.R.string.factorytest_no_action);
10256                }
10257                if (errorMsg != null) {
10258                    mTopAction = null;
10259                    mTopData = null;
10260                    mTopComponent = null;
10261                    Message msg = Message.obtain();
10262                    msg.what = SHOW_FACTORY_ERROR_MSG;
10263                    msg.getData().putCharSequence("msg", errorMsg);
10264                    mHandler.sendMessage(msg);
10265                }
10266            }
10267        }
10268
10269        retrieveSettings();
10270
10271        synchronized (this) {
10272            readGrantedUriPermissionsLocked();
10273        }
10274
10275        if (goingCallback != null) goingCallback.run();
10276
10277        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10278                Integer.toString(mCurrentUserId), mCurrentUserId);
10279        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10280                Integer.toString(mCurrentUserId), mCurrentUserId);
10281        mSystemServiceManager.startUser(mCurrentUserId);
10282
10283        synchronized (this) {
10284            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10285                try {
10286                    List apps = AppGlobals.getPackageManager().
10287                        getPersistentApplications(STOCK_PM_FLAGS);
10288                    if (apps != null) {
10289                        int N = apps.size();
10290                        int i;
10291                        for (i=0; i<N; i++) {
10292                            ApplicationInfo info
10293                                = (ApplicationInfo)apps.get(i);
10294                            if (info != null &&
10295                                    !info.packageName.equals("android")) {
10296                                addAppLocked(info, false, null /* ABI override */);
10297                            }
10298                        }
10299                    }
10300                } catch (RemoteException ex) {
10301                    // pm is in same process, this will never happen.
10302                }
10303            }
10304
10305            // Start up initial activity.
10306            mBooting = true;
10307
10308            try {
10309                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10310                    Message msg = Message.obtain();
10311                    msg.what = SHOW_UID_ERROR_MSG;
10312                    mHandler.sendMessage(msg);
10313                }
10314            } catch (RemoteException e) {
10315            }
10316
10317            long ident = Binder.clearCallingIdentity();
10318            try {
10319                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10320                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10321                        | Intent.FLAG_RECEIVER_FOREGROUND);
10322                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10323                broadcastIntentLocked(null, null, intent,
10324                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10325                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10326                intent = new Intent(Intent.ACTION_USER_STARTING);
10327                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10328                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10329                broadcastIntentLocked(null, null, intent,
10330                        null, new IIntentReceiver.Stub() {
10331                            @Override
10332                            public void performReceive(Intent intent, int resultCode, String data,
10333                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10334                                    throws RemoteException {
10335                            }
10336                        }, 0, null, null,
10337                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10338                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10339            } catch (Throwable t) {
10340                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10341            } finally {
10342                Binder.restoreCallingIdentity(ident);
10343            }
10344            mStackSupervisor.resumeTopActivitiesLocked();
10345            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10346        }
10347    }
10348
10349    private boolean makeAppCrashingLocked(ProcessRecord app,
10350            String shortMsg, String longMsg, String stackTrace) {
10351        app.crashing = true;
10352        app.crashingReport = generateProcessError(app,
10353                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10354        startAppProblemLocked(app);
10355        app.stopFreezingAllLocked();
10356        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10357    }
10358
10359    private void makeAppNotRespondingLocked(ProcessRecord app,
10360            String activity, String shortMsg, String longMsg) {
10361        app.notResponding = true;
10362        app.notRespondingReport = generateProcessError(app,
10363                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10364                activity, shortMsg, longMsg, null);
10365        startAppProblemLocked(app);
10366        app.stopFreezingAllLocked();
10367    }
10368
10369    /**
10370     * Generate a process error record, suitable for attachment to a ProcessRecord.
10371     *
10372     * @param app The ProcessRecord in which the error occurred.
10373     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10374     *                      ActivityManager.AppErrorStateInfo
10375     * @param activity The activity associated with the crash, if known.
10376     * @param shortMsg Short message describing the crash.
10377     * @param longMsg Long message describing the crash.
10378     * @param stackTrace Full crash stack trace, may be null.
10379     *
10380     * @return Returns a fully-formed AppErrorStateInfo record.
10381     */
10382    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10383            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10384        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10385
10386        report.condition = condition;
10387        report.processName = app.processName;
10388        report.pid = app.pid;
10389        report.uid = app.info.uid;
10390        report.tag = activity;
10391        report.shortMsg = shortMsg;
10392        report.longMsg = longMsg;
10393        report.stackTrace = stackTrace;
10394
10395        return report;
10396    }
10397
10398    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10399        synchronized (this) {
10400            app.crashing = false;
10401            app.crashingReport = null;
10402            app.notResponding = false;
10403            app.notRespondingReport = null;
10404            if (app.anrDialog == fromDialog) {
10405                app.anrDialog = null;
10406            }
10407            if (app.waitDialog == fromDialog) {
10408                app.waitDialog = null;
10409            }
10410            if (app.pid > 0 && app.pid != MY_PID) {
10411                handleAppCrashLocked(app, null, null, null);
10412                killUnneededProcessLocked(app, "user request after error");
10413            }
10414        }
10415    }
10416
10417    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10418            String stackTrace) {
10419        long now = SystemClock.uptimeMillis();
10420
10421        Long crashTime;
10422        if (!app.isolated) {
10423            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10424        } else {
10425            crashTime = null;
10426        }
10427        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10428            // This process loses!
10429            Slog.w(TAG, "Process " + app.info.processName
10430                    + " has crashed too many times: killing!");
10431            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10432                    app.userId, app.info.processName, app.uid);
10433            mStackSupervisor.handleAppCrashLocked(app);
10434            if (!app.persistent) {
10435                // We don't want to start this process again until the user
10436                // explicitly does so...  but for persistent process, we really
10437                // need to keep it running.  If a persistent process is actually
10438                // repeatedly crashing, then badness for everyone.
10439                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10440                        app.info.processName);
10441                if (!app.isolated) {
10442                    // XXX We don't have a way to mark isolated processes
10443                    // as bad, since they don't have a peristent identity.
10444                    mBadProcesses.put(app.info.processName, app.uid,
10445                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10446                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10447                }
10448                app.bad = true;
10449                app.removed = true;
10450                // Don't let services in this process be restarted and potentially
10451                // annoy the user repeatedly.  Unless it is persistent, since those
10452                // processes run critical code.
10453                removeProcessLocked(app, false, false, "crash");
10454                mStackSupervisor.resumeTopActivitiesLocked();
10455                return false;
10456            }
10457            mStackSupervisor.resumeTopActivitiesLocked();
10458        } else {
10459            mStackSupervisor.finishTopRunningActivityLocked(app);
10460        }
10461
10462        // Bump up the crash count of any services currently running in the proc.
10463        for (int i=app.services.size()-1; i>=0; i--) {
10464            // Any services running in the application need to be placed
10465            // back in the pending list.
10466            ServiceRecord sr = app.services.valueAt(i);
10467            sr.crashCount++;
10468        }
10469
10470        // If the crashing process is what we consider to be the "home process" and it has been
10471        // replaced by a third-party app, clear the package preferred activities from packages
10472        // with a home activity running in the process to prevent a repeatedly crashing app
10473        // from blocking the user to manually clear the list.
10474        final ArrayList<ActivityRecord> activities = app.activities;
10475        if (app == mHomeProcess && activities.size() > 0
10476                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10477            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10478                final ActivityRecord r = activities.get(activityNdx);
10479                if (r.isHomeActivity()) {
10480                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10481                    try {
10482                        ActivityThread.getPackageManager()
10483                                .clearPackagePreferredActivities(r.packageName);
10484                    } catch (RemoteException c) {
10485                        // pm is in same process, this will never happen.
10486                    }
10487                }
10488            }
10489        }
10490
10491        if (!app.isolated) {
10492            // XXX Can't keep track of crash times for isolated processes,
10493            // because they don't have a perisistent identity.
10494            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10495        }
10496
10497        return true;
10498    }
10499
10500    void startAppProblemLocked(ProcessRecord app) {
10501        if (app.userId == mCurrentUserId) {
10502            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10503                    mContext, app.info.packageName, app.info.flags);
10504        } else {
10505            // If this app is not running under the current user, then we
10506            // can't give it a report button because that would require
10507            // launching the report UI under a different user.
10508            app.errorReportReceiver = null;
10509        }
10510        skipCurrentReceiverLocked(app);
10511    }
10512
10513    void skipCurrentReceiverLocked(ProcessRecord app) {
10514        for (BroadcastQueue queue : mBroadcastQueues) {
10515            queue.skipCurrentReceiverLocked(app);
10516        }
10517    }
10518
10519    /**
10520     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10521     * The application process will exit immediately after this call returns.
10522     * @param app object of the crashing app, null for the system server
10523     * @param crashInfo describing the exception
10524     */
10525    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10526        ProcessRecord r = findAppProcess(app, "Crash");
10527        final String processName = app == null ? "system_server"
10528                : (r == null ? "unknown" : r.processName);
10529
10530        handleApplicationCrashInner("crash", r, processName, crashInfo);
10531    }
10532
10533    /* Native crash reporting uses this inner version because it needs to be somewhat
10534     * decoupled from the AM-managed cleanup lifecycle
10535     */
10536    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10537            ApplicationErrorReport.CrashInfo crashInfo) {
10538        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10539                UserHandle.getUserId(Binder.getCallingUid()), processName,
10540                r == null ? -1 : r.info.flags,
10541                crashInfo.exceptionClassName,
10542                crashInfo.exceptionMessage,
10543                crashInfo.throwFileName,
10544                crashInfo.throwLineNumber);
10545
10546        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10547
10548        crashApplication(r, crashInfo);
10549    }
10550
10551    public void handleApplicationStrictModeViolation(
10552            IBinder app,
10553            int violationMask,
10554            StrictMode.ViolationInfo info) {
10555        ProcessRecord r = findAppProcess(app, "StrictMode");
10556        if (r == null) {
10557            return;
10558        }
10559
10560        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10561            Integer stackFingerprint = info.hashCode();
10562            boolean logIt = true;
10563            synchronized (mAlreadyLoggedViolatedStacks) {
10564                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10565                    logIt = false;
10566                    // TODO: sub-sample into EventLog for these, with
10567                    // the info.durationMillis?  Then we'd get
10568                    // the relative pain numbers, without logging all
10569                    // the stack traces repeatedly.  We'd want to do
10570                    // likewise in the client code, which also does
10571                    // dup suppression, before the Binder call.
10572                } else {
10573                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10574                        mAlreadyLoggedViolatedStacks.clear();
10575                    }
10576                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10577                }
10578            }
10579            if (logIt) {
10580                logStrictModeViolationToDropBox(r, info);
10581            }
10582        }
10583
10584        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10585            AppErrorResult result = new AppErrorResult();
10586            synchronized (this) {
10587                final long origId = Binder.clearCallingIdentity();
10588
10589                Message msg = Message.obtain();
10590                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10591                HashMap<String, Object> data = new HashMap<String, Object>();
10592                data.put("result", result);
10593                data.put("app", r);
10594                data.put("violationMask", violationMask);
10595                data.put("info", info);
10596                msg.obj = data;
10597                mHandler.sendMessage(msg);
10598
10599                Binder.restoreCallingIdentity(origId);
10600            }
10601            int res = result.get();
10602            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10603        }
10604    }
10605
10606    // Depending on the policy in effect, there could be a bunch of
10607    // these in quick succession so we try to batch these together to
10608    // minimize disk writes, number of dropbox entries, and maximize
10609    // compression, by having more fewer, larger records.
10610    private void logStrictModeViolationToDropBox(
10611            ProcessRecord process,
10612            StrictMode.ViolationInfo info) {
10613        if (info == null) {
10614            return;
10615        }
10616        final boolean isSystemApp = process == null ||
10617                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10618                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10619        final String processName = process == null ? "unknown" : process.processName;
10620        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10621        final DropBoxManager dbox = (DropBoxManager)
10622                mContext.getSystemService(Context.DROPBOX_SERVICE);
10623
10624        // Exit early if the dropbox isn't configured to accept this report type.
10625        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10626
10627        boolean bufferWasEmpty;
10628        boolean needsFlush;
10629        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10630        synchronized (sb) {
10631            bufferWasEmpty = sb.length() == 0;
10632            appendDropBoxProcessHeaders(process, processName, sb);
10633            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10634            sb.append("System-App: ").append(isSystemApp).append("\n");
10635            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10636            if (info.violationNumThisLoop != 0) {
10637                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10638            }
10639            if (info.numAnimationsRunning != 0) {
10640                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10641            }
10642            if (info.broadcastIntentAction != null) {
10643                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10644            }
10645            if (info.durationMillis != -1) {
10646                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10647            }
10648            if (info.numInstances != -1) {
10649                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10650            }
10651            if (info.tags != null) {
10652                for (String tag : info.tags) {
10653                    sb.append("Span-Tag: ").append(tag).append("\n");
10654                }
10655            }
10656            sb.append("\n");
10657            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10658                sb.append(info.crashInfo.stackTrace);
10659            }
10660            sb.append("\n");
10661
10662            // Only buffer up to ~64k.  Various logging bits truncate
10663            // things at 128k.
10664            needsFlush = (sb.length() > 64 * 1024);
10665        }
10666
10667        // Flush immediately if the buffer's grown too large, or this
10668        // is a non-system app.  Non-system apps are isolated with a
10669        // different tag & policy and not batched.
10670        //
10671        // Batching is useful during internal testing with
10672        // StrictMode settings turned up high.  Without batching,
10673        // thousands of separate files could be created on boot.
10674        if (!isSystemApp || needsFlush) {
10675            new Thread("Error dump: " + dropboxTag) {
10676                @Override
10677                public void run() {
10678                    String report;
10679                    synchronized (sb) {
10680                        report = sb.toString();
10681                        sb.delete(0, sb.length());
10682                        sb.trimToSize();
10683                    }
10684                    if (report.length() != 0) {
10685                        dbox.addText(dropboxTag, report);
10686                    }
10687                }
10688            }.start();
10689            return;
10690        }
10691
10692        // System app batching:
10693        if (!bufferWasEmpty) {
10694            // An existing dropbox-writing thread is outstanding, so
10695            // we don't need to start it up.  The existing thread will
10696            // catch the buffer appends we just did.
10697            return;
10698        }
10699
10700        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10701        // (After this point, we shouldn't access AMS internal data structures.)
10702        new Thread("Error dump: " + dropboxTag) {
10703            @Override
10704            public void run() {
10705                // 5 second sleep to let stacks arrive and be batched together
10706                try {
10707                    Thread.sleep(5000);  // 5 seconds
10708                } catch (InterruptedException e) {}
10709
10710                String errorReport;
10711                synchronized (mStrictModeBuffer) {
10712                    errorReport = mStrictModeBuffer.toString();
10713                    if (errorReport.length() == 0) {
10714                        return;
10715                    }
10716                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10717                    mStrictModeBuffer.trimToSize();
10718                }
10719                dbox.addText(dropboxTag, errorReport);
10720            }
10721        }.start();
10722    }
10723
10724    /**
10725     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10726     * @param app object of the crashing app, null for the system server
10727     * @param tag reported by the caller
10728     * @param crashInfo describing the context of the error
10729     * @return true if the process should exit immediately (WTF is fatal)
10730     */
10731    public boolean handleApplicationWtf(IBinder app, String tag,
10732            ApplicationErrorReport.CrashInfo crashInfo) {
10733        ProcessRecord r = findAppProcess(app, "WTF");
10734        final String processName = app == null ? "system_server"
10735                : (r == null ? "unknown" : r.processName);
10736
10737        EventLog.writeEvent(EventLogTags.AM_WTF,
10738                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10739                processName,
10740                r == null ? -1 : r.info.flags,
10741                tag, crashInfo.exceptionMessage);
10742
10743        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10744
10745        if (r != null && r.pid != Process.myPid() &&
10746                Settings.Global.getInt(mContext.getContentResolver(),
10747                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10748            crashApplication(r, crashInfo);
10749            return true;
10750        } else {
10751            return false;
10752        }
10753    }
10754
10755    /**
10756     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10757     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10758     */
10759    private ProcessRecord findAppProcess(IBinder app, String reason) {
10760        if (app == null) {
10761            return null;
10762        }
10763
10764        synchronized (this) {
10765            final int NP = mProcessNames.getMap().size();
10766            for (int ip=0; ip<NP; ip++) {
10767                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10768                final int NA = apps.size();
10769                for (int ia=0; ia<NA; ia++) {
10770                    ProcessRecord p = apps.valueAt(ia);
10771                    if (p.thread != null && p.thread.asBinder() == app) {
10772                        return p;
10773                    }
10774                }
10775            }
10776
10777            Slog.w(TAG, "Can't find mystery application for " + reason
10778                    + " from pid=" + Binder.getCallingPid()
10779                    + " uid=" + Binder.getCallingUid() + ": " + app);
10780            return null;
10781        }
10782    }
10783
10784    /**
10785     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10786     * to append various headers to the dropbox log text.
10787     */
10788    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10789            StringBuilder sb) {
10790        // Watchdog thread ends up invoking this function (with
10791        // a null ProcessRecord) to add the stack file to dropbox.
10792        // Do not acquire a lock on this (am) in such cases, as it
10793        // could cause a potential deadlock, if and when watchdog
10794        // is invoked due to unavailability of lock on am and it
10795        // would prevent watchdog from killing system_server.
10796        if (process == null) {
10797            sb.append("Process: ").append(processName).append("\n");
10798            return;
10799        }
10800        // Note: ProcessRecord 'process' is guarded by the service
10801        // instance.  (notably process.pkgList, which could otherwise change
10802        // concurrently during execution of this method)
10803        synchronized (this) {
10804            sb.append("Process: ").append(processName).append("\n");
10805            int flags = process.info.flags;
10806            IPackageManager pm = AppGlobals.getPackageManager();
10807            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10808            for (int ip=0; ip<process.pkgList.size(); ip++) {
10809                String pkg = process.pkgList.keyAt(ip);
10810                sb.append("Package: ").append(pkg);
10811                try {
10812                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10813                    if (pi != null) {
10814                        sb.append(" v").append(pi.versionCode);
10815                        if (pi.versionName != null) {
10816                            sb.append(" (").append(pi.versionName).append(")");
10817                        }
10818                    }
10819                } catch (RemoteException e) {
10820                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10821                }
10822                sb.append("\n");
10823            }
10824        }
10825    }
10826
10827    private static String processClass(ProcessRecord process) {
10828        if (process == null || process.pid == MY_PID) {
10829            return "system_server";
10830        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10831            return "system_app";
10832        } else {
10833            return "data_app";
10834        }
10835    }
10836
10837    /**
10838     * Write a description of an error (crash, WTF, ANR) to the drop box.
10839     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10840     * @param process which caused the error, null means the system server
10841     * @param activity which triggered the error, null if unknown
10842     * @param parent activity related to the error, null if unknown
10843     * @param subject line related to the error, null if absent
10844     * @param report in long form describing the error, null if absent
10845     * @param logFile to include in the report, null if none
10846     * @param crashInfo giving an application stack trace, null if absent
10847     */
10848    public void addErrorToDropBox(String eventType,
10849            ProcessRecord process, String processName, ActivityRecord activity,
10850            ActivityRecord parent, String subject,
10851            final String report, final File logFile,
10852            final ApplicationErrorReport.CrashInfo crashInfo) {
10853        // NOTE -- this must never acquire the ActivityManagerService lock,
10854        // otherwise the watchdog may be prevented from resetting the system.
10855
10856        final String dropboxTag = processClass(process) + "_" + eventType;
10857        final DropBoxManager dbox = (DropBoxManager)
10858                mContext.getSystemService(Context.DROPBOX_SERVICE);
10859
10860        // Exit early if the dropbox isn't configured to accept this report type.
10861        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10862
10863        final StringBuilder sb = new StringBuilder(1024);
10864        appendDropBoxProcessHeaders(process, processName, sb);
10865        if (activity != null) {
10866            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10867        }
10868        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10869            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10870        }
10871        if (parent != null && parent != activity) {
10872            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10873        }
10874        if (subject != null) {
10875            sb.append("Subject: ").append(subject).append("\n");
10876        }
10877        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10878        if (Debug.isDebuggerConnected()) {
10879            sb.append("Debugger: Connected\n");
10880        }
10881        sb.append("\n");
10882
10883        // Do the rest in a worker thread to avoid blocking the caller on I/O
10884        // (After this point, we shouldn't access AMS internal data structures.)
10885        Thread worker = new Thread("Error dump: " + dropboxTag) {
10886            @Override
10887            public void run() {
10888                if (report != null) {
10889                    sb.append(report);
10890                }
10891                if (logFile != null) {
10892                    try {
10893                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10894                                    "\n\n[[TRUNCATED]]"));
10895                    } catch (IOException e) {
10896                        Slog.e(TAG, "Error reading " + logFile, e);
10897                    }
10898                }
10899                if (crashInfo != null && crashInfo.stackTrace != null) {
10900                    sb.append(crashInfo.stackTrace);
10901                }
10902
10903                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10904                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10905                if (lines > 0) {
10906                    sb.append("\n");
10907
10908                    // Merge several logcat streams, and take the last N lines
10909                    InputStreamReader input = null;
10910                    try {
10911                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10912                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10913                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10914
10915                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10916                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10917                        input = new InputStreamReader(logcat.getInputStream());
10918
10919                        int num;
10920                        char[] buf = new char[8192];
10921                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10922                    } catch (IOException e) {
10923                        Slog.e(TAG, "Error running logcat", e);
10924                    } finally {
10925                        if (input != null) try { input.close(); } catch (IOException e) {}
10926                    }
10927                }
10928
10929                dbox.addText(dropboxTag, sb.toString());
10930            }
10931        };
10932
10933        if (process == null) {
10934            // If process is null, we are being called from some internal code
10935            // and may be about to die -- run this synchronously.
10936            worker.run();
10937        } else {
10938            worker.start();
10939        }
10940    }
10941
10942    /**
10943     * Bring up the "unexpected error" dialog box for a crashing app.
10944     * Deal with edge cases (intercepts from instrumented applications,
10945     * ActivityController, error intent receivers, that sort of thing).
10946     * @param r the application crashing
10947     * @param crashInfo describing the failure
10948     */
10949    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10950        long timeMillis = System.currentTimeMillis();
10951        String shortMsg = crashInfo.exceptionClassName;
10952        String longMsg = crashInfo.exceptionMessage;
10953        String stackTrace = crashInfo.stackTrace;
10954        if (shortMsg != null && longMsg != null) {
10955            longMsg = shortMsg + ": " + longMsg;
10956        } else if (shortMsg != null) {
10957            longMsg = shortMsg;
10958        }
10959
10960        AppErrorResult result = new AppErrorResult();
10961        synchronized (this) {
10962            if (mController != null) {
10963                try {
10964                    String name = r != null ? r.processName : null;
10965                    int pid = r != null ? r.pid : Binder.getCallingPid();
10966                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
10967                    if (!mController.appCrashed(name, pid,
10968                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10969                        Slog.w(TAG, "Force-killing crashed app " + name
10970                                + " at watcher's request");
10971                        Process.killProcess(pid);
10972                        if (r != null) {
10973                            Process.killProcessGroup(uid, pid);
10974                        }
10975                        return;
10976                    }
10977                } catch (RemoteException e) {
10978                    mController = null;
10979                    Watchdog.getInstance().setActivityController(null);
10980                }
10981            }
10982
10983            final long origId = Binder.clearCallingIdentity();
10984
10985            // If this process is running instrumentation, finish it.
10986            if (r != null && r.instrumentationClass != null) {
10987                Slog.w(TAG, "Error in app " + r.processName
10988                      + " running instrumentation " + r.instrumentationClass + ":");
10989                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10990                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10991                Bundle info = new Bundle();
10992                info.putString("shortMsg", shortMsg);
10993                info.putString("longMsg", longMsg);
10994                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10995                Binder.restoreCallingIdentity(origId);
10996                return;
10997            }
10998
10999            // If we can't identify the process or it's already exceeded its crash quota,
11000            // quit right away without showing a crash dialog.
11001            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11002                Binder.restoreCallingIdentity(origId);
11003                return;
11004            }
11005
11006            Message msg = Message.obtain();
11007            msg.what = SHOW_ERROR_MSG;
11008            HashMap data = new HashMap();
11009            data.put("result", result);
11010            data.put("app", r);
11011            msg.obj = data;
11012            mHandler.sendMessage(msg);
11013
11014            Binder.restoreCallingIdentity(origId);
11015        }
11016
11017        int res = result.get();
11018
11019        Intent appErrorIntent = null;
11020        synchronized (this) {
11021            if (r != null && !r.isolated) {
11022                // XXX Can't keep track of crash time for isolated processes,
11023                // since they don't have a persistent identity.
11024                mProcessCrashTimes.put(r.info.processName, r.uid,
11025                        SystemClock.uptimeMillis());
11026            }
11027            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11028                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11029            }
11030        }
11031
11032        if (appErrorIntent != null) {
11033            try {
11034                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11035            } catch (ActivityNotFoundException e) {
11036                Slog.w(TAG, "bug report receiver dissappeared", e);
11037            }
11038        }
11039    }
11040
11041    Intent createAppErrorIntentLocked(ProcessRecord r,
11042            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11043        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11044        if (report == null) {
11045            return null;
11046        }
11047        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11048        result.setComponent(r.errorReportReceiver);
11049        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11050        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11051        return result;
11052    }
11053
11054    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11055            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11056        if (r.errorReportReceiver == null) {
11057            return null;
11058        }
11059
11060        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11061            return null;
11062        }
11063
11064        ApplicationErrorReport report = new ApplicationErrorReport();
11065        report.packageName = r.info.packageName;
11066        report.installerPackageName = r.errorReportReceiver.getPackageName();
11067        report.processName = r.processName;
11068        report.time = timeMillis;
11069        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11070
11071        if (r.crashing || r.forceCrashReport) {
11072            report.type = ApplicationErrorReport.TYPE_CRASH;
11073            report.crashInfo = crashInfo;
11074        } else if (r.notResponding) {
11075            report.type = ApplicationErrorReport.TYPE_ANR;
11076            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11077
11078            report.anrInfo.activity = r.notRespondingReport.tag;
11079            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11080            report.anrInfo.info = r.notRespondingReport.longMsg;
11081        }
11082
11083        return report;
11084    }
11085
11086    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11087        enforceNotIsolatedCaller("getProcessesInErrorState");
11088        // assume our apps are happy - lazy create the list
11089        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11090
11091        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11092                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11093        int userId = UserHandle.getUserId(Binder.getCallingUid());
11094
11095        synchronized (this) {
11096
11097            // iterate across all processes
11098            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11099                ProcessRecord app = mLruProcesses.get(i);
11100                if (!allUsers && app.userId != userId) {
11101                    continue;
11102                }
11103                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11104                    // This one's in trouble, so we'll generate a report for it
11105                    // crashes are higher priority (in case there's a crash *and* an anr)
11106                    ActivityManager.ProcessErrorStateInfo report = null;
11107                    if (app.crashing) {
11108                        report = app.crashingReport;
11109                    } else if (app.notResponding) {
11110                        report = app.notRespondingReport;
11111                    }
11112
11113                    if (report != null) {
11114                        if (errList == null) {
11115                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11116                        }
11117                        errList.add(report);
11118                    } else {
11119                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11120                                " crashing = " + app.crashing +
11121                                " notResponding = " + app.notResponding);
11122                    }
11123                }
11124            }
11125        }
11126
11127        return errList;
11128    }
11129
11130    static int procStateToImportance(int procState, int memAdj,
11131            ActivityManager.RunningAppProcessInfo currApp) {
11132        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11133        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11134            currApp.lru = memAdj;
11135        } else {
11136            currApp.lru = 0;
11137        }
11138        return imp;
11139    }
11140
11141    private void fillInProcMemInfo(ProcessRecord app,
11142            ActivityManager.RunningAppProcessInfo outInfo) {
11143        outInfo.pid = app.pid;
11144        outInfo.uid = app.info.uid;
11145        if (mHeavyWeightProcess == app) {
11146            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11147        }
11148        if (app.persistent) {
11149            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11150        }
11151        if (app.activities.size() > 0) {
11152            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11153        }
11154        outInfo.lastTrimLevel = app.trimMemoryLevel;
11155        int adj = app.curAdj;
11156        int procState = app.curProcState;
11157        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11158        outInfo.importanceReasonCode = app.adjTypeCode;
11159        outInfo.processState = app.curProcState;
11160    }
11161
11162    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11163        enforceNotIsolatedCaller("getRunningAppProcesses");
11164        // Lazy instantiation of list
11165        List<ActivityManager.RunningAppProcessInfo> runList = null;
11166        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11167                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11168        int userId = UserHandle.getUserId(Binder.getCallingUid());
11169        synchronized (this) {
11170            // Iterate across all processes
11171            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11172                ProcessRecord app = mLruProcesses.get(i);
11173                if (!allUsers && app.userId != userId) {
11174                    continue;
11175                }
11176                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11177                    // Generate process state info for running application
11178                    ActivityManager.RunningAppProcessInfo currApp =
11179                        new ActivityManager.RunningAppProcessInfo(app.processName,
11180                                app.pid, app.getPackageList());
11181                    fillInProcMemInfo(app, currApp);
11182                    if (app.adjSource instanceof ProcessRecord) {
11183                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11184                        currApp.importanceReasonImportance =
11185                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11186                                        app.adjSourceProcState);
11187                    } else if (app.adjSource instanceof ActivityRecord) {
11188                        ActivityRecord r = (ActivityRecord)app.adjSource;
11189                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11190                    }
11191                    if (app.adjTarget instanceof ComponentName) {
11192                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11193                    }
11194                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11195                    //        + " lru=" + currApp.lru);
11196                    if (runList == null) {
11197                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11198                    }
11199                    runList.add(currApp);
11200                }
11201            }
11202        }
11203        return runList;
11204    }
11205
11206    public List<ApplicationInfo> getRunningExternalApplications() {
11207        enforceNotIsolatedCaller("getRunningExternalApplications");
11208        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11209        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11210        if (runningApps != null && runningApps.size() > 0) {
11211            Set<String> extList = new HashSet<String>();
11212            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11213                if (app.pkgList != null) {
11214                    for (String pkg : app.pkgList) {
11215                        extList.add(pkg);
11216                    }
11217                }
11218            }
11219            IPackageManager pm = AppGlobals.getPackageManager();
11220            for (String pkg : extList) {
11221                try {
11222                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11223                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11224                        retList.add(info);
11225                    }
11226                } catch (RemoteException e) {
11227                }
11228            }
11229        }
11230        return retList;
11231    }
11232
11233    @Override
11234    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11235        enforceNotIsolatedCaller("getMyMemoryState");
11236        synchronized (this) {
11237            ProcessRecord proc;
11238            synchronized (mPidsSelfLocked) {
11239                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11240            }
11241            fillInProcMemInfo(proc, outInfo);
11242        }
11243    }
11244
11245    @Override
11246    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11247        if (checkCallingPermission(android.Manifest.permission.DUMP)
11248                != PackageManager.PERMISSION_GRANTED) {
11249            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11250                    + Binder.getCallingPid()
11251                    + ", uid=" + Binder.getCallingUid()
11252                    + " without permission "
11253                    + android.Manifest.permission.DUMP);
11254            return;
11255        }
11256
11257        boolean dumpAll = false;
11258        boolean dumpClient = false;
11259        String dumpPackage = null;
11260
11261        int opti = 0;
11262        while (opti < args.length) {
11263            String opt = args[opti];
11264            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11265                break;
11266            }
11267            opti++;
11268            if ("-a".equals(opt)) {
11269                dumpAll = true;
11270            } else if ("-c".equals(opt)) {
11271                dumpClient = true;
11272            } else if ("-h".equals(opt)) {
11273                pw.println("Activity manager dump options:");
11274                pw.println("  [-a] [-c] [-h] [cmd] ...");
11275                pw.println("  cmd may be one of:");
11276                pw.println("    a[ctivities]: activity stack state");
11277                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11278                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11279                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11280                pw.println("    o[om]: out of memory management");
11281                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11282                pw.println("    provider [COMP_SPEC]: provider client-side state");
11283                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11284                pw.println("    service [COMP_SPEC]: service client-side state");
11285                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11286                pw.println("    all: dump all activities");
11287                pw.println("    top: dump the top activity");
11288                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11289                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11290                pw.println("    a partial substring in a component name, a");
11291                pw.println("    hex object identifier.");
11292                pw.println("  -a: include all available server state.");
11293                pw.println("  -c: include client state.");
11294                return;
11295            } else {
11296                pw.println("Unknown argument: " + opt + "; use -h for help");
11297            }
11298        }
11299
11300        long origId = Binder.clearCallingIdentity();
11301        boolean more = false;
11302        // Is the caller requesting to dump a particular piece of data?
11303        if (opti < args.length) {
11304            String cmd = args[opti];
11305            opti++;
11306            if ("activities".equals(cmd) || "a".equals(cmd)) {
11307                synchronized (this) {
11308                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11309                }
11310            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11311                String[] newArgs;
11312                String name;
11313                if (opti >= args.length) {
11314                    name = null;
11315                    newArgs = EMPTY_STRING_ARRAY;
11316                } else {
11317                    name = args[opti];
11318                    opti++;
11319                    newArgs = new String[args.length - opti];
11320                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11321                            args.length - opti);
11322                }
11323                synchronized (this) {
11324                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11325                }
11326            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11327                String[] newArgs;
11328                String name;
11329                if (opti >= args.length) {
11330                    name = null;
11331                    newArgs = EMPTY_STRING_ARRAY;
11332                } else {
11333                    name = args[opti];
11334                    opti++;
11335                    newArgs = new String[args.length - opti];
11336                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11337                            args.length - opti);
11338                }
11339                synchronized (this) {
11340                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11341                }
11342            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11343                String[] newArgs;
11344                String name;
11345                if (opti >= args.length) {
11346                    name = null;
11347                    newArgs = EMPTY_STRING_ARRAY;
11348                } else {
11349                    name = args[opti];
11350                    opti++;
11351                    newArgs = new String[args.length - opti];
11352                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11353                            args.length - opti);
11354                }
11355                synchronized (this) {
11356                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11357                }
11358            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11359                synchronized (this) {
11360                    dumpOomLocked(fd, pw, args, opti, true);
11361                }
11362            } else if ("provider".equals(cmd)) {
11363                String[] newArgs;
11364                String name;
11365                if (opti >= args.length) {
11366                    name = null;
11367                    newArgs = EMPTY_STRING_ARRAY;
11368                } else {
11369                    name = args[opti];
11370                    opti++;
11371                    newArgs = new String[args.length - opti];
11372                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11373                }
11374                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11375                    pw.println("No providers match: " + name);
11376                    pw.println("Use -h for help.");
11377                }
11378            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11379                synchronized (this) {
11380                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11381                }
11382            } else if ("service".equals(cmd)) {
11383                String[] newArgs;
11384                String name;
11385                if (opti >= args.length) {
11386                    name = null;
11387                    newArgs = EMPTY_STRING_ARRAY;
11388                } else {
11389                    name = args[opti];
11390                    opti++;
11391                    newArgs = new String[args.length - opti];
11392                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11393                            args.length - opti);
11394                }
11395                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11396                    pw.println("No services match: " + name);
11397                    pw.println("Use -h for help.");
11398                }
11399            } else if ("package".equals(cmd)) {
11400                String[] newArgs;
11401                if (opti >= args.length) {
11402                    pw.println("package: no package name specified");
11403                    pw.println("Use -h for help.");
11404                } else {
11405                    dumpPackage = args[opti];
11406                    opti++;
11407                    newArgs = new String[args.length - opti];
11408                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11409                            args.length - opti);
11410                    args = newArgs;
11411                    opti = 0;
11412                    more = true;
11413                }
11414            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11415                synchronized (this) {
11416                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11417                }
11418            } else {
11419                // Dumping a single activity?
11420                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11421                    pw.println("Bad activity command, or no activities match: " + cmd);
11422                    pw.println("Use -h for help.");
11423                }
11424            }
11425            if (!more) {
11426                Binder.restoreCallingIdentity(origId);
11427                return;
11428            }
11429        }
11430
11431        // No piece of data specified, dump everything.
11432        synchronized (this) {
11433            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11434            pw.println();
11435            if (dumpAll) {
11436                pw.println("-------------------------------------------------------------------------------");
11437            }
11438            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11439            pw.println();
11440            if (dumpAll) {
11441                pw.println("-------------------------------------------------------------------------------");
11442            }
11443            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11444            pw.println();
11445            if (dumpAll) {
11446                pw.println("-------------------------------------------------------------------------------");
11447            }
11448            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11449            pw.println();
11450            if (dumpAll) {
11451                pw.println("-------------------------------------------------------------------------------");
11452            }
11453            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11454            pw.println();
11455            if (dumpAll) {
11456                pw.println("-------------------------------------------------------------------------------");
11457            }
11458            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11459        }
11460        Binder.restoreCallingIdentity(origId);
11461    }
11462
11463    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11464            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11465        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11466
11467        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11468                dumpPackage);
11469        boolean needSep = printedAnything;
11470
11471        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11472                dumpPackage, needSep, "  mFocusedActivity: ");
11473        if (printed) {
11474            printedAnything = true;
11475            needSep = false;
11476        }
11477
11478        if (dumpPackage == null) {
11479            if (needSep) {
11480                pw.println();
11481            }
11482            needSep = true;
11483            printedAnything = true;
11484            mStackSupervisor.dump(pw, "  ");
11485        }
11486
11487        if (mRecentTasks.size() > 0) {
11488            boolean printedHeader = false;
11489
11490            final int N = mRecentTasks.size();
11491            for (int i=0; i<N; i++) {
11492                TaskRecord tr = mRecentTasks.get(i);
11493                if (dumpPackage != null) {
11494                    if (tr.realActivity == null ||
11495                            !dumpPackage.equals(tr.realActivity)) {
11496                        continue;
11497                    }
11498                }
11499                if (!printedHeader) {
11500                    if (needSep) {
11501                        pw.println();
11502                    }
11503                    pw.println("  Recent tasks:");
11504                    printedHeader = true;
11505                    printedAnything = true;
11506                }
11507                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11508                        pw.println(tr);
11509                if (dumpAll) {
11510                    mRecentTasks.get(i).dump(pw, "    ");
11511                }
11512            }
11513        }
11514
11515        if (!printedAnything) {
11516            pw.println("  (nothing)");
11517        }
11518    }
11519
11520    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11521            int opti, boolean dumpAll, String dumpPackage) {
11522        boolean needSep = false;
11523        boolean printedAnything = false;
11524        int numPers = 0;
11525
11526        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11527
11528        if (dumpAll) {
11529            final int NP = mProcessNames.getMap().size();
11530            for (int ip=0; ip<NP; ip++) {
11531                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11532                final int NA = procs.size();
11533                for (int ia=0; ia<NA; ia++) {
11534                    ProcessRecord r = procs.valueAt(ia);
11535                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11536                        continue;
11537                    }
11538                    if (!needSep) {
11539                        pw.println("  All known processes:");
11540                        needSep = true;
11541                        printedAnything = true;
11542                    }
11543                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11544                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11545                        pw.print(" "); pw.println(r);
11546                    r.dump(pw, "    ");
11547                    if (r.persistent) {
11548                        numPers++;
11549                    }
11550                }
11551            }
11552        }
11553
11554        if (mIsolatedProcesses.size() > 0) {
11555            boolean printed = false;
11556            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11557                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11558                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11559                    continue;
11560                }
11561                if (!printed) {
11562                    if (needSep) {
11563                        pw.println();
11564                    }
11565                    pw.println("  Isolated process list (sorted by uid):");
11566                    printedAnything = true;
11567                    printed = true;
11568                    needSep = true;
11569                }
11570                pw.println(String.format("%sIsolated #%2d: %s",
11571                        "    ", i, r.toString()));
11572            }
11573        }
11574
11575        if (mLruProcesses.size() > 0) {
11576            if (needSep) {
11577                pw.println();
11578            }
11579            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11580                    pw.print(" total, non-act at ");
11581                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11582                    pw.print(", non-svc at ");
11583                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11584                    pw.println("):");
11585            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11586            needSep = true;
11587            printedAnything = true;
11588        }
11589
11590        if (dumpAll || dumpPackage != null) {
11591            synchronized (mPidsSelfLocked) {
11592                boolean printed = false;
11593                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11594                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11595                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11596                        continue;
11597                    }
11598                    if (!printed) {
11599                        if (needSep) pw.println();
11600                        needSep = true;
11601                        pw.println("  PID mappings:");
11602                        printed = true;
11603                        printedAnything = true;
11604                    }
11605                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11606                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11607                }
11608            }
11609        }
11610
11611        if (mForegroundProcesses.size() > 0) {
11612            synchronized (mPidsSelfLocked) {
11613                boolean printed = false;
11614                for (int i=0; i<mForegroundProcesses.size(); i++) {
11615                    ProcessRecord r = mPidsSelfLocked.get(
11616                            mForegroundProcesses.valueAt(i).pid);
11617                    if (dumpPackage != null && (r == null
11618                            || !r.pkgList.containsKey(dumpPackage))) {
11619                        continue;
11620                    }
11621                    if (!printed) {
11622                        if (needSep) pw.println();
11623                        needSep = true;
11624                        pw.println("  Foreground Processes:");
11625                        printed = true;
11626                        printedAnything = true;
11627                    }
11628                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11629                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11630                }
11631            }
11632        }
11633
11634        if (mPersistentStartingProcesses.size() > 0) {
11635            if (needSep) pw.println();
11636            needSep = true;
11637            printedAnything = true;
11638            pw.println("  Persisent processes that are starting:");
11639            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11640                    "Starting Norm", "Restarting PERS", dumpPackage);
11641        }
11642
11643        if (mRemovedProcesses.size() > 0) {
11644            if (needSep) pw.println();
11645            needSep = true;
11646            printedAnything = true;
11647            pw.println("  Processes that are being removed:");
11648            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11649                    "Removed Norm", "Removed PERS", dumpPackage);
11650        }
11651
11652        if (mProcessesOnHold.size() > 0) {
11653            if (needSep) pw.println();
11654            needSep = true;
11655            printedAnything = true;
11656            pw.println("  Processes that are on old until the system is ready:");
11657            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11658                    "OnHold Norm", "OnHold PERS", dumpPackage);
11659        }
11660
11661        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11662
11663        if (mProcessCrashTimes.getMap().size() > 0) {
11664            boolean printed = false;
11665            long now = SystemClock.uptimeMillis();
11666            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11667            final int NP = pmap.size();
11668            for (int ip=0; ip<NP; ip++) {
11669                String pname = pmap.keyAt(ip);
11670                SparseArray<Long> uids = pmap.valueAt(ip);
11671                final int N = uids.size();
11672                for (int i=0; i<N; i++) {
11673                    int puid = uids.keyAt(i);
11674                    ProcessRecord r = mProcessNames.get(pname, puid);
11675                    if (dumpPackage != null && (r == null
11676                            || !r.pkgList.containsKey(dumpPackage))) {
11677                        continue;
11678                    }
11679                    if (!printed) {
11680                        if (needSep) pw.println();
11681                        needSep = true;
11682                        pw.println("  Time since processes crashed:");
11683                        printed = true;
11684                        printedAnything = true;
11685                    }
11686                    pw.print("    Process "); pw.print(pname);
11687                            pw.print(" uid "); pw.print(puid);
11688                            pw.print(": last crashed ");
11689                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11690                            pw.println(" ago");
11691                }
11692            }
11693        }
11694
11695        if (mBadProcesses.getMap().size() > 0) {
11696            boolean printed = false;
11697            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11698            final int NP = pmap.size();
11699            for (int ip=0; ip<NP; ip++) {
11700                String pname = pmap.keyAt(ip);
11701                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11702                final int N = uids.size();
11703                for (int i=0; i<N; i++) {
11704                    int puid = uids.keyAt(i);
11705                    ProcessRecord r = mProcessNames.get(pname, puid);
11706                    if (dumpPackage != null && (r == null
11707                            || !r.pkgList.containsKey(dumpPackage))) {
11708                        continue;
11709                    }
11710                    if (!printed) {
11711                        if (needSep) pw.println();
11712                        needSep = true;
11713                        pw.println("  Bad processes:");
11714                        printedAnything = true;
11715                    }
11716                    BadProcessInfo info = uids.valueAt(i);
11717                    pw.print("    Bad process "); pw.print(pname);
11718                            pw.print(" uid "); pw.print(puid);
11719                            pw.print(": crashed at time "); pw.println(info.time);
11720                    if (info.shortMsg != null) {
11721                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11722                    }
11723                    if (info.longMsg != null) {
11724                        pw.print("      Long msg: "); pw.println(info.longMsg);
11725                    }
11726                    if (info.stack != null) {
11727                        pw.println("      Stack:");
11728                        int lastPos = 0;
11729                        for (int pos=0; pos<info.stack.length(); pos++) {
11730                            if (info.stack.charAt(pos) == '\n') {
11731                                pw.print("        ");
11732                                pw.write(info.stack, lastPos, pos-lastPos);
11733                                pw.println();
11734                                lastPos = pos+1;
11735                            }
11736                        }
11737                        if (lastPos < info.stack.length()) {
11738                            pw.print("        ");
11739                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11740                            pw.println();
11741                        }
11742                    }
11743                }
11744            }
11745        }
11746
11747        if (dumpPackage == null) {
11748            pw.println();
11749            needSep = false;
11750            pw.println("  mStartedUsers:");
11751            for (int i=0; i<mStartedUsers.size(); i++) {
11752                UserStartedState uss = mStartedUsers.valueAt(i);
11753                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11754                        pw.print(": "); uss.dump("", pw);
11755            }
11756            pw.print("  mStartedUserArray: [");
11757            for (int i=0; i<mStartedUserArray.length; i++) {
11758                if (i > 0) pw.print(", ");
11759                pw.print(mStartedUserArray[i]);
11760            }
11761            pw.println("]");
11762            pw.print("  mUserLru: [");
11763            for (int i=0; i<mUserLru.size(); i++) {
11764                if (i > 0) pw.print(", ");
11765                pw.print(mUserLru.get(i));
11766            }
11767            pw.println("]");
11768            if (dumpAll) {
11769                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11770            }
11771            synchronized (mUserProfileGroupIdsSelfLocked) {
11772                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11773                    pw.println("  mUserProfileGroupIds:");
11774                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11775                        pw.print("    User #");
11776                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11777                        pw.print(" -> profile #");
11778                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11779                    }
11780                }
11781            }
11782        }
11783        if (mHomeProcess != null && (dumpPackage == null
11784                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11785            if (needSep) {
11786                pw.println();
11787                needSep = false;
11788            }
11789            pw.println("  mHomeProcess: " + mHomeProcess);
11790        }
11791        if (mPreviousProcess != null && (dumpPackage == null
11792                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11793            if (needSep) {
11794                pw.println();
11795                needSep = false;
11796            }
11797            pw.println("  mPreviousProcess: " + mPreviousProcess);
11798        }
11799        if (dumpAll) {
11800            StringBuilder sb = new StringBuilder(128);
11801            sb.append("  mPreviousProcessVisibleTime: ");
11802            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11803            pw.println(sb);
11804        }
11805        if (mHeavyWeightProcess != null && (dumpPackage == null
11806                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11807            if (needSep) {
11808                pw.println();
11809                needSep = false;
11810            }
11811            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11812        }
11813        if (dumpPackage == null) {
11814            pw.println("  mConfiguration: " + mConfiguration);
11815        }
11816        if (dumpAll) {
11817            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11818            if (mCompatModePackages.getPackages().size() > 0) {
11819                boolean printed = false;
11820                for (Map.Entry<String, Integer> entry
11821                        : mCompatModePackages.getPackages().entrySet()) {
11822                    String pkg = entry.getKey();
11823                    int mode = entry.getValue();
11824                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11825                        continue;
11826                    }
11827                    if (!printed) {
11828                        pw.println("  mScreenCompatPackages:");
11829                        printed = true;
11830                    }
11831                    pw.print("    "); pw.print(pkg); pw.print(": ");
11832                            pw.print(mode); pw.println();
11833                }
11834            }
11835        }
11836        if (dumpPackage == null) {
11837            if (mSleeping || mWentToSleep || mLockScreenShown) {
11838                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11839                        + " mLockScreenShown " + mLockScreenShown);
11840            }
11841            if (mShuttingDown || mRunningVoice) {
11842                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11843            }
11844        }
11845        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11846                || mOrigWaitForDebugger) {
11847            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11848                    || dumpPackage.equals(mOrigDebugApp)) {
11849                if (needSep) {
11850                    pw.println();
11851                    needSep = false;
11852                }
11853                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11854                        + " mDebugTransient=" + mDebugTransient
11855                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11856            }
11857        }
11858        if (mOpenGlTraceApp != null) {
11859            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11860                if (needSep) {
11861                    pw.println();
11862                    needSep = false;
11863                }
11864                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11865            }
11866        }
11867        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11868                || mProfileFd != null) {
11869            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11870                if (needSep) {
11871                    pw.println();
11872                    needSep = false;
11873                }
11874                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11875                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11876                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11877                        + mAutoStopProfiler);
11878            }
11879        }
11880        if (dumpPackage == null) {
11881            if (mAlwaysFinishActivities || mController != null) {
11882                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11883                        + " mController=" + mController);
11884            }
11885            if (dumpAll) {
11886                pw.println("  Total persistent processes: " + numPers);
11887                pw.println("  mProcessesReady=" + mProcessesReady
11888                        + " mSystemReady=" + mSystemReady);
11889                pw.println("  mBooting=" + mBooting
11890                        + " mBooted=" + mBooted
11891                        + " mFactoryTest=" + mFactoryTest);
11892                pw.print("  mLastPowerCheckRealtime=");
11893                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11894                        pw.println("");
11895                pw.print("  mLastPowerCheckUptime=");
11896                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11897                        pw.println("");
11898                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11899                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11900                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11901                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11902                        + " (" + mLruProcesses.size() + " total)"
11903                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11904                        + " mNumServiceProcs=" + mNumServiceProcs
11905                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11906                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11907                        + " mLastMemoryLevel" + mLastMemoryLevel
11908                        + " mLastNumProcesses" + mLastNumProcesses);
11909                long now = SystemClock.uptimeMillis();
11910                pw.print("  mLastIdleTime=");
11911                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11912                        pw.print(" mLowRamSinceLastIdle=");
11913                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11914                        pw.println();
11915            }
11916        }
11917
11918        if (!printedAnything) {
11919            pw.println("  (nothing)");
11920        }
11921    }
11922
11923    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11924            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11925        if (mProcessesToGc.size() > 0) {
11926            boolean printed = false;
11927            long now = SystemClock.uptimeMillis();
11928            for (int i=0; i<mProcessesToGc.size(); i++) {
11929                ProcessRecord proc = mProcessesToGc.get(i);
11930                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11931                    continue;
11932                }
11933                if (!printed) {
11934                    if (needSep) pw.println();
11935                    needSep = true;
11936                    pw.println("  Processes that are waiting to GC:");
11937                    printed = true;
11938                }
11939                pw.print("    Process "); pw.println(proc);
11940                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11941                        pw.print(", last gced=");
11942                        pw.print(now-proc.lastRequestedGc);
11943                        pw.print(" ms ago, last lowMem=");
11944                        pw.print(now-proc.lastLowMemory);
11945                        pw.println(" ms ago");
11946
11947            }
11948        }
11949        return needSep;
11950    }
11951
11952    void printOomLevel(PrintWriter pw, String name, int adj) {
11953        pw.print("    ");
11954        if (adj >= 0) {
11955            pw.print(' ');
11956            if (adj < 10) pw.print(' ');
11957        } else {
11958            if (adj > -10) pw.print(' ');
11959        }
11960        pw.print(adj);
11961        pw.print(": ");
11962        pw.print(name);
11963        pw.print(" (");
11964        pw.print(mProcessList.getMemLevel(adj)/1024);
11965        pw.println(" kB)");
11966    }
11967
11968    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11969            int opti, boolean dumpAll) {
11970        boolean needSep = false;
11971
11972        if (mLruProcesses.size() > 0) {
11973            if (needSep) pw.println();
11974            needSep = true;
11975            pw.println("  OOM levels:");
11976            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11977            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11978            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11979            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11980            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11981            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11982            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11983            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11984            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11985            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11986            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11987            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11988            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11989
11990            if (needSep) pw.println();
11991            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11992                    pw.print(" total, non-act at ");
11993                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11994                    pw.print(", non-svc at ");
11995                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11996                    pw.println("):");
11997            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11998            needSep = true;
11999        }
12000
12001        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12002
12003        pw.println();
12004        pw.println("  mHomeProcess: " + mHomeProcess);
12005        pw.println("  mPreviousProcess: " + mPreviousProcess);
12006        if (mHeavyWeightProcess != null) {
12007            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12008        }
12009
12010        return true;
12011    }
12012
12013    /**
12014     * There are three ways to call this:
12015     *  - no provider specified: dump all the providers
12016     *  - a flattened component name that matched an existing provider was specified as the
12017     *    first arg: dump that one provider
12018     *  - the first arg isn't the flattened component name of an existing provider:
12019     *    dump all providers whose component contains the first arg as a substring
12020     */
12021    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12022            int opti, boolean dumpAll) {
12023        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12024    }
12025
12026    static class ItemMatcher {
12027        ArrayList<ComponentName> components;
12028        ArrayList<String> strings;
12029        ArrayList<Integer> objects;
12030        boolean all;
12031
12032        ItemMatcher() {
12033            all = true;
12034        }
12035
12036        void build(String name) {
12037            ComponentName componentName = ComponentName.unflattenFromString(name);
12038            if (componentName != null) {
12039                if (components == null) {
12040                    components = new ArrayList<ComponentName>();
12041                }
12042                components.add(componentName);
12043                all = false;
12044            } else {
12045                int objectId = 0;
12046                // Not a '/' separated full component name; maybe an object ID?
12047                try {
12048                    objectId = Integer.parseInt(name, 16);
12049                    if (objects == null) {
12050                        objects = new ArrayList<Integer>();
12051                    }
12052                    objects.add(objectId);
12053                    all = false;
12054                } catch (RuntimeException e) {
12055                    // Not an integer; just do string match.
12056                    if (strings == null) {
12057                        strings = new ArrayList<String>();
12058                    }
12059                    strings.add(name);
12060                    all = false;
12061                }
12062            }
12063        }
12064
12065        int build(String[] args, int opti) {
12066            for (; opti<args.length; opti++) {
12067                String name = args[opti];
12068                if ("--".equals(name)) {
12069                    return opti+1;
12070                }
12071                build(name);
12072            }
12073            return opti;
12074        }
12075
12076        boolean match(Object object, ComponentName comp) {
12077            if (all) {
12078                return true;
12079            }
12080            if (components != null) {
12081                for (int i=0; i<components.size(); i++) {
12082                    if (components.get(i).equals(comp)) {
12083                        return true;
12084                    }
12085                }
12086            }
12087            if (objects != null) {
12088                for (int i=0; i<objects.size(); i++) {
12089                    if (System.identityHashCode(object) == objects.get(i)) {
12090                        return true;
12091                    }
12092                }
12093            }
12094            if (strings != null) {
12095                String flat = comp.flattenToString();
12096                for (int i=0; i<strings.size(); i++) {
12097                    if (flat.contains(strings.get(i))) {
12098                        return true;
12099                    }
12100                }
12101            }
12102            return false;
12103        }
12104    }
12105
12106    /**
12107     * There are three things that cmd can be:
12108     *  - a flattened component name that matches an existing activity
12109     *  - the cmd arg isn't the flattened component name of an existing activity:
12110     *    dump all activity whose component contains the cmd as a substring
12111     *  - A hex number of the ActivityRecord object instance.
12112     */
12113    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12114            int opti, boolean dumpAll) {
12115        ArrayList<ActivityRecord> activities;
12116
12117        synchronized (this) {
12118            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12119        }
12120
12121        if (activities.size() <= 0) {
12122            return false;
12123        }
12124
12125        String[] newArgs = new String[args.length - opti];
12126        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12127
12128        TaskRecord lastTask = null;
12129        boolean needSep = false;
12130        for (int i=activities.size()-1; i>=0; i--) {
12131            ActivityRecord r = activities.get(i);
12132            if (needSep) {
12133                pw.println();
12134            }
12135            needSep = true;
12136            synchronized (this) {
12137                if (lastTask != r.task) {
12138                    lastTask = r.task;
12139                    pw.print("TASK "); pw.print(lastTask.affinity);
12140                            pw.print(" id="); pw.println(lastTask.taskId);
12141                    if (dumpAll) {
12142                        lastTask.dump(pw, "  ");
12143                    }
12144                }
12145            }
12146            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12147        }
12148        return true;
12149    }
12150
12151    /**
12152     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12153     * there is a thread associated with the activity.
12154     */
12155    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12156            final ActivityRecord r, String[] args, boolean dumpAll) {
12157        String innerPrefix = prefix + "  ";
12158        synchronized (this) {
12159            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12160                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12161                    pw.print(" pid=");
12162                    if (r.app != null) pw.println(r.app.pid);
12163                    else pw.println("(not running)");
12164            if (dumpAll) {
12165                r.dump(pw, innerPrefix);
12166            }
12167        }
12168        if (r.app != null && r.app.thread != null) {
12169            // flush anything that is already in the PrintWriter since the thread is going
12170            // to write to the file descriptor directly
12171            pw.flush();
12172            try {
12173                TransferPipe tp = new TransferPipe();
12174                try {
12175                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12176                            r.appToken, innerPrefix, args);
12177                    tp.go(fd);
12178                } finally {
12179                    tp.kill();
12180                }
12181            } catch (IOException e) {
12182                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12183            } catch (RemoteException e) {
12184                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12185            }
12186        }
12187    }
12188
12189    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12190            int opti, boolean dumpAll, String dumpPackage) {
12191        boolean needSep = false;
12192        boolean onlyHistory = false;
12193        boolean printedAnything = false;
12194
12195        if ("history".equals(dumpPackage)) {
12196            if (opti < args.length && "-s".equals(args[opti])) {
12197                dumpAll = false;
12198            }
12199            onlyHistory = true;
12200            dumpPackage = null;
12201        }
12202
12203        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12204        if (!onlyHistory && dumpAll) {
12205            if (mRegisteredReceivers.size() > 0) {
12206                boolean printed = false;
12207                Iterator it = mRegisteredReceivers.values().iterator();
12208                while (it.hasNext()) {
12209                    ReceiverList r = (ReceiverList)it.next();
12210                    if (dumpPackage != null && (r.app == null ||
12211                            !dumpPackage.equals(r.app.info.packageName))) {
12212                        continue;
12213                    }
12214                    if (!printed) {
12215                        pw.println("  Registered Receivers:");
12216                        needSep = true;
12217                        printed = true;
12218                        printedAnything = true;
12219                    }
12220                    pw.print("  * "); pw.println(r);
12221                    r.dump(pw, "    ");
12222                }
12223            }
12224
12225            if (mReceiverResolver.dump(pw, needSep ?
12226                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12227                    "    ", dumpPackage, false)) {
12228                needSep = true;
12229                printedAnything = true;
12230            }
12231        }
12232
12233        for (BroadcastQueue q : mBroadcastQueues) {
12234            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12235            printedAnything |= needSep;
12236        }
12237
12238        needSep = true;
12239
12240        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12241            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12242                if (needSep) {
12243                    pw.println();
12244                }
12245                needSep = true;
12246                printedAnything = true;
12247                pw.print("  Sticky broadcasts for user ");
12248                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12249                StringBuilder sb = new StringBuilder(128);
12250                for (Map.Entry<String, ArrayList<Intent>> ent
12251                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12252                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12253                    if (dumpAll) {
12254                        pw.println(":");
12255                        ArrayList<Intent> intents = ent.getValue();
12256                        final int N = intents.size();
12257                        for (int i=0; i<N; i++) {
12258                            sb.setLength(0);
12259                            sb.append("    Intent: ");
12260                            intents.get(i).toShortString(sb, false, true, false, false);
12261                            pw.println(sb.toString());
12262                            Bundle bundle = intents.get(i).getExtras();
12263                            if (bundle != null) {
12264                                pw.print("      ");
12265                                pw.println(bundle.toString());
12266                            }
12267                        }
12268                    } else {
12269                        pw.println("");
12270                    }
12271                }
12272            }
12273        }
12274
12275        if (!onlyHistory && dumpAll) {
12276            pw.println();
12277            for (BroadcastQueue queue : mBroadcastQueues) {
12278                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12279                        + queue.mBroadcastsScheduled);
12280            }
12281            pw.println("  mHandler:");
12282            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12283            needSep = true;
12284            printedAnything = true;
12285        }
12286
12287        if (!printedAnything) {
12288            pw.println("  (nothing)");
12289        }
12290    }
12291
12292    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12293            int opti, boolean dumpAll, String dumpPackage) {
12294        boolean needSep;
12295        boolean printedAnything = false;
12296
12297        ItemMatcher matcher = new ItemMatcher();
12298        matcher.build(args, opti);
12299
12300        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12301
12302        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12303        printedAnything |= needSep;
12304
12305        if (mLaunchingProviders.size() > 0) {
12306            boolean printed = false;
12307            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12308                ContentProviderRecord r = mLaunchingProviders.get(i);
12309                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12310                    continue;
12311                }
12312                if (!printed) {
12313                    if (needSep) pw.println();
12314                    needSep = true;
12315                    pw.println("  Launching content providers:");
12316                    printed = true;
12317                    printedAnything = true;
12318                }
12319                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12320                        pw.println(r);
12321            }
12322        }
12323
12324        if (mGrantedUriPermissions.size() > 0) {
12325            boolean printed = false;
12326            int dumpUid = -2;
12327            if (dumpPackage != null) {
12328                try {
12329                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12330                } catch (NameNotFoundException e) {
12331                    dumpUid = -1;
12332                }
12333            }
12334            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12335                int uid = mGrantedUriPermissions.keyAt(i);
12336                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12337                    continue;
12338                }
12339                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12340                if (!printed) {
12341                    if (needSep) pw.println();
12342                    needSep = true;
12343                    pw.println("  Granted Uri Permissions:");
12344                    printed = true;
12345                    printedAnything = true;
12346                }
12347                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12348                for (UriPermission perm : perms.values()) {
12349                    pw.print("    "); pw.println(perm);
12350                    if (dumpAll) {
12351                        perm.dump(pw, "      ");
12352                    }
12353                }
12354            }
12355        }
12356
12357        if (!printedAnything) {
12358            pw.println("  (nothing)");
12359        }
12360    }
12361
12362    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12363            int opti, boolean dumpAll, String dumpPackage) {
12364        boolean printed = false;
12365
12366        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12367
12368        if (mIntentSenderRecords.size() > 0) {
12369            Iterator<WeakReference<PendingIntentRecord>> it
12370                    = mIntentSenderRecords.values().iterator();
12371            while (it.hasNext()) {
12372                WeakReference<PendingIntentRecord> ref = it.next();
12373                PendingIntentRecord rec = ref != null ? ref.get(): null;
12374                if (dumpPackage != null && (rec == null
12375                        || !dumpPackage.equals(rec.key.packageName))) {
12376                    continue;
12377                }
12378                printed = true;
12379                if (rec != null) {
12380                    pw.print("  * "); pw.println(rec);
12381                    if (dumpAll) {
12382                        rec.dump(pw, "    ");
12383                    }
12384                } else {
12385                    pw.print("  * "); pw.println(ref);
12386                }
12387            }
12388        }
12389
12390        if (!printed) {
12391            pw.println("  (nothing)");
12392        }
12393    }
12394
12395    private static final int dumpProcessList(PrintWriter pw,
12396            ActivityManagerService service, List list,
12397            String prefix, String normalLabel, String persistentLabel,
12398            String dumpPackage) {
12399        int numPers = 0;
12400        final int N = list.size()-1;
12401        for (int i=N; i>=0; i--) {
12402            ProcessRecord r = (ProcessRecord)list.get(i);
12403            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12404                continue;
12405            }
12406            pw.println(String.format("%s%s #%2d: %s",
12407                    prefix, (r.persistent ? persistentLabel : normalLabel),
12408                    i, r.toString()));
12409            if (r.persistent) {
12410                numPers++;
12411            }
12412        }
12413        return numPers;
12414    }
12415
12416    private static final boolean dumpProcessOomList(PrintWriter pw,
12417            ActivityManagerService service, List<ProcessRecord> origList,
12418            String prefix, String normalLabel, String persistentLabel,
12419            boolean inclDetails, String dumpPackage) {
12420
12421        ArrayList<Pair<ProcessRecord, Integer>> list
12422                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12423        for (int i=0; i<origList.size(); i++) {
12424            ProcessRecord r = origList.get(i);
12425            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12426                continue;
12427            }
12428            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12429        }
12430
12431        if (list.size() <= 0) {
12432            return false;
12433        }
12434
12435        Comparator<Pair<ProcessRecord, Integer>> comparator
12436                = new Comparator<Pair<ProcessRecord, Integer>>() {
12437            @Override
12438            public int compare(Pair<ProcessRecord, Integer> object1,
12439                    Pair<ProcessRecord, Integer> object2) {
12440                if (object1.first.setAdj != object2.first.setAdj) {
12441                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12442                }
12443                if (object1.second.intValue() != object2.second.intValue()) {
12444                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12445                }
12446                return 0;
12447            }
12448        };
12449
12450        Collections.sort(list, comparator);
12451
12452        final long curRealtime = SystemClock.elapsedRealtime();
12453        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12454        final long curUptime = SystemClock.uptimeMillis();
12455        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12456
12457        for (int i=list.size()-1; i>=0; i--) {
12458            ProcessRecord r = list.get(i).first;
12459            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12460            char schedGroup;
12461            switch (r.setSchedGroup) {
12462                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12463                    schedGroup = 'B';
12464                    break;
12465                case Process.THREAD_GROUP_DEFAULT:
12466                    schedGroup = 'F';
12467                    break;
12468                default:
12469                    schedGroup = '?';
12470                    break;
12471            }
12472            char foreground;
12473            if (r.foregroundActivities) {
12474                foreground = 'A';
12475            } else if (r.foregroundServices) {
12476                foreground = 'S';
12477            } else {
12478                foreground = ' ';
12479            }
12480            String procState = ProcessList.makeProcStateString(r.curProcState);
12481            pw.print(prefix);
12482            pw.print(r.persistent ? persistentLabel : normalLabel);
12483            pw.print(" #");
12484            int num = (origList.size()-1)-list.get(i).second;
12485            if (num < 10) pw.print(' ');
12486            pw.print(num);
12487            pw.print(": ");
12488            pw.print(oomAdj);
12489            pw.print(' ');
12490            pw.print(schedGroup);
12491            pw.print('/');
12492            pw.print(foreground);
12493            pw.print('/');
12494            pw.print(procState);
12495            pw.print(" trm:");
12496            if (r.trimMemoryLevel < 10) pw.print(' ');
12497            pw.print(r.trimMemoryLevel);
12498            pw.print(' ');
12499            pw.print(r.toShortString());
12500            pw.print(" (");
12501            pw.print(r.adjType);
12502            pw.println(')');
12503            if (r.adjSource != null || r.adjTarget != null) {
12504                pw.print(prefix);
12505                pw.print("    ");
12506                if (r.adjTarget instanceof ComponentName) {
12507                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12508                } else if (r.adjTarget != null) {
12509                    pw.print(r.adjTarget.toString());
12510                } else {
12511                    pw.print("{null}");
12512                }
12513                pw.print("<=");
12514                if (r.adjSource instanceof ProcessRecord) {
12515                    pw.print("Proc{");
12516                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12517                    pw.println("}");
12518                } else if (r.adjSource != null) {
12519                    pw.println(r.adjSource.toString());
12520                } else {
12521                    pw.println("{null}");
12522                }
12523            }
12524            if (inclDetails) {
12525                pw.print(prefix);
12526                pw.print("    ");
12527                pw.print("oom: max="); pw.print(r.maxAdj);
12528                pw.print(" curRaw="); pw.print(r.curRawAdj);
12529                pw.print(" setRaw="); pw.print(r.setRawAdj);
12530                pw.print(" cur="); pw.print(r.curAdj);
12531                pw.print(" set="); pw.println(r.setAdj);
12532                pw.print(prefix);
12533                pw.print("    ");
12534                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12535                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12536                pw.print(" lastPss="); pw.print(r.lastPss);
12537                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12538                pw.print(prefix);
12539                pw.print("    ");
12540                pw.print("cached="); pw.print(r.cached);
12541                pw.print(" empty="); pw.print(r.empty);
12542                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12543
12544                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12545                    if (r.lastWakeTime != 0) {
12546                        long wtime;
12547                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12548                        synchronized (stats) {
12549                            wtime = stats.getProcessWakeTime(r.info.uid,
12550                                    r.pid, curRealtime);
12551                        }
12552                        long timeUsed = wtime - r.lastWakeTime;
12553                        pw.print(prefix);
12554                        pw.print("    ");
12555                        pw.print("keep awake over ");
12556                        TimeUtils.formatDuration(realtimeSince, pw);
12557                        pw.print(" used ");
12558                        TimeUtils.formatDuration(timeUsed, pw);
12559                        pw.print(" (");
12560                        pw.print((timeUsed*100)/realtimeSince);
12561                        pw.println("%)");
12562                    }
12563                    if (r.lastCpuTime != 0) {
12564                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12565                        pw.print(prefix);
12566                        pw.print("    ");
12567                        pw.print("run cpu over ");
12568                        TimeUtils.formatDuration(uptimeSince, pw);
12569                        pw.print(" used ");
12570                        TimeUtils.formatDuration(timeUsed, pw);
12571                        pw.print(" (");
12572                        pw.print((timeUsed*100)/uptimeSince);
12573                        pw.println("%)");
12574                    }
12575                }
12576            }
12577        }
12578        return true;
12579    }
12580
12581    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12582        ArrayList<ProcessRecord> procs;
12583        synchronized (this) {
12584            if (args != null && args.length > start
12585                    && args[start].charAt(0) != '-') {
12586                procs = new ArrayList<ProcessRecord>();
12587                int pid = -1;
12588                try {
12589                    pid = Integer.parseInt(args[start]);
12590                } catch (NumberFormatException e) {
12591                }
12592                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12593                    ProcessRecord proc = mLruProcesses.get(i);
12594                    if (proc.pid == pid) {
12595                        procs.add(proc);
12596                    } else if (proc.processName.equals(args[start])) {
12597                        procs.add(proc);
12598                    }
12599                }
12600                if (procs.size() <= 0) {
12601                    return null;
12602                }
12603            } else {
12604                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12605            }
12606        }
12607        return procs;
12608    }
12609
12610    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12611            PrintWriter pw, String[] args) {
12612        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12613        if (procs == null) {
12614            pw.println("No process found for: " + args[0]);
12615            return;
12616        }
12617
12618        long uptime = SystemClock.uptimeMillis();
12619        long realtime = SystemClock.elapsedRealtime();
12620        pw.println("Applications Graphics Acceleration Info:");
12621        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12622
12623        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12624            ProcessRecord r = procs.get(i);
12625            if (r.thread != null) {
12626                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12627                pw.flush();
12628                try {
12629                    TransferPipe tp = new TransferPipe();
12630                    try {
12631                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12632                        tp.go(fd);
12633                    } finally {
12634                        tp.kill();
12635                    }
12636                } catch (IOException e) {
12637                    pw.println("Failure while dumping the app: " + r);
12638                    pw.flush();
12639                } catch (RemoteException e) {
12640                    pw.println("Got a RemoteException while dumping the app " + r);
12641                    pw.flush();
12642                }
12643            }
12644        }
12645    }
12646
12647    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12648        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12649        if (procs == null) {
12650            pw.println("No process found for: " + args[0]);
12651            return;
12652        }
12653
12654        pw.println("Applications Database Info:");
12655
12656        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12657            ProcessRecord r = procs.get(i);
12658            if (r.thread != null) {
12659                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12660                pw.flush();
12661                try {
12662                    TransferPipe tp = new TransferPipe();
12663                    try {
12664                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12665                        tp.go(fd);
12666                    } finally {
12667                        tp.kill();
12668                    }
12669                } catch (IOException e) {
12670                    pw.println("Failure while dumping the app: " + r);
12671                    pw.flush();
12672                } catch (RemoteException e) {
12673                    pw.println("Got a RemoteException while dumping the app " + r);
12674                    pw.flush();
12675                }
12676            }
12677        }
12678    }
12679
12680    final static class MemItem {
12681        final boolean isProc;
12682        final String label;
12683        final String shortLabel;
12684        final long pss;
12685        final int id;
12686        final boolean hasActivities;
12687        ArrayList<MemItem> subitems;
12688
12689        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12690                boolean _hasActivities) {
12691            isProc = true;
12692            label = _label;
12693            shortLabel = _shortLabel;
12694            pss = _pss;
12695            id = _id;
12696            hasActivities = _hasActivities;
12697        }
12698
12699        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12700            isProc = false;
12701            label = _label;
12702            shortLabel = _shortLabel;
12703            pss = _pss;
12704            id = _id;
12705            hasActivities = false;
12706        }
12707    }
12708
12709    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12710            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12711        if (sort && !isCompact) {
12712            Collections.sort(items, new Comparator<MemItem>() {
12713                @Override
12714                public int compare(MemItem lhs, MemItem rhs) {
12715                    if (lhs.pss < rhs.pss) {
12716                        return 1;
12717                    } else if (lhs.pss > rhs.pss) {
12718                        return -1;
12719                    }
12720                    return 0;
12721                }
12722            });
12723        }
12724
12725        for (int i=0; i<items.size(); i++) {
12726            MemItem mi = items.get(i);
12727            if (!isCompact) {
12728                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12729            } else if (mi.isProc) {
12730                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12731                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12732                pw.println(mi.hasActivities ? ",a" : ",e");
12733            } else {
12734                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12735                pw.println(mi.pss);
12736            }
12737            if (mi.subitems != null) {
12738                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12739                        true, isCompact);
12740            }
12741        }
12742    }
12743
12744    // These are in KB.
12745    static final long[] DUMP_MEM_BUCKETS = new long[] {
12746        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12747        120*1024, 160*1024, 200*1024,
12748        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12749        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12750    };
12751
12752    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12753            boolean stackLike) {
12754        int start = label.lastIndexOf('.');
12755        if (start >= 0) start++;
12756        else start = 0;
12757        int end = label.length();
12758        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12759            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12760                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12761                out.append(bucket);
12762                out.append(stackLike ? "MB." : "MB ");
12763                out.append(label, start, end);
12764                return;
12765            }
12766        }
12767        out.append(memKB/1024);
12768        out.append(stackLike ? "MB." : "MB ");
12769        out.append(label, start, end);
12770    }
12771
12772    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12773            ProcessList.NATIVE_ADJ,
12774            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12775            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12776            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12777            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12778            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12779    };
12780    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12781            "Native",
12782            "System", "Persistent", "Foreground",
12783            "Visible", "Perceptible",
12784            "Heavy Weight", "Backup",
12785            "A Services", "Home",
12786            "Previous", "B Services", "Cached"
12787    };
12788    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12789            "native",
12790            "sys", "pers", "fore",
12791            "vis", "percept",
12792            "heavy", "backup",
12793            "servicea", "home",
12794            "prev", "serviceb", "cached"
12795    };
12796
12797    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12798            long realtime, boolean isCheckinRequest, boolean isCompact) {
12799        if (isCheckinRequest || isCompact) {
12800            // short checkin version
12801            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12802        } else {
12803            pw.println("Applications Memory Usage (kB):");
12804            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12805        }
12806    }
12807
12808    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12809            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12810        boolean dumpDetails = false;
12811        boolean dumpFullDetails = false;
12812        boolean dumpDalvik = false;
12813        boolean oomOnly = false;
12814        boolean isCompact = false;
12815        boolean localOnly = false;
12816
12817        int opti = 0;
12818        while (opti < args.length) {
12819            String opt = args[opti];
12820            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12821                break;
12822            }
12823            opti++;
12824            if ("-a".equals(opt)) {
12825                dumpDetails = true;
12826                dumpFullDetails = true;
12827                dumpDalvik = true;
12828            } else if ("-d".equals(opt)) {
12829                dumpDalvik = true;
12830            } else if ("-c".equals(opt)) {
12831                isCompact = true;
12832            } else if ("--oom".equals(opt)) {
12833                oomOnly = true;
12834            } else if ("--local".equals(opt)) {
12835                localOnly = true;
12836            } else if ("-h".equals(opt)) {
12837                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12838                pw.println("  -a: include all available information for each process.");
12839                pw.println("  -d: include dalvik details when dumping process details.");
12840                pw.println("  -c: dump in a compact machine-parseable representation.");
12841                pw.println("  --oom: only show processes organized by oom adj.");
12842                pw.println("  --local: only collect details locally, don't call process.");
12843                pw.println("If [process] is specified it can be the name or ");
12844                pw.println("pid of a specific process to dump.");
12845                return;
12846            } else {
12847                pw.println("Unknown argument: " + opt + "; use -h for help");
12848            }
12849        }
12850
12851        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12852        long uptime = SystemClock.uptimeMillis();
12853        long realtime = SystemClock.elapsedRealtime();
12854        final long[] tmpLong = new long[1];
12855
12856        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12857        if (procs == null) {
12858            // No Java processes.  Maybe they want to print a native process.
12859            if (args != null && args.length > opti
12860                    && args[opti].charAt(0) != '-') {
12861                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12862                        = new ArrayList<ProcessCpuTracker.Stats>();
12863                updateCpuStatsNow();
12864                int findPid = -1;
12865                try {
12866                    findPid = Integer.parseInt(args[opti]);
12867                } catch (NumberFormatException e) {
12868                }
12869                synchronized (mProcessCpuThread) {
12870                    final int N = mProcessCpuTracker.countStats();
12871                    for (int i=0; i<N; i++) {
12872                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12873                        if (st.pid == findPid || (st.baseName != null
12874                                && st.baseName.equals(args[opti]))) {
12875                            nativeProcs.add(st);
12876                        }
12877                    }
12878                }
12879                if (nativeProcs.size() > 0) {
12880                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12881                            isCompact);
12882                    Debug.MemoryInfo mi = null;
12883                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12884                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12885                        final int pid = r.pid;
12886                        if (!isCheckinRequest && dumpDetails) {
12887                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12888                        }
12889                        if (mi == null) {
12890                            mi = new Debug.MemoryInfo();
12891                        }
12892                        if (dumpDetails || (!brief && !oomOnly)) {
12893                            Debug.getMemoryInfo(pid, mi);
12894                        } else {
12895                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12896                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12897                        }
12898                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12899                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12900                        if (isCheckinRequest) {
12901                            pw.println();
12902                        }
12903                    }
12904                    return;
12905                }
12906            }
12907            pw.println("No process found for: " + args[opti]);
12908            return;
12909        }
12910
12911        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12912            dumpDetails = true;
12913        }
12914
12915        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12916
12917        String[] innerArgs = new String[args.length-opti];
12918        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12919
12920        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12921        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12922        long nativePss=0, dalvikPss=0, otherPss=0;
12923        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12924
12925        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12926        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12927                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12928
12929        long totalPss = 0;
12930        long cachedPss = 0;
12931
12932        Debug.MemoryInfo mi = null;
12933        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12934            final ProcessRecord r = procs.get(i);
12935            final IApplicationThread thread;
12936            final int pid;
12937            final int oomAdj;
12938            final boolean hasActivities;
12939            synchronized (this) {
12940                thread = r.thread;
12941                pid = r.pid;
12942                oomAdj = r.getSetAdjWithServices();
12943                hasActivities = r.activities.size() > 0;
12944            }
12945            if (thread != null) {
12946                if (!isCheckinRequest && dumpDetails) {
12947                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12948                }
12949                if (mi == null) {
12950                    mi = new Debug.MemoryInfo();
12951                }
12952                if (dumpDetails || (!brief && !oomOnly)) {
12953                    Debug.getMemoryInfo(pid, mi);
12954                } else {
12955                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12956                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12957                }
12958                if (dumpDetails) {
12959                    if (localOnly) {
12960                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12961                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12962                        if (isCheckinRequest) {
12963                            pw.println();
12964                        }
12965                    } else {
12966                        try {
12967                            pw.flush();
12968                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12969                                    dumpDalvik, innerArgs);
12970                        } catch (RemoteException e) {
12971                            if (!isCheckinRequest) {
12972                                pw.println("Got RemoteException!");
12973                                pw.flush();
12974                            }
12975                        }
12976                    }
12977                }
12978
12979                final long myTotalPss = mi.getTotalPss();
12980                final long myTotalUss = mi.getTotalUss();
12981
12982                synchronized (this) {
12983                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12984                        // Record this for posterity if the process has been stable.
12985                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12986                    }
12987                }
12988
12989                if (!isCheckinRequest && mi != null) {
12990                    totalPss += myTotalPss;
12991                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12992                            (hasActivities ? " / activities)" : ")"),
12993                            r.processName, myTotalPss, pid, hasActivities);
12994                    procMems.add(pssItem);
12995                    procMemsMap.put(pid, pssItem);
12996
12997                    nativePss += mi.nativePss;
12998                    dalvikPss += mi.dalvikPss;
12999                    otherPss += mi.otherPss;
13000                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13001                        long mem = mi.getOtherPss(j);
13002                        miscPss[j] += mem;
13003                        otherPss -= mem;
13004                    }
13005
13006                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13007                        cachedPss += myTotalPss;
13008                    }
13009
13010                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13011                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13012                                || oomIndex == (oomPss.length-1)) {
13013                            oomPss[oomIndex] += myTotalPss;
13014                            if (oomProcs[oomIndex] == null) {
13015                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13016                            }
13017                            oomProcs[oomIndex].add(pssItem);
13018                            break;
13019                        }
13020                    }
13021                }
13022            }
13023        }
13024
13025        long nativeProcTotalPss = 0;
13026
13027        if (!isCheckinRequest && procs.size() > 1) {
13028            // If we are showing aggregations, also look for native processes to
13029            // include so that our aggregations are more accurate.
13030            updateCpuStatsNow();
13031            synchronized (mProcessCpuThread) {
13032                final int N = mProcessCpuTracker.countStats();
13033                for (int i=0; i<N; i++) {
13034                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13035                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13036                        if (mi == null) {
13037                            mi = new Debug.MemoryInfo();
13038                        }
13039                        if (!brief && !oomOnly) {
13040                            Debug.getMemoryInfo(st.pid, mi);
13041                        } else {
13042                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13043                            mi.nativePrivateDirty = (int)tmpLong[0];
13044                        }
13045
13046                        final long myTotalPss = mi.getTotalPss();
13047                        totalPss += myTotalPss;
13048                        nativeProcTotalPss += myTotalPss;
13049
13050                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13051                                st.name, myTotalPss, st.pid, false);
13052                        procMems.add(pssItem);
13053
13054                        nativePss += mi.nativePss;
13055                        dalvikPss += mi.dalvikPss;
13056                        otherPss += mi.otherPss;
13057                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13058                            long mem = mi.getOtherPss(j);
13059                            miscPss[j] += mem;
13060                            otherPss -= mem;
13061                        }
13062                        oomPss[0] += myTotalPss;
13063                        if (oomProcs[0] == null) {
13064                            oomProcs[0] = new ArrayList<MemItem>();
13065                        }
13066                        oomProcs[0].add(pssItem);
13067                    }
13068                }
13069            }
13070
13071            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13072
13073            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13074            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13075            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13076            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13077                String label = Debug.MemoryInfo.getOtherLabel(j);
13078                catMems.add(new MemItem(label, label, miscPss[j], j));
13079            }
13080
13081            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13082            for (int j=0; j<oomPss.length; j++) {
13083                if (oomPss[j] != 0) {
13084                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13085                            : DUMP_MEM_OOM_LABEL[j];
13086                    MemItem item = new MemItem(label, label, oomPss[j],
13087                            DUMP_MEM_OOM_ADJ[j]);
13088                    item.subitems = oomProcs[j];
13089                    oomMems.add(item);
13090                }
13091            }
13092
13093            if (!brief && !oomOnly && !isCompact) {
13094                pw.println();
13095                pw.println("Total PSS by process:");
13096                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13097                pw.println();
13098            }
13099            if (!isCompact) {
13100                pw.println("Total PSS by OOM adjustment:");
13101            }
13102            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13103            if (!brief && !oomOnly) {
13104                PrintWriter out = categoryPw != null ? categoryPw : pw;
13105                if (!isCompact) {
13106                    out.println();
13107                    out.println("Total PSS by category:");
13108                }
13109                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13110            }
13111            if (!isCompact) {
13112                pw.println();
13113            }
13114            MemInfoReader memInfo = new MemInfoReader();
13115            memInfo.readMemInfo();
13116            if (nativeProcTotalPss > 0) {
13117                synchronized (this) {
13118                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13119                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13120                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13121                            nativeProcTotalPss);
13122                }
13123            }
13124            if (!brief) {
13125                if (!isCompact) {
13126                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13127                    pw.print(" kB (status ");
13128                    switch (mLastMemoryLevel) {
13129                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13130                            pw.println("normal)");
13131                            break;
13132                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13133                            pw.println("moderate)");
13134                            break;
13135                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13136                            pw.println("low)");
13137                            break;
13138                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13139                            pw.println("critical)");
13140                            break;
13141                        default:
13142                            pw.print(mLastMemoryLevel);
13143                            pw.println(")");
13144                            break;
13145                    }
13146                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13147                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13148                            pw.print(cachedPss); pw.print(" cached pss + ");
13149                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13150                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13151                } else {
13152                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13153                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13154                            + memInfo.getFreeSizeKb()); pw.print(",");
13155                    pw.println(totalPss - cachedPss);
13156                }
13157            }
13158            if (!isCompact) {
13159                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13160                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13161                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13162                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13163                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13164                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13165                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13166                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13167                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13168                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13169                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13170            }
13171            if (!brief) {
13172                if (memInfo.getZramTotalSizeKb() != 0) {
13173                    if (!isCompact) {
13174                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13175                                pw.print(" kB physical used for ");
13176                                pw.print(memInfo.getSwapTotalSizeKb()
13177                                        - memInfo.getSwapFreeSizeKb());
13178                                pw.print(" kB in swap (");
13179                                pw.print(memInfo.getSwapTotalSizeKb());
13180                                pw.println(" kB total swap)");
13181                    } else {
13182                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13183                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13184                                pw.println(memInfo.getSwapFreeSizeKb());
13185                    }
13186                }
13187                final int[] SINGLE_LONG_FORMAT = new int[] {
13188                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13189                };
13190                long[] longOut = new long[1];
13191                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13192                        SINGLE_LONG_FORMAT, null, longOut, null);
13193                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13194                longOut[0] = 0;
13195                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13196                        SINGLE_LONG_FORMAT, null, longOut, null);
13197                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13198                longOut[0] = 0;
13199                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13200                        SINGLE_LONG_FORMAT, null, longOut, null);
13201                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13202                longOut[0] = 0;
13203                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13204                        SINGLE_LONG_FORMAT, null, longOut, null);
13205                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13206                if (!isCompact) {
13207                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13208                        pw.print("      KSM: "); pw.print(sharing);
13209                                pw.print(" kB saved from shared ");
13210                                pw.print(shared); pw.println(" kB");
13211                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13212                                pw.print(voltile); pw.println(" kB volatile");
13213                    }
13214                    pw.print("   Tuning: ");
13215                    pw.print(ActivityManager.staticGetMemoryClass());
13216                    pw.print(" (large ");
13217                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13218                    pw.print("), oom ");
13219                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13220                    pw.print(" kB");
13221                    pw.print(", restore limit ");
13222                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13223                    pw.print(" kB");
13224                    if (ActivityManager.isLowRamDeviceStatic()) {
13225                        pw.print(" (low-ram)");
13226                    }
13227                    if (ActivityManager.isHighEndGfx()) {
13228                        pw.print(" (high-end-gfx)");
13229                    }
13230                    pw.println();
13231                } else {
13232                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13233                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13234                    pw.println(voltile);
13235                    pw.print("tuning,");
13236                    pw.print(ActivityManager.staticGetMemoryClass());
13237                    pw.print(',');
13238                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13239                    pw.print(',');
13240                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13241                    if (ActivityManager.isLowRamDeviceStatic()) {
13242                        pw.print(",low-ram");
13243                    }
13244                    if (ActivityManager.isHighEndGfx()) {
13245                        pw.print(",high-end-gfx");
13246                    }
13247                    pw.println();
13248                }
13249            }
13250        }
13251    }
13252
13253    /**
13254     * Searches array of arguments for the specified string
13255     * @param args array of argument strings
13256     * @param value value to search for
13257     * @return true if the value is contained in the array
13258     */
13259    private static boolean scanArgs(String[] args, String value) {
13260        if (args != null) {
13261            for (String arg : args) {
13262                if (value.equals(arg)) {
13263                    return true;
13264                }
13265            }
13266        }
13267        return false;
13268    }
13269
13270    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13271            ContentProviderRecord cpr, boolean always) {
13272        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13273
13274        if (!inLaunching || always) {
13275            synchronized (cpr) {
13276                cpr.launchingApp = null;
13277                cpr.notifyAll();
13278            }
13279            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13280            String names[] = cpr.info.authority.split(";");
13281            for (int j = 0; j < names.length; j++) {
13282                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13283            }
13284        }
13285
13286        for (int i=0; i<cpr.connections.size(); i++) {
13287            ContentProviderConnection conn = cpr.connections.get(i);
13288            if (conn.waiting) {
13289                // If this connection is waiting for the provider, then we don't
13290                // need to mess with its process unless we are always removing
13291                // or for some reason the provider is not currently launching.
13292                if (inLaunching && !always) {
13293                    continue;
13294                }
13295            }
13296            ProcessRecord capp = conn.client;
13297            conn.dead = true;
13298            if (conn.stableCount > 0) {
13299                if (!capp.persistent && capp.thread != null
13300                        && capp.pid != 0
13301                        && capp.pid != MY_PID) {
13302                    killUnneededProcessLocked(capp, "depends on provider "
13303                            + cpr.name.flattenToShortString()
13304                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13305                }
13306            } else if (capp.thread != null && conn.provider.provider != null) {
13307                try {
13308                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13309                } catch (RemoteException e) {
13310                }
13311                // In the protocol here, we don't expect the client to correctly
13312                // clean up this connection, we'll just remove it.
13313                cpr.connections.remove(i);
13314                conn.client.conProviders.remove(conn);
13315            }
13316        }
13317
13318        if (inLaunching && always) {
13319            mLaunchingProviders.remove(cpr);
13320        }
13321        return inLaunching;
13322    }
13323
13324    /**
13325     * Main code for cleaning up a process when it has gone away.  This is
13326     * called both as a result of the process dying, or directly when stopping
13327     * a process when running in single process mode.
13328     */
13329    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13330            boolean restarting, boolean allowRestart, int index) {
13331        if (index >= 0) {
13332            removeLruProcessLocked(app);
13333            ProcessList.remove(app.pid);
13334        }
13335
13336        mProcessesToGc.remove(app);
13337        mPendingPssProcesses.remove(app);
13338
13339        // Dismiss any open dialogs.
13340        if (app.crashDialog != null && !app.forceCrashReport) {
13341            app.crashDialog.dismiss();
13342            app.crashDialog = null;
13343        }
13344        if (app.anrDialog != null) {
13345            app.anrDialog.dismiss();
13346            app.anrDialog = null;
13347        }
13348        if (app.waitDialog != null) {
13349            app.waitDialog.dismiss();
13350            app.waitDialog = null;
13351        }
13352
13353        app.crashing = false;
13354        app.notResponding = false;
13355
13356        app.resetPackageList(mProcessStats);
13357        app.unlinkDeathRecipient();
13358        app.makeInactive(mProcessStats);
13359        app.waitingToKill = null;
13360        app.forcingToForeground = null;
13361        updateProcessForegroundLocked(app, false, false);
13362        app.foregroundActivities = false;
13363        app.hasShownUi = false;
13364        app.treatLikeActivity = false;
13365        app.hasAboveClient = false;
13366        app.hasClientActivities = false;
13367
13368        mServices.killServicesLocked(app, allowRestart);
13369
13370        boolean restart = false;
13371
13372        // Remove published content providers.
13373        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13374            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13375            final boolean always = app.bad || !allowRestart;
13376            if (removeDyingProviderLocked(app, cpr, always) || always) {
13377                // We left the provider in the launching list, need to
13378                // restart it.
13379                restart = true;
13380            }
13381
13382            cpr.provider = null;
13383            cpr.proc = null;
13384        }
13385        app.pubProviders.clear();
13386
13387        // Take care of any launching providers waiting for this process.
13388        if (checkAppInLaunchingProvidersLocked(app, false)) {
13389            restart = true;
13390        }
13391
13392        // Unregister from connected content providers.
13393        if (!app.conProviders.isEmpty()) {
13394            for (int i=0; i<app.conProviders.size(); i++) {
13395                ContentProviderConnection conn = app.conProviders.get(i);
13396                conn.provider.connections.remove(conn);
13397            }
13398            app.conProviders.clear();
13399        }
13400
13401        // At this point there may be remaining entries in mLaunchingProviders
13402        // where we were the only one waiting, so they are no longer of use.
13403        // Look for these and clean up if found.
13404        // XXX Commented out for now.  Trying to figure out a way to reproduce
13405        // the actual situation to identify what is actually going on.
13406        if (false) {
13407            for (int i=0; i<mLaunchingProviders.size(); i++) {
13408                ContentProviderRecord cpr = (ContentProviderRecord)
13409                        mLaunchingProviders.get(i);
13410                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13411                    synchronized (cpr) {
13412                        cpr.launchingApp = null;
13413                        cpr.notifyAll();
13414                    }
13415                }
13416            }
13417        }
13418
13419        skipCurrentReceiverLocked(app);
13420
13421        // Unregister any receivers.
13422        for (int i=app.receivers.size()-1; i>=0; i--) {
13423            removeReceiverLocked(app.receivers.valueAt(i));
13424        }
13425        app.receivers.clear();
13426
13427        // If the app is undergoing backup, tell the backup manager about it
13428        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13429            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13430                    + mBackupTarget.appInfo + " died during backup");
13431            try {
13432                IBackupManager bm = IBackupManager.Stub.asInterface(
13433                        ServiceManager.getService(Context.BACKUP_SERVICE));
13434                bm.agentDisconnected(app.info.packageName);
13435            } catch (RemoteException e) {
13436                // can't happen; backup manager is local
13437            }
13438        }
13439
13440        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13441            ProcessChangeItem item = mPendingProcessChanges.get(i);
13442            if (item.pid == app.pid) {
13443                mPendingProcessChanges.remove(i);
13444                mAvailProcessChanges.add(item);
13445            }
13446        }
13447        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13448
13449        // If the caller is restarting this app, then leave it in its
13450        // current lists and let the caller take care of it.
13451        if (restarting) {
13452            return;
13453        }
13454
13455        if (!app.persistent || app.isolated) {
13456            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13457                    "Removing non-persistent process during cleanup: " + app);
13458            mProcessNames.remove(app.processName, app.uid);
13459            mIsolatedProcesses.remove(app.uid);
13460            if (mHeavyWeightProcess == app) {
13461                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13462                        mHeavyWeightProcess.userId, 0));
13463                mHeavyWeightProcess = null;
13464            }
13465        } else if (!app.removed) {
13466            // This app is persistent, so we need to keep its record around.
13467            // If it is not already on the pending app list, add it there
13468            // and start a new process for it.
13469            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13470                mPersistentStartingProcesses.add(app);
13471                restart = true;
13472            }
13473        }
13474        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13475                "Clean-up removing on hold: " + app);
13476        mProcessesOnHold.remove(app);
13477
13478        if (app == mHomeProcess) {
13479            mHomeProcess = null;
13480        }
13481        if (app == mPreviousProcess) {
13482            mPreviousProcess = null;
13483        }
13484
13485        if (restart && !app.isolated) {
13486            // We have components that still need to be running in the
13487            // process, so re-launch it.
13488            mProcessNames.put(app.processName, app.uid, app);
13489            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13490        } else if (app.pid > 0 && app.pid != MY_PID) {
13491            // Goodbye!
13492            boolean removed;
13493            synchronized (mPidsSelfLocked) {
13494                mPidsSelfLocked.remove(app.pid);
13495                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13496            }
13497            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13498            if (app.isolated) {
13499                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13500            }
13501            app.setPid(0);
13502        }
13503    }
13504
13505    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13506        // Look through the content providers we are waiting to have launched,
13507        // and if any run in this process then either schedule a restart of
13508        // the process or kill the client waiting for it if this process has
13509        // gone bad.
13510        int NL = mLaunchingProviders.size();
13511        boolean restart = false;
13512        for (int i=0; i<NL; i++) {
13513            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13514            if (cpr.launchingApp == app) {
13515                if (!alwaysBad && !app.bad) {
13516                    restart = true;
13517                } else {
13518                    removeDyingProviderLocked(app, cpr, true);
13519                    // cpr should have been removed from mLaunchingProviders
13520                    NL = mLaunchingProviders.size();
13521                    i--;
13522                }
13523            }
13524        }
13525        return restart;
13526    }
13527
13528    // =========================================================
13529    // SERVICES
13530    // =========================================================
13531
13532    @Override
13533    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13534            int flags) {
13535        enforceNotIsolatedCaller("getServices");
13536        synchronized (this) {
13537            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13538        }
13539    }
13540
13541    @Override
13542    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13543        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13544        synchronized (this) {
13545            return mServices.getRunningServiceControlPanelLocked(name);
13546        }
13547    }
13548
13549    @Override
13550    public ComponentName startService(IApplicationThread caller, Intent service,
13551            String resolvedType, int userId) {
13552        enforceNotIsolatedCaller("startService");
13553        // Refuse possible leaked file descriptors
13554        if (service != null && service.hasFileDescriptors() == true) {
13555            throw new IllegalArgumentException("File descriptors passed in Intent");
13556        }
13557
13558        if (DEBUG_SERVICE)
13559            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13560        synchronized(this) {
13561            final int callingPid = Binder.getCallingPid();
13562            final int callingUid = Binder.getCallingUid();
13563            final long origId = Binder.clearCallingIdentity();
13564            ComponentName res = mServices.startServiceLocked(caller, service,
13565                    resolvedType, callingPid, callingUid, userId);
13566            Binder.restoreCallingIdentity(origId);
13567            return res;
13568        }
13569    }
13570
13571    ComponentName startServiceInPackage(int uid,
13572            Intent service, String resolvedType, int userId) {
13573        synchronized(this) {
13574            if (DEBUG_SERVICE)
13575                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13576            final long origId = Binder.clearCallingIdentity();
13577            ComponentName res = mServices.startServiceLocked(null, service,
13578                    resolvedType, -1, uid, userId);
13579            Binder.restoreCallingIdentity(origId);
13580            return res;
13581        }
13582    }
13583
13584    @Override
13585    public int stopService(IApplicationThread caller, Intent service,
13586            String resolvedType, int userId) {
13587        enforceNotIsolatedCaller("stopService");
13588        // Refuse possible leaked file descriptors
13589        if (service != null && service.hasFileDescriptors() == true) {
13590            throw new IllegalArgumentException("File descriptors passed in Intent");
13591        }
13592
13593        synchronized(this) {
13594            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13595        }
13596    }
13597
13598    @Override
13599    public IBinder peekService(Intent service, String resolvedType) {
13600        enforceNotIsolatedCaller("peekService");
13601        // Refuse possible leaked file descriptors
13602        if (service != null && service.hasFileDescriptors() == true) {
13603            throw new IllegalArgumentException("File descriptors passed in Intent");
13604        }
13605        synchronized(this) {
13606            return mServices.peekServiceLocked(service, resolvedType);
13607        }
13608    }
13609
13610    @Override
13611    public boolean stopServiceToken(ComponentName className, IBinder token,
13612            int startId) {
13613        synchronized(this) {
13614            return mServices.stopServiceTokenLocked(className, token, startId);
13615        }
13616    }
13617
13618    @Override
13619    public void setServiceForeground(ComponentName className, IBinder token,
13620            int id, Notification notification, boolean removeNotification) {
13621        synchronized(this) {
13622            mServices.setServiceForegroundLocked(className, token, id, notification,
13623                    removeNotification);
13624        }
13625    }
13626
13627    @Override
13628    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13629            boolean requireFull, String name, String callerPackage) {
13630        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13631                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13632    }
13633
13634    int unsafeConvertIncomingUser(int userId) {
13635        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13636                ? mCurrentUserId : userId;
13637    }
13638
13639    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13640            int allowMode, String name, String callerPackage) {
13641        final int callingUserId = UserHandle.getUserId(callingUid);
13642        if (callingUserId == userId) {
13643            return userId;
13644        }
13645
13646        // Note that we may be accessing mCurrentUserId outside of a lock...
13647        // shouldn't be a big deal, if this is being called outside
13648        // of a locked context there is intrinsically a race with
13649        // the value the caller will receive and someone else changing it.
13650        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13651        // we will switch to the calling user if access to the current user fails.
13652        int targetUserId = unsafeConvertIncomingUser(userId);
13653
13654        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13655            final boolean allow;
13656            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13657                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13658                // If the caller has this permission, they always pass go.  And collect $200.
13659                allow = true;
13660            } else if (allowMode == ALLOW_FULL_ONLY) {
13661                // We require full access, sucks to be you.
13662                allow = false;
13663            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13664                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13665                // If the caller does not have either permission, they are always doomed.
13666                allow = false;
13667            } else if (allowMode == ALLOW_NON_FULL) {
13668                // We are blanket allowing non-full access, you lucky caller!
13669                allow = true;
13670            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13671                // We may or may not allow this depending on whether the two users are
13672                // in the same profile.
13673                synchronized (mUserProfileGroupIdsSelfLocked) {
13674                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13675                            UserInfo.NO_PROFILE_GROUP_ID);
13676                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13677                            UserInfo.NO_PROFILE_GROUP_ID);
13678                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13679                            && callingProfile == targetProfile;
13680                }
13681            } else {
13682                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13683            }
13684            if (!allow) {
13685                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13686                    // In this case, they would like to just execute as their
13687                    // owner user instead of failing.
13688                    targetUserId = callingUserId;
13689                } else {
13690                    StringBuilder builder = new StringBuilder(128);
13691                    builder.append("Permission Denial: ");
13692                    builder.append(name);
13693                    if (callerPackage != null) {
13694                        builder.append(" from ");
13695                        builder.append(callerPackage);
13696                    }
13697                    builder.append(" asks to run as user ");
13698                    builder.append(userId);
13699                    builder.append(" but is calling from user ");
13700                    builder.append(UserHandle.getUserId(callingUid));
13701                    builder.append("; this requires ");
13702                    builder.append(INTERACT_ACROSS_USERS_FULL);
13703                    if (allowMode != ALLOW_FULL_ONLY) {
13704                        builder.append(" or ");
13705                        builder.append(INTERACT_ACROSS_USERS);
13706                    }
13707                    String msg = builder.toString();
13708                    Slog.w(TAG, msg);
13709                    throw new SecurityException(msg);
13710                }
13711            }
13712        }
13713        if (!allowAll && targetUserId < 0) {
13714            throw new IllegalArgumentException(
13715                    "Call does not support special user #" + targetUserId);
13716        }
13717        return targetUserId;
13718    }
13719
13720    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13721            String className, int flags) {
13722        boolean result = false;
13723        // For apps that don't have pre-defined UIDs, check for permission
13724        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13725            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13726                if (ActivityManager.checkUidPermission(
13727                        INTERACT_ACROSS_USERS,
13728                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13729                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13730                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13731                            + " requests FLAG_SINGLE_USER, but app does not hold "
13732                            + INTERACT_ACROSS_USERS;
13733                    Slog.w(TAG, msg);
13734                    throw new SecurityException(msg);
13735                }
13736                // Permission passed
13737                result = true;
13738            }
13739        } else if ("system".equals(componentProcessName)) {
13740            result = true;
13741        } else {
13742            // App with pre-defined UID, check if it's a persistent app
13743            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13744        }
13745        if (DEBUG_MU) {
13746            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13747                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13748        }
13749        return result;
13750    }
13751
13752    /**
13753     * Checks to see if the caller is in the same app as the singleton
13754     * component, or the component is in a special app. It allows special apps
13755     * to export singleton components but prevents exporting singleton
13756     * components for regular apps.
13757     */
13758    boolean isValidSingletonCall(int callingUid, int componentUid) {
13759        int componentAppId = UserHandle.getAppId(componentUid);
13760        return UserHandle.isSameApp(callingUid, componentUid)
13761                || componentAppId == Process.SYSTEM_UID
13762                || componentAppId == Process.PHONE_UID
13763                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13764                        == PackageManager.PERMISSION_GRANTED;
13765    }
13766
13767    public int bindService(IApplicationThread caller, IBinder token,
13768            Intent service, String resolvedType,
13769            IServiceConnection connection, int flags, int userId) {
13770        enforceNotIsolatedCaller("bindService");
13771        // Refuse possible leaked file descriptors
13772        if (service != null && service.hasFileDescriptors() == true) {
13773            throw new IllegalArgumentException("File descriptors passed in Intent");
13774        }
13775
13776        synchronized(this) {
13777            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13778                    connection, flags, userId);
13779        }
13780    }
13781
13782    public boolean unbindService(IServiceConnection connection) {
13783        synchronized (this) {
13784            return mServices.unbindServiceLocked(connection);
13785        }
13786    }
13787
13788    public void publishService(IBinder token, Intent intent, IBinder service) {
13789        // Refuse possible leaked file descriptors
13790        if (intent != null && intent.hasFileDescriptors() == true) {
13791            throw new IllegalArgumentException("File descriptors passed in Intent");
13792        }
13793
13794        synchronized(this) {
13795            if (!(token instanceof ServiceRecord)) {
13796                throw new IllegalArgumentException("Invalid service token");
13797            }
13798            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13799        }
13800    }
13801
13802    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13803        // Refuse possible leaked file descriptors
13804        if (intent != null && intent.hasFileDescriptors() == true) {
13805            throw new IllegalArgumentException("File descriptors passed in Intent");
13806        }
13807
13808        synchronized(this) {
13809            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13810        }
13811    }
13812
13813    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13814        synchronized(this) {
13815            if (!(token instanceof ServiceRecord)) {
13816                throw new IllegalArgumentException("Invalid service token");
13817            }
13818            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13819        }
13820    }
13821
13822    // =========================================================
13823    // BACKUP AND RESTORE
13824    // =========================================================
13825
13826    // Cause the target app to be launched if necessary and its backup agent
13827    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13828    // activity manager to announce its creation.
13829    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13830        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13831        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13832
13833        synchronized(this) {
13834            // !!! TODO: currently no check here that we're already bound
13835            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13836            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13837            synchronized (stats) {
13838                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13839            }
13840
13841            // Backup agent is now in use, its package can't be stopped.
13842            try {
13843                AppGlobals.getPackageManager().setPackageStoppedState(
13844                        app.packageName, false, UserHandle.getUserId(app.uid));
13845            } catch (RemoteException e) {
13846            } catch (IllegalArgumentException e) {
13847                Slog.w(TAG, "Failed trying to unstop package "
13848                        + app.packageName + ": " + e);
13849            }
13850
13851            BackupRecord r = new BackupRecord(ss, app, backupMode);
13852            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13853                    ? new ComponentName(app.packageName, app.backupAgentName)
13854                    : new ComponentName("android", "FullBackupAgent");
13855            // startProcessLocked() returns existing proc's record if it's already running
13856            ProcessRecord proc = startProcessLocked(app.processName, app,
13857                    false, 0, "backup", hostingName, false, false, false);
13858            if (proc == null) {
13859                Slog.e(TAG, "Unable to start backup agent process " + r);
13860                return false;
13861            }
13862
13863            r.app = proc;
13864            mBackupTarget = r;
13865            mBackupAppName = app.packageName;
13866
13867            // Try not to kill the process during backup
13868            updateOomAdjLocked(proc);
13869
13870            // If the process is already attached, schedule the creation of the backup agent now.
13871            // If it is not yet live, this will be done when it attaches to the framework.
13872            if (proc.thread != null) {
13873                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13874                try {
13875                    proc.thread.scheduleCreateBackupAgent(app,
13876                            compatibilityInfoForPackageLocked(app), backupMode);
13877                } catch (RemoteException e) {
13878                    // Will time out on the backup manager side
13879                }
13880            } else {
13881                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13882            }
13883            // Invariants: at this point, the target app process exists and the application
13884            // is either already running or in the process of coming up.  mBackupTarget and
13885            // mBackupAppName describe the app, so that when it binds back to the AM we
13886            // know that it's scheduled for a backup-agent operation.
13887        }
13888
13889        return true;
13890    }
13891
13892    @Override
13893    public void clearPendingBackup() {
13894        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13895        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13896
13897        synchronized (this) {
13898            mBackupTarget = null;
13899            mBackupAppName = null;
13900        }
13901    }
13902
13903    // A backup agent has just come up
13904    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13905        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13906                + " = " + agent);
13907
13908        synchronized(this) {
13909            if (!agentPackageName.equals(mBackupAppName)) {
13910                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13911                return;
13912            }
13913        }
13914
13915        long oldIdent = Binder.clearCallingIdentity();
13916        try {
13917            IBackupManager bm = IBackupManager.Stub.asInterface(
13918                    ServiceManager.getService(Context.BACKUP_SERVICE));
13919            bm.agentConnected(agentPackageName, agent);
13920        } catch (RemoteException e) {
13921            // can't happen; the backup manager service is local
13922        } catch (Exception e) {
13923            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13924            e.printStackTrace();
13925        } finally {
13926            Binder.restoreCallingIdentity(oldIdent);
13927        }
13928    }
13929
13930    // done with this agent
13931    public void unbindBackupAgent(ApplicationInfo appInfo) {
13932        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13933        if (appInfo == null) {
13934            Slog.w(TAG, "unbind backup agent for null app");
13935            return;
13936        }
13937
13938        synchronized(this) {
13939            try {
13940                if (mBackupAppName == null) {
13941                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13942                    return;
13943                }
13944
13945                if (!mBackupAppName.equals(appInfo.packageName)) {
13946                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13947                    return;
13948                }
13949
13950                // Not backing this app up any more; reset its OOM adjustment
13951                final ProcessRecord proc = mBackupTarget.app;
13952                updateOomAdjLocked(proc);
13953
13954                // If the app crashed during backup, 'thread' will be null here
13955                if (proc.thread != null) {
13956                    try {
13957                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13958                                compatibilityInfoForPackageLocked(appInfo));
13959                    } catch (Exception e) {
13960                        Slog.e(TAG, "Exception when unbinding backup agent:");
13961                        e.printStackTrace();
13962                    }
13963                }
13964            } finally {
13965                mBackupTarget = null;
13966                mBackupAppName = null;
13967            }
13968        }
13969    }
13970    // =========================================================
13971    // BROADCASTS
13972    // =========================================================
13973
13974    private final List getStickiesLocked(String action, IntentFilter filter,
13975            List cur, int userId) {
13976        final ContentResolver resolver = mContext.getContentResolver();
13977        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13978        if (stickies == null) {
13979            return cur;
13980        }
13981        final ArrayList<Intent> list = stickies.get(action);
13982        if (list == null) {
13983            return cur;
13984        }
13985        int N = list.size();
13986        for (int i=0; i<N; i++) {
13987            Intent intent = list.get(i);
13988            if (filter.match(resolver, intent, true, TAG) >= 0) {
13989                if (cur == null) {
13990                    cur = new ArrayList<Intent>();
13991                }
13992                cur.add(intent);
13993            }
13994        }
13995        return cur;
13996    }
13997
13998    boolean isPendingBroadcastProcessLocked(int pid) {
13999        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14000                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14001    }
14002
14003    void skipPendingBroadcastLocked(int pid) {
14004            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14005            for (BroadcastQueue queue : mBroadcastQueues) {
14006                queue.skipPendingBroadcastLocked(pid);
14007            }
14008    }
14009
14010    // The app just attached; send any pending broadcasts that it should receive
14011    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14012        boolean didSomething = false;
14013        for (BroadcastQueue queue : mBroadcastQueues) {
14014            didSomething |= queue.sendPendingBroadcastsLocked(app);
14015        }
14016        return didSomething;
14017    }
14018
14019    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14020            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14021        enforceNotIsolatedCaller("registerReceiver");
14022        int callingUid;
14023        int callingPid;
14024        synchronized(this) {
14025            ProcessRecord callerApp = null;
14026            if (caller != null) {
14027                callerApp = getRecordForAppLocked(caller);
14028                if (callerApp == null) {
14029                    throw new SecurityException(
14030                            "Unable to find app for caller " + caller
14031                            + " (pid=" + Binder.getCallingPid()
14032                            + ") when registering receiver " + receiver);
14033                }
14034                if (callerApp.info.uid != Process.SYSTEM_UID &&
14035                        !callerApp.pkgList.containsKey(callerPackage) &&
14036                        !"android".equals(callerPackage)) {
14037                    throw new SecurityException("Given caller package " + callerPackage
14038                            + " is not running in process " + callerApp);
14039                }
14040                callingUid = callerApp.info.uid;
14041                callingPid = callerApp.pid;
14042            } else {
14043                callerPackage = null;
14044                callingUid = Binder.getCallingUid();
14045                callingPid = Binder.getCallingPid();
14046            }
14047
14048            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14049                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14050
14051            List allSticky = null;
14052
14053            // Look for any matching sticky broadcasts...
14054            Iterator actions = filter.actionsIterator();
14055            if (actions != null) {
14056                while (actions.hasNext()) {
14057                    String action = (String)actions.next();
14058                    allSticky = getStickiesLocked(action, filter, allSticky,
14059                            UserHandle.USER_ALL);
14060                    allSticky = getStickiesLocked(action, filter, allSticky,
14061                            UserHandle.getUserId(callingUid));
14062                }
14063            } else {
14064                allSticky = getStickiesLocked(null, filter, allSticky,
14065                        UserHandle.USER_ALL);
14066                allSticky = getStickiesLocked(null, filter, allSticky,
14067                        UserHandle.getUserId(callingUid));
14068            }
14069
14070            // The first sticky in the list is returned directly back to
14071            // the client.
14072            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14073
14074            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14075                    + ": " + sticky);
14076
14077            if (receiver == null) {
14078                return sticky;
14079            }
14080
14081            ReceiverList rl
14082                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14083            if (rl == null) {
14084                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14085                        userId, receiver);
14086                if (rl.app != null) {
14087                    rl.app.receivers.add(rl);
14088                } else {
14089                    try {
14090                        receiver.asBinder().linkToDeath(rl, 0);
14091                    } catch (RemoteException e) {
14092                        return sticky;
14093                    }
14094                    rl.linkedToDeath = true;
14095                }
14096                mRegisteredReceivers.put(receiver.asBinder(), rl);
14097            } else if (rl.uid != callingUid) {
14098                throw new IllegalArgumentException(
14099                        "Receiver requested to register for uid " + callingUid
14100                        + " was previously registered for uid " + rl.uid);
14101            } else if (rl.pid != callingPid) {
14102                throw new IllegalArgumentException(
14103                        "Receiver requested to register for pid " + callingPid
14104                        + " was previously registered for pid " + rl.pid);
14105            } else if (rl.userId != userId) {
14106                throw new IllegalArgumentException(
14107                        "Receiver requested to register for user " + userId
14108                        + " was previously registered for user " + rl.userId);
14109            }
14110            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14111                    permission, callingUid, userId);
14112            rl.add(bf);
14113            if (!bf.debugCheck()) {
14114                Slog.w(TAG, "==> For Dynamic broadast");
14115            }
14116            mReceiverResolver.addFilter(bf);
14117
14118            // Enqueue broadcasts for all existing stickies that match
14119            // this filter.
14120            if (allSticky != null) {
14121                ArrayList receivers = new ArrayList();
14122                receivers.add(bf);
14123
14124                int N = allSticky.size();
14125                for (int i=0; i<N; i++) {
14126                    Intent intent = (Intent)allSticky.get(i);
14127                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14128                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14129                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14130                            null, null, false, true, true, -1);
14131                    queue.enqueueParallelBroadcastLocked(r);
14132                    queue.scheduleBroadcastsLocked();
14133                }
14134            }
14135
14136            return sticky;
14137        }
14138    }
14139
14140    public void unregisterReceiver(IIntentReceiver receiver) {
14141        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14142
14143        final long origId = Binder.clearCallingIdentity();
14144        try {
14145            boolean doTrim = false;
14146
14147            synchronized(this) {
14148                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14149                if (rl != null) {
14150                    if (rl.curBroadcast != null) {
14151                        BroadcastRecord r = rl.curBroadcast;
14152                        final boolean doNext = finishReceiverLocked(
14153                                receiver.asBinder(), r.resultCode, r.resultData,
14154                                r.resultExtras, r.resultAbort);
14155                        if (doNext) {
14156                            doTrim = true;
14157                            r.queue.processNextBroadcast(false);
14158                        }
14159                    }
14160
14161                    if (rl.app != null) {
14162                        rl.app.receivers.remove(rl);
14163                    }
14164                    removeReceiverLocked(rl);
14165                    if (rl.linkedToDeath) {
14166                        rl.linkedToDeath = false;
14167                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14168                    }
14169                }
14170            }
14171
14172            // If we actually concluded any broadcasts, we might now be able
14173            // to trim the recipients' apps from our working set
14174            if (doTrim) {
14175                trimApplications();
14176                return;
14177            }
14178
14179        } finally {
14180            Binder.restoreCallingIdentity(origId);
14181        }
14182    }
14183
14184    void removeReceiverLocked(ReceiverList rl) {
14185        mRegisteredReceivers.remove(rl.receiver.asBinder());
14186        int N = rl.size();
14187        for (int i=0; i<N; i++) {
14188            mReceiverResolver.removeFilter(rl.get(i));
14189        }
14190    }
14191
14192    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14193        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14194            ProcessRecord r = mLruProcesses.get(i);
14195            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14196                try {
14197                    r.thread.dispatchPackageBroadcast(cmd, packages);
14198                } catch (RemoteException ex) {
14199                }
14200            }
14201        }
14202    }
14203
14204    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14205            int[] users) {
14206        List<ResolveInfo> receivers = null;
14207        try {
14208            HashSet<ComponentName> singleUserReceivers = null;
14209            boolean scannedFirstReceivers = false;
14210            for (int user : users) {
14211                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14212                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14213                if (user != 0 && newReceivers != null) {
14214                    // If this is not the primary user, we need to check for
14215                    // any receivers that should be filtered out.
14216                    for (int i=0; i<newReceivers.size(); i++) {
14217                        ResolveInfo ri = newReceivers.get(i);
14218                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14219                            newReceivers.remove(i);
14220                            i--;
14221                        }
14222                    }
14223                }
14224                if (newReceivers != null && newReceivers.size() == 0) {
14225                    newReceivers = null;
14226                }
14227                if (receivers == null) {
14228                    receivers = newReceivers;
14229                } else if (newReceivers != null) {
14230                    // We need to concatenate the additional receivers
14231                    // found with what we have do far.  This would be easy,
14232                    // but we also need to de-dup any receivers that are
14233                    // singleUser.
14234                    if (!scannedFirstReceivers) {
14235                        // Collect any single user receivers we had already retrieved.
14236                        scannedFirstReceivers = true;
14237                        for (int i=0; i<receivers.size(); i++) {
14238                            ResolveInfo ri = receivers.get(i);
14239                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14240                                ComponentName cn = new ComponentName(
14241                                        ri.activityInfo.packageName, ri.activityInfo.name);
14242                                if (singleUserReceivers == null) {
14243                                    singleUserReceivers = new HashSet<ComponentName>();
14244                                }
14245                                singleUserReceivers.add(cn);
14246                            }
14247                        }
14248                    }
14249                    // Add the new results to the existing results, tracking
14250                    // and de-dupping single user receivers.
14251                    for (int i=0; i<newReceivers.size(); i++) {
14252                        ResolveInfo ri = newReceivers.get(i);
14253                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14254                            ComponentName cn = new ComponentName(
14255                                    ri.activityInfo.packageName, ri.activityInfo.name);
14256                            if (singleUserReceivers == null) {
14257                                singleUserReceivers = new HashSet<ComponentName>();
14258                            }
14259                            if (!singleUserReceivers.contains(cn)) {
14260                                singleUserReceivers.add(cn);
14261                                receivers.add(ri);
14262                            }
14263                        } else {
14264                            receivers.add(ri);
14265                        }
14266                    }
14267                }
14268            }
14269        } catch (RemoteException ex) {
14270            // pm is in same process, this will never happen.
14271        }
14272        return receivers;
14273    }
14274
14275    private final int broadcastIntentLocked(ProcessRecord callerApp,
14276            String callerPackage, Intent intent, String resolvedType,
14277            IIntentReceiver resultTo, int resultCode, String resultData,
14278            Bundle map, String requiredPermission, int appOp,
14279            boolean ordered, boolean sticky, int callingPid, int callingUid,
14280            int userId) {
14281        intent = new Intent(intent);
14282
14283        // By default broadcasts do not go to stopped apps.
14284        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14285
14286        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14287            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14288            + " ordered=" + ordered + " userid=" + userId);
14289        if ((resultTo != null) && !ordered) {
14290            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14291        }
14292
14293        userId = handleIncomingUser(callingPid, callingUid, userId,
14294                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14295
14296        // Make sure that the user who is receiving this broadcast is started.
14297        // If not, we will just skip it.
14298
14299
14300        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14301            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14302                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14303                Slog.w(TAG, "Skipping broadcast of " + intent
14304                        + ": user " + userId + " is stopped");
14305                return ActivityManager.BROADCAST_SUCCESS;
14306            }
14307        }
14308
14309        /*
14310         * Prevent non-system code (defined here to be non-persistent
14311         * processes) from sending protected broadcasts.
14312         */
14313        int callingAppId = UserHandle.getAppId(callingUid);
14314        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14315            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14316            || callingAppId == Process.NFC_UID || callingUid == 0) {
14317            // Always okay.
14318        } else if (callerApp == null || !callerApp.persistent) {
14319            try {
14320                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14321                        intent.getAction())) {
14322                    String msg = "Permission Denial: not allowed to send broadcast "
14323                            + intent.getAction() + " from pid="
14324                            + callingPid + ", uid=" + callingUid;
14325                    Slog.w(TAG, msg);
14326                    throw new SecurityException(msg);
14327                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14328                    // Special case for compatibility: we don't want apps to send this,
14329                    // but historically it has not been protected and apps may be using it
14330                    // to poke their own app widget.  So, instead of making it protected,
14331                    // just limit it to the caller.
14332                    if (callerApp == null) {
14333                        String msg = "Permission Denial: not allowed to send broadcast "
14334                                + intent.getAction() + " from unknown caller.";
14335                        Slog.w(TAG, msg);
14336                        throw new SecurityException(msg);
14337                    } else if (intent.getComponent() != null) {
14338                        // They are good enough to send to an explicit component...  verify
14339                        // it is being sent to the calling app.
14340                        if (!intent.getComponent().getPackageName().equals(
14341                                callerApp.info.packageName)) {
14342                            String msg = "Permission Denial: not allowed to send broadcast "
14343                                    + intent.getAction() + " to "
14344                                    + intent.getComponent().getPackageName() + " from "
14345                                    + callerApp.info.packageName;
14346                            Slog.w(TAG, msg);
14347                            throw new SecurityException(msg);
14348                        }
14349                    } else {
14350                        // Limit broadcast to their own package.
14351                        intent.setPackage(callerApp.info.packageName);
14352                    }
14353                }
14354            } catch (RemoteException e) {
14355                Slog.w(TAG, "Remote exception", e);
14356                return ActivityManager.BROADCAST_SUCCESS;
14357            }
14358        }
14359
14360        // Handle special intents: if this broadcast is from the package
14361        // manager about a package being removed, we need to remove all of
14362        // its activities from the history stack.
14363        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14364                intent.getAction());
14365        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14366                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14367                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14368                || uidRemoved) {
14369            if (checkComponentPermission(
14370                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14371                    callingPid, callingUid, -1, true)
14372                    == PackageManager.PERMISSION_GRANTED) {
14373                if (uidRemoved) {
14374                    final Bundle intentExtras = intent.getExtras();
14375                    final int uid = intentExtras != null
14376                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14377                    if (uid >= 0) {
14378                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14379                        synchronized (bs) {
14380                            bs.removeUidStatsLocked(uid);
14381                        }
14382                        mAppOpsService.uidRemoved(uid);
14383                    }
14384                } else {
14385                    // If resources are unavailable just force stop all
14386                    // those packages and flush the attribute cache as well.
14387                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14388                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14389                        if (list != null && (list.length > 0)) {
14390                            for (String pkg : list) {
14391                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14392                                        "storage unmount");
14393                            }
14394                            sendPackageBroadcastLocked(
14395                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14396                        }
14397                    } else {
14398                        Uri data = intent.getData();
14399                        String ssp;
14400                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14401                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14402                                    intent.getAction());
14403                            boolean fullUninstall = removed &&
14404                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14405                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14406                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14407                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14408                                        false, fullUninstall, userId,
14409                                        removed ? "pkg removed" : "pkg changed");
14410                            }
14411                            if (removed) {
14412                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14413                                        new String[] {ssp}, userId);
14414                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14415                                    mAppOpsService.packageRemoved(
14416                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14417
14418                                    // Remove all permissions granted from/to this package
14419                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14420                                }
14421                            }
14422                        }
14423                    }
14424                }
14425            } else {
14426                String msg = "Permission Denial: " + intent.getAction()
14427                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14428                        + ", uid=" + callingUid + ")"
14429                        + " requires "
14430                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14431                Slog.w(TAG, msg);
14432                throw new SecurityException(msg);
14433            }
14434
14435        // Special case for adding a package: by default turn on compatibility
14436        // mode.
14437        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14438            Uri data = intent.getData();
14439            String ssp;
14440            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14441                mCompatModePackages.handlePackageAddedLocked(ssp,
14442                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14443            }
14444        }
14445
14446        /*
14447         * If this is the time zone changed action, queue up a message that will reset the timezone
14448         * of all currently running processes. This message will get queued up before the broadcast
14449         * happens.
14450         */
14451        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14452            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14453        }
14454
14455        /*
14456         * If the user set the time, let all running processes know.
14457         */
14458        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14459            final int is24Hour = intent.getBooleanExtra(
14460                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14461            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14462        }
14463
14464        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14465            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14466        }
14467
14468        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14469            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14470            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14471        }
14472
14473        // Add to the sticky list if requested.
14474        if (sticky) {
14475            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14476                    callingPid, callingUid)
14477                    != PackageManager.PERMISSION_GRANTED) {
14478                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14479                        + callingPid + ", uid=" + callingUid
14480                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14481                Slog.w(TAG, msg);
14482                throw new SecurityException(msg);
14483            }
14484            if (requiredPermission != null) {
14485                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14486                        + " and enforce permission " + requiredPermission);
14487                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14488            }
14489            if (intent.getComponent() != null) {
14490                throw new SecurityException(
14491                        "Sticky broadcasts can't target a specific component");
14492            }
14493            // We use userId directly here, since the "all" target is maintained
14494            // as a separate set of sticky broadcasts.
14495            if (userId != UserHandle.USER_ALL) {
14496                // But first, if this is not a broadcast to all users, then
14497                // make sure it doesn't conflict with an existing broadcast to
14498                // all users.
14499                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14500                        UserHandle.USER_ALL);
14501                if (stickies != null) {
14502                    ArrayList<Intent> list = stickies.get(intent.getAction());
14503                    if (list != null) {
14504                        int N = list.size();
14505                        int i;
14506                        for (i=0; i<N; i++) {
14507                            if (intent.filterEquals(list.get(i))) {
14508                                throw new IllegalArgumentException(
14509                                        "Sticky broadcast " + intent + " for user "
14510                                        + userId + " conflicts with existing global broadcast");
14511                            }
14512                        }
14513                    }
14514                }
14515            }
14516            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14517            if (stickies == null) {
14518                stickies = new ArrayMap<String, ArrayList<Intent>>();
14519                mStickyBroadcasts.put(userId, stickies);
14520            }
14521            ArrayList<Intent> list = stickies.get(intent.getAction());
14522            if (list == null) {
14523                list = new ArrayList<Intent>();
14524                stickies.put(intent.getAction(), list);
14525            }
14526            int N = list.size();
14527            int i;
14528            for (i=0; i<N; i++) {
14529                if (intent.filterEquals(list.get(i))) {
14530                    // This sticky already exists, replace it.
14531                    list.set(i, new Intent(intent));
14532                    break;
14533                }
14534            }
14535            if (i >= N) {
14536                list.add(new Intent(intent));
14537            }
14538        }
14539
14540        int[] users;
14541        if (userId == UserHandle.USER_ALL) {
14542            // Caller wants broadcast to go to all started users.
14543            users = mStartedUserArray;
14544        } else {
14545            // Caller wants broadcast to go to one specific user.
14546            users = new int[] {userId};
14547        }
14548
14549        // Figure out who all will receive this broadcast.
14550        List receivers = null;
14551        List<BroadcastFilter> registeredReceivers = null;
14552        // Need to resolve the intent to interested receivers...
14553        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14554                 == 0) {
14555            receivers = collectReceiverComponents(intent, resolvedType, users);
14556        }
14557        if (intent.getComponent() == null) {
14558            registeredReceivers = mReceiverResolver.queryIntent(intent,
14559                    resolvedType, false, userId);
14560        }
14561
14562        final boolean replacePending =
14563                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14564
14565        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14566                + " replacePending=" + replacePending);
14567
14568        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14569        if (!ordered && NR > 0) {
14570            // If we are not serializing this broadcast, then send the
14571            // registered receivers separately so they don't wait for the
14572            // components to be launched.
14573            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14574            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14575                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14576                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14577                    ordered, sticky, false, userId);
14578            if (DEBUG_BROADCAST) Slog.v(
14579                    TAG, "Enqueueing parallel broadcast " + r);
14580            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14581            if (!replaced) {
14582                queue.enqueueParallelBroadcastLocked(r);
14583                queue.scheduleBroadcastsLocked();
14584            }
14585            registeredReceivers = null;
14586            NR = 0;
14587        }
14588
14589        // Merge into one list.
14590        int ir = 0;
14591        if (receivers != null) {
14592            // A special case for PACKAGE_ADDED: do not allow the package
14593            // being added to see this broadcast.  This prevents them from
14594            // using this as a back door to get run as soon as they are
14595            // installed.  Maybe in the future we want to have a special install
14596            // broadcast or such for apps, but we'd like to deliberately make
14597            // this decision.
14598            String skipPackages[] = null;
14599            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14600                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14601                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14602                Uri data = intent.getData();
14603                if (data != null) {
14604                    String pkgName = data.getSchemeSpecificPart();
14605                    if (pkgName != null) {
14606                        skipPackages = new String[] { pkgName };
14607                    }
14608                }
14609            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14610                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14611            }
14612            if (skipPackages != null && (skipPackages.length > 0)) {
14613                for (String skipPackage : skipPackages) {
14614                    if (skipPackage != null) {
14615                        int NT = receivers.size();
14616                        for (int it=0; it<NT; it++) {
14617                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14618                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14619                                receivers.remove(it);
14620                                it--;
14621                                NT--;
14622                            }
14623                        }
14624                    }
14625                }
14626            }
14627
14628            int NT = receivers != null ? receivers.size() : 0;
14629            int it = 0;
14630            ResolveInfo curt = null;
14631            BroadcastFilter curr = null;
14632            while (it < NT && ir < NR) {
14633                if (curt == null) {
14634                    curt = (ResolveInfo)receivers.get(it);
14635                }
14636                if (curr == null) {
14637                    curr = registeredReceivers.get(ir);
14638                }
14639                if (curr.getPriority() >= curt.priority) {
14640                    // Insert this broadcast record into the final list.
14641                    receivers.add(it, curr);
14642                    ir++;
14643                    curr = null;
14644                    it++;
14645                    NT++;
14646                } else {
14647                    // Skip to the next ResolveInfo in the final list.
14648                    it++;
14649                    curt = null;
14650                }
14651            }
14652        }
14653        while (ir < NR) {
14654            if (receivers == null) {
14655                receivers = new ArrayList();
14656            }
14657            receivers.add(registeredReceivers.get(ir));
14658            ir++;
14659        }
14660
14661        if ((receivers != null && receivers.size() > 0)
14662                || resultTo != null) {
14663            BroadcastQueue queue = broadcastQueueForIntent(intent);
14664            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14665                    callerPackage, callingPid, callingUid, resolvedType,
14666                    requiredPermission, appOp, receivers, resultTo, resultCode,
14667                    resultData, map, ordered, sticky, false, userId);
14668            if (DEBUG_BROADCAST) Slog.v(
14669                    TAG, "Enqueueing ordered broadcast " + r
14670                    + ": prev had " + queue.mOrderedBroadcasts.size());
14671            if (DEBUG_BROADCAST) {
14672                int seq = r.intent.getIntExtra("seq", -1);
14673                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14674            }
14675            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14676            if (!replaced) {
14677                queue.enqueueOrderedBroadcastLocked(r);
14678                queue.scheduleBroadcastsLocked();
14679            }
14680        }
14681
14682        return ActivityManager.BROADCAST_SUCCESS;
14683    }
14684
14685    final Intent verifyBroadcastLocked(Intent intent) {
14686        // Refuse possible leaked file descriptors
14687        if (intent != null && intent.hasFileDescriptors() == true) {
14688            throw new IllegalArgumentException("File descriptors passed in Intent");
14689        }
14690
14691        int flags = intent.getFlags();
14692
14693        if (!mProcessesReady) {
14694            // if the caller really truly claims to know what they're doing, go
14695            // ahead and allow the broadcast without launching any receivers
14696            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14697                intent = new Intent(intent);
14698                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14699            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14700                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14701                        + " before boot completion");
14702                throw new IllegalStateException("Cannot broadcast before boot completed");
14703            }
14704        }
14705
14706        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14707            throw new IllegalArgumentException(
14708                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14709        }
14710
14711        return intent;
14712    }
14713
14714    public final int broadcastIntent(IApplicationThread caller,
14715            Intent intent, String resolvedType, IIntentReceiver resultTo,
14716            int resultCode, String resultData, Bundle map,
14717            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14718        enforceNotIsolatedCaller("broadcastIntent");
14719        synchronized(this) {
14720            intent = verifyBroadcastLocked(intent);
14721
14722            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14723            final int callingPid = Binder.getCallingPid();
14724            final int callingUid = Binder.getCallingUid();
14725            final long origId = Binder.clearCallingIdentity();
14726            int res = broadcastIntentLocked(callerApp,
14727                    callerApp != null ? callerApp.info.packageName : null,
14728                    intent, resolvedType, resultTo,
14729                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14730                    callingPid, callingUid, userId);
14731            Binder.restoreCallingIdentity(origId);
14732            return res;
14733        }
14734    }
14735
14736    int broadcastIntentInPackage(String packageName, int uid,
14737            Intent intent, String resolvedType, IIntentReceiver resultTo,
14738            int resultCode, String resultData, Bundle map,
14739            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14740        synchronized(this) {
14741            intent = verifyBroadcastLocked(intent);
14742
14743            final long origId = Binder.clearCallingIdentity();
14744            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14745                    resultTo, resultCode, resultData, map, requiredPermission,
14746                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14747            Binder.restoreCallingIdentity(origId);
14748            return res;
14749        }
14750    }
14751
14752    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14753        // Refuse possible leaked file descriptors
14754        if (intent != null && intent.hasFileDescriptors() == true) {
14755            throw new IllegalArgumentException("File descriptors passed in Intent");
14756        }
14757
14758        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14759                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14760
14761        synchronized(this) {
14762            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14763                    != PackageManager.PERMISSION_GRANTED) {
14764                String msg = "Permission Denial: unbroadcastIntent() from pid="
14765                        + Binder.getCallingPid()
14766                        + ", uid=" + Binder.getCallingUid()
14767                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14768                Slog.w(TAG, msg);
14769                throw new SecurityException(msg);
14770            }
14771            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14772            if (stickies != null) {
14773                ArrayList<Intent> list = stickies.get(intent.getAction());
14774                if (list != null) {
14775                    int N = list.size();
14776                    int i;
14777                    for (i=0; i<N; i++) {
14778                        if (intent.filterEquals(list.get(i))) {
14779                            list.remove(i);
14780                            break;
14781                        }
14782                    }
14783                    if (list.size() <= 0) {
14784                        stickies.remove(intent.getAction());
14785                    }
14786                }
14787                if (stickies.size() <= 0) {
14788                    mStickyBroadcasts.remove(userId);
14789                }
14790            }
14791        }
14792    }
14793
14794    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14795            String resultData, Bundle resultExtras, boolean resultAbort) {
14796        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14797        if (r == null) {
14798            Slog.w(TAG, "finishReceiver called but not found on queue");
14799            return false;
14800        }
14801
14802        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14803    }
14804
14805    void backgroundServicesFinishedLocked(int userId) {
14806        for (BroadcastQueue queue : mBroadcastQueues) {
14807            queue.backgroundServicesFinishedLocked(userId);
14808        }
14809    }
14810
14811    public void finishReceiver(IBinder who, int resultCode, String resultData,
14812            Bundle resultExtras, boolean resultAbort) {
14813        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14814
14815        // Refuse possible leaked file descriptors
14816        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14817            throw new IllegalArgumentException("File descriptors passed in Bundle");
14818        }
14819
14820        final long origId = Binder.clearCallingIdentity();
14821        try {
14822            boolean doNext = false;
14823            BroadcastRecord r;
14824
14825            synchronized(this) {
14826                r = broadcastRecordForReceiverLocked(who);
14827                if (r != null) {
14828                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14829                        resultData, resultExtras, resultAbort, true);
14830                }
14831            }
14832
14833            if (doNext) {
14834                r.queue.processNextBroadcast(false);
14835            }
14836            trimApplications();
14837        } finally {
14838            Binder.restoreCallingIdentity(origId);
14839        }
14840    }
14841
14842    // =========================================================
14843    // INSTRUMENTATION
14844    // =========================================================
14845
14846    public boolean startInstrumentation(ComponentName className,
14847            String profileFile, int flags, Bundle arguments,
14848            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14849            int userId, String abiOverride) {
14850        enforceNotIsolatedCaller("startInstrumentation");
14851        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14852                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14853        // Refuse possible leaked file descriptors
14854        if (arguments != null && arguments.hasFileDescriptors()) {
14855            throw new IllegalArgumentException("File descriptors passed in Bundle");
14856        }
14857
14858        synchronized(this) {
14859            InstrumentationInfo ii = null;
14860            ApplicationInfo ai = null;
14861            try {
14862                ii = mContext.getPackageManager().getInstrumentationInfo(
14863                    className, STOCK_PM_FLAGS);
14864                ai = AppGlobals.getPackageManager().getApplicationInfo(
14865                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14866            } catch (PackageManager.NameNotFoundException e) {
14867            } catch (RemoteException e) {
14868            }
14869            if (ii == null) {
14870                reportStartInstrumentationFailure(watcher, className,
14871                        "Unable to find instrumentation info for: " + className);
14872                return false;
14873            }
14874            if (ai == null) {
14875                reportStartInstrumentationFailure(watcher, className,
14876                        "Unable to find instrumentation target package: " + ii.targetPackage);
14877                return false;
14878            }
14879
14880            int match = mContext.getPackageManager().checkSignatures(
14881                    ii.targetPackage, ii.packageName);
14882            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14883                String msg = "Permission Denial: starting instrumentation "
14884                        + className + " from pid="
14885                        + Binder.getCallingPid()
14886                        + ", uid=" + Binder.getCallingPid()
14887                        + " not allowed because package " + ii.packageName
14888                        + " does not have a signature matching the target "
14889                        + ii.targetPackage;
14890                reportStartInstrumentationFailure(watcher, className, msg);
14891                throw new SecurityException(msg);
14892            }
14893
14894            final long origId = Binder.clearCallingIdentity();
14895            // Instrumentation can kill and relaunch even persistent processes
14896            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14897                    "start instr");
14898            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14899            app.instrumentationClass = className;
14900            app.instrumentationInfo = ai;
14901            app.instrumentationProfileFile = profileFile;
14902            app.instrumentationArguments = arguments;
14903            app.instrumentationWatcher = watcher;
14904            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14905            app.instrumentationResultClass = className;
14906            Binder.restoreCallingIdentity(origId);
14907        }
14908
14909        return true;
14910    }
14911
14912    /**
14913     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14914     * error to the logs, but if somebody is watching, send the report there too.  This enables
14915     * the "am" command to report errors with more information.
14916     *
14917     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14918     * @param cn The component name of the instrumentation.
14919     * @param report The error report.
14920     */
14921    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14922            ComponentName cn, String report) {
14923        Slog.w(TAG, report);
14924        try {
14925            if (watcher != null) {
14926                Bundle results = new Bundle();
14927                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14928                results.putString("Error", report);
14929                watcher.instrumentationStatus(cn, -1, results);
14930            }
14931        } catch (RemoteException e) {
14932            Slog.w(TAG, e);
14933        }
14934    }
14935
14936    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14937        if (app.instrumentationWatcher != null) {
14938            try {
14939                // NOTE:  IInstrumentationWatcher *must* be oneway here
14940                app.instrumentationWatcher.instrumentationFinished(
14941                    app.instrumentationClass,
14942                    resultCode,
14943                    results);
14944            } catch (RemoteException e) {
14945            }
14946        }
14947        if (app.instrumentationUiAutomationConnection != null) {
14948            try {
14949                app.instrumentationUiAutomationConnection.shutdown();
14950            } catch (RemoteException re) {
14951                /* ignore */
14952            }
14953            // Only a UiAutomation can set this flag and now that
14954            // it is finished we make sure it is reset to its default.
14955            mUserIsMonkey = false;
14956        }
14957        app.instrumentationWatcher = null;
14958        app.instrumentationUiAutomationConnection = null;
14959        app.instrumentationClass = null;
14960        app.instrumentationInfo = null;
14961        app.instrumentationProfileFile = null;
14962        app.instrumentationArguments = null;
14963
14964        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14965                "finished inst");
14966    }
14967
14968    public void finishInstrumentation(IApplicationThread target,
14969            int resultCode, Bundle results) {
14970        int userId = UserHandle.getCallingUserId();
14971        // Refuse possible leaked file descriptors
14972        if (results != null && results.hasFileDescriptors()) {
14973            throw new IllegalArgumentException("File descriptors passed in Intent");
14974        }
14975
14976        synchronized(this) {
14977            ProcessRecord app = getRecordForAppLocked(target);
14978            if (app == null) {
14979                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14980                return;
14981            }
14982            final long origId = Binder.clearCallingIdentity();
14983            finishInstrumentationLocked(app, resultCode, results);
14984            Binder.restoreCallingIdentity(origId);
14985        }
14986    }
14987
14988    // =========================================================
14989    // CONFIGURATION
14990    // =========================================================
14991
14992    public ConfigurationInfo getDeviceConfigurationInfo() {
14993        ConfigurationInfo config = new ConfigurationInfo();
14994        synchronized (this) {
14995            config.reqTouchScreen = mConfiguration.touchscreen;
14996            config.reqKeyboardType = mConfiguration.keyboard;
14997            config.reqNavigation = mConfiguration.navigation;
14998            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14999                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15000                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15001            }
15002            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15003                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15004                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15005            }
15006            config.reqGlEsVersion = GL_ES_VERSION;
15007        }
15008        return config;
15009    }
15010
15011    ActivityStack getFocusedStack() {
15012        return mStackSupervisor.getFocusedStack();
15013    }
15014
15015    public Configuration getConfiguration() {
15016        Configuration ci;
15017        synchronized(this) {
15018            ci = new Configuration(mConfiguration);
15019        }
15020        return ci;
15021    }
15022
15023    public void updatePersistentConfiguration(Configuration values) {
15024        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15025                "updateConfiguration()");
15026        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15027                "updateConfiguration()");
15028        if (values == null) {
15029            throw new NullPointerException("Configuration must not be null");
15030        }
15031
15032        synchronized(this) {
15033            final long origId = Binder.clearCallingIdentity();
15034            updateConfigurationLocked(values, null, true, false);
15035            Binder.restoreCallingIdentity(origId);
15036        }
15037    }
15038
15039    public void updateConfiguration(Configuration values) {
15040        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15041                "updateConfiguration()");
15042
15043        synchronized(this) {
15044            if (values == null && mWindowManager != null) {
15045                // sentinel: fetch the current configuration from the window manager
15046                values = mWindowManager.computeNewConfiguration();
15047            }
15048
15049            if (mWindowManager != null) {
15050                mProcessList.applyDisplaySize(mWindowManager);
15051            }
15052
15053            final long origId = Binder.clearCallingIdentity();
15054            if (values != null) {
15055                Settings.System.clearConfiguration(values);
15056            }
15057            updateConfigurationLocked(values, null, false, false);
15058            Binder.restoreCallingIdentity(origId);
15059        }
15060    }
15061
15062    /**
15063     * Do either or both things: (1) change the current configuration, and (2)
15064     * make sure the given activity is running with the (now) current
15065     * configuration.  Returns true if the activity has been left running, or
15066     * false if <var>starting</var> is being destroyed to match the new
15067     * configuration.
15068     * @param persistent TODO
15069     */
15070    boolean updateConfigurationLocked(Configuration values,
15071            ActivityRecord starting, boolean persistent, boolean initLocale) {
15072        int changes = 0;
15073
15074        if (values != null) {
15075            Configuration newConfig = new Configuration(mConfiguration);
15076            changes = newConfig.updateFrom(values);
15077            if (changes != 0) {
15078                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15079                    Slog.i(TAG, "Updating configuration to: " + values);
15080                }
15081
15082                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15083
15084                if (values.locale != null && !initLocale) {
15085                    saveLocaleLocked(values.locale,
15086                                     !values.locale.equals(mConfiguration.locale),
15087                                     values.userSetLocale);
15088                }
15089
15090                mConfigurationSeq++;
15091                if (mConfigurationSeq <= 0) {
15092                    mConfigurationSeq = 1;
15093                }
15094                newConfig.seq = mConfigurationSeq;
15095                mConfiguration = newConfig;
15096                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15097                //mUsageStatsService.noteStartConfig(newConfig);
15098
15099                final Configuration configCopy = new Configuration(mConfiguration);
15100
15101                // TODO: If our config changes, should we auto dismiss any currently
15102                // showing dialogs?
15103                mShowDialogs = shouldShowDialogs(newConfig);
15104
15105                AttributeCache ac = AttributeCache.instance();
15106                if (ac != null) {
15107                    ac.updateConfiguration(configCopy);
15108                }
15109
15110                // Make sure all resources in our process are updated
15111                // right now, so that anyone who is going to retrieve
15112                // resource values after we return will be sure to get
15113                // the new ones.  This is especially important during
15114                // boot, where the first config change needs to guarantee
15115                // all resources have that config before following boot
15116                // code is executed.
15117                mSystemThread.applyConfigurationToResources(configCopy);
15118
15119                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15120                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15121                    msg.obj = new Configuration(configCopy);
15122                    mHandler.sendMessage(msg);
15123                }
15124
15125                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15126                    ProcessRecord app = mLruProcesses.get(i);
15127                    try {
15128                        if (app.thread != null) {
15129                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15130                                    + app.processName + " new config " + mConfiguration);
15131                            app.thread.scheduleConfigurationChanged(configCopy);
15132                        }
15133                    } catch (Exception e) {
15134                    }
15135                }
15136                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15137                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15138                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15139                        | Intent.FLAG_RECEIVER_FOREGROUND);
15140                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15141                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15142                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15143                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15144                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15145                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15146                    broadcastIntentLocked(null, null, intent,
15147                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15148                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15149                }
15150            }
15151        }
15152
15153        boolean kept = true;
15154        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15155        // mainStack is null during startup.
15156        if (mainStack != null) {
15157            if (changes != 0 && starting == null) {
15158                // If the configuration changed, and the caller is not already
15159                // in the process of starting an activity, then find the top
15160                // activity to check if its configuration needs to change.
15161                starting = mainStack.topRunningActivityLocked(null);
15162            }
15163
15164            if (starting != null) {
15165                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15166                // And we need to make sure at this point that all other activities
15167                // are made visible with the correct configuration.
15168                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15169            }
15170        }
15171
15172        if (values != null && mWindowManager != null) {
15173            mWindowManager.setNewConfiguration(mConfiguration);
15174        }
15175
15176        return kept;
15177    }
15178
15179    /**
15180     * Decide based on the configuration whether we should shouw the ANR,
15181     * crash, etc dialogs.  The idea is that if there is no affordnace to
15182     * press the on-screen buttons, we shouldn't show the dialog.
15183     *
15184     * A thought: SystemUI might also want to get told about this, the Power
15185     * dialog / global actions also might want different behaviors.
15186     */
15187    private static final boolean shouldShowDialogs(Configuration config) {
15188        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15189                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15190    }
15191
15192    /**
15193     * Save the locale.  You must be inside a synchronized (this) block.
15194     */
15195    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15196        if(isDiff) {
15197            SystemProperties.set("user.language", l.getLanguage());
15198            SystemProperties.set("user.region", l.getCountry());
15199        }
15200
15201        if(isPersist) {
15202            SystemProperties.set("persist.sys.language", l.getLanguage());
15203            SystemProperties.set("persist.sys.country", l.getCountry());
15204            SystemProperties.set("persist.sys.localevar", l.getVariant());
15205        }
15206    }
15207
15208    @Override
15209    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15210        ActivityRecord srec = ActivityRecord.forToken(token);
15211        return srec != null && srec.task.affinity != null &&
15212                srec.task.affinity.equals(destAffinity);
15213    }
15214
15215    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15216            Intent resultData) {
15217
15218        synchronized (this) {
15219            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15220            if (stack != null) {
15221                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15222            }
15223            return false;
15224        }
15225    }
15226
15227    public int getLaunchedFromUid(IBinder activityToken) {
15228        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15229        if (srec == null) {
15230            return -1;
15231        }
15232        return srec.launchedFromUid;
15233    }
15234
15235    public String getLaunchedFromPackage(IBinder activityToken) {
15236        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15237        if (srec == null) {
15238            return null;
15239        }
15240        return srec.launchedFromPackage;
15241    }
15242
15243    // =========================================================
15244    // LIFETIME MANAGEMENT
15245    // =========================================================
15246
15247    // Returns which broadcast queue the app is the current [or imminent] receiver
15248    // on, or 'null' if the app is not an active broadcast recipient.
15249    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15250        BroadcastRecord r = app.curReceiver;
15251        if (r != null) {
15252            return r.queue;
15253        }
15254
15255        // It's not the current receiver, but it might be starting up to become one
15256        synchronized (this) {
15257            for (BroadcastQueue queue : mBroadcastQueues) {
15258                r = queue.mPendingBroadcast;
15259                if (r != null && r.curApp == app) {
15260                    // found it; report which queue it's in
15261                    return queue;
15262                }
15263            }
15264        }
15265
15266        return null;
15267    }
15268
15269    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15270            boolean doingAll, long now) {
15271        if (mAdjSeq == app.adjSeq) {
15272            // This adjustment has already been computed.
15273            return app.curRawAdj;
15274        }
15275
15276        if (app.thread == null) {
15277            app.adjSeq = mAdjSeq;
15278            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15279            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15280            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15281        }
15282
15283        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15284        app.adjSource = null;
15285        app.adjTarget = null;
15286        app.empty = false;
15287        app.cached = false;
15288
15289        final int activitiesSize = app.activities.size();
15290
15291        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15292            // The max adjustment doesn't allow this app to be anything
15293            // below foreground, so it is not worth doing work for it.
15294            app.adjType = "fixed";
15295            app.adjSeq = mAdjSeq;
15296            app.curRawAdj = app.maxAdj;
15297            app.foregroundActivities = false;
15298            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15299            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15300            // System processes can do UI, and when they do we want to have
15301            // them trim their memory after the user leaves the UI.  To
15302            // facilitate this, here we need to determine whether or not it
15303            // is currently showing UI.
15304            app.systemNoUi = true;
15305            if (app == TOP_APP) {
15306                app.systemNoUi = false;
15307            } else if (activitiesSize > 0) {
15308                for (int j = 0; j < activitiesSize; j++) {
15309                    final ActivityRecord r = app.activities.get(j);
15310                    if (r.visible) {
15311                        app.systemNoUi = false;
15312                    }
15313                }
15314            }
15315            if (!app.systemNoUi) {
15316                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15317            }
15318            return (app.curAdj=app.maxAdj);
15319        }
15320
15321        app.systemNoUi = false;
15322
15323        // Determine the importance of the process, starting with most
15324        // important to least, and assign an appropriate OOM adjustment.
15325        int adj;
15326        int schedGroup;
15327        int procState;
15328        boolean foregroundActivities = false;
15329        BroadcastQueue queue;
15330        if (app == TOP_APP) {
15331            // The last app on the list is the foreground app.
15332            adj = ProcessList.FOREGROUND_APP_ADJ;
15333            schedGroup = Process.THREAD_GROUP_DEFAULT;
15334            app.adjType = "top-activity";
15335            foregroundActivities = true;
15336            procState = ActivityManager.PROCESS_STATE_TOP;
15337        } else if (app.instrumentationClass != null) {
15338            // Don't want to kill running instrumentation.
15339            adj = ProcessList.FOREGROUND_APP_ADJ;
15340            schedGroup = Process.THREAD_GROUP_DEFAULT;
15341            app.adjType = "instrumentation";
15342            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15343        } else if ((queue = isReceivingBroadcast(app)) != null) {
15344            // An app that is currently receiving a broadcast also
15345            // counts as being in the foreground for OOM killer purposes.
15346            // It's placed in a sched group based on the nature of the
15347            // broadcast as reflected by which queue it's active in.
15348            adj = ProcessList.FOREGROUND_APP_ADJ;
15349            schedGroup = (queue == mFgBroadcastQueue)
15350                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15351            app.adjType = "broadcast";
15352            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15353        } else if (app.executingServices.size() > 0) {
15354            // An app that is currently executing a service callback also
15355            // counts as being in the foreground.
15356            adj = ProcessList.FOREGROUND_APP_ADJ;
15357            schedGroup = app.execServicesFg ?
15358                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15359            app.adjType = "exec-service";
15360            procState = ActivityManager.PROCESS_STATE_SERVICE;
15361            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15362        } else {
15363            // As far as we know the process is empty.  We may change our mind later.
15364            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15365            // At this point we don't actually know the adjustment.  Use the cached adj
15366            // value that the caller wants us to.
15367            adj = cachedAdj;
15368            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15369            app.cached = true;
15370            app.empty = true;
15371            app.adjType = "cch-empty";
15372        }
15373
15374        // Examine all activities if not already foreground.
15375        if (!foregroundActivities && activitiesSize > 0) {
15376            for (int j = 0; j < activitiesSize; j++) {
15377                final ActivityRecord r = app.activities.get(j);
15378                if (r.app != app) {
15379                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15380                            + app + "?!?");
15381                    continue;
15382                }
15383                if (r.visible) {
15384                    // App has a visible activity; only upgrade adjustment.
15385                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15386                        adj = ProcessList.VISIBLE_APP_ADJ;
15387                        app.adjType = "visible";
15388                    }
15389                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15390                        procState = ActivityManager.PROCESS_STATE_TOP;
15391                    }
15392                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15393                    app.cached = false;
15394                    app.empty = false;
15395                    foregroundActivities = true;
15396                    break;
15397                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15398                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15399                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15400                        app.adjType = "pausing";
15401                    }
15402                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15403                        procState = ActivityManager.PROCESS_STATE_TOP;
15404                    }
15405                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15406                    app.cached = false;
15407                    app.empty = false;
15408                    foregroundActivities = true;
15409                } else if (r.state == ActivityState.STOPPING) {
15410                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15411                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15412                        app.adjType = "stopping";
15413                    }
15414                    // For the process state, we will at this point consider the
15415                    // process to be cached.  It will be cached either as an activity
15416                    // or empty depending on whether the activity is finishing.  We do
15417                    // this so that we can treat the process as cached for purposes of
15418                    // memory trimming (determing current memory level, trim command to
15419                    // send to process) since there can be an arbitrary number of stopping
15420                    // processes and they should soon all go into the cached state.
15421                    if (!r.finishing) {
15422                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15423                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15424                        }
15425                    }
15426                    app.cached = false;
15427                    app.empty = false;
15428                    foregroundActivities = true;
15429                } else {
15430                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15431                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15432                        app.adjType = "cch-act";
15433                    }
15434                }
15435            }
15436        }
15437
15438        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15439            if (app.foregroundServices) {
15440                // The user is aware of this app, so make it visible.
15441                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15442                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15443                app.cached = false;
15444                app.adjType = "fg-service";
15445                schedGroup = Process.THREAD_GROUP_DEFAULT;
15446            } else if (app.forcingToForeground != null) {
15447                // The user is aware of this app, so make it visible.
15448                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15449                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15450                app.cached = false;
15451                app.adjType = "force-fg";
15452                app.adjSource = app.forcingToForeground;
15453                schedGroup = Process.THREAD_GROUP_DEFAULT;
15454            }
15455        }
15456
15457        if (app == mHeavyWeightProcess) {
15458            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15459                // We don't want to kill the current heavy-weight process.
15460                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15461                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15462                app.cached = false;
15463                app.adjType = "heavy";
15464            }
15465            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15466                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15467            }
15468        }
15469
15470        if (app == mHomeProcess) {
15471            if (adj > ProcessList.HOME_APP_ADJ) {
15472                // This process is hosting what we currently consider to be the
15473                // home app, so we don't want to let it go into the background.
15474                adj = ProcessList.HOME_APP_ADJ;
15475                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15476                app.cached = false;
15477                app.adjType = "home";
15478            }
15479            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15480                procState = ActivityManager.PROCESS_STATE_HOME;
15481            }
15482        }
15483
15484        if (app == mPreviousProcess && app.activities.size() > 0) {
15485            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15486                // This was the previous process that showed UI to the user.
15487                // We want to try to keep it around more aggressively, to give
15488                // a good experience around switching between two apps.
15489                adj = ProcessList.PREVIOUS_APP_ADJ;
15490                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15491                app.cached = false;
15492                app.adjType = "previous";
15493            }
15494            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15495                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15496            }
15497        }
15498
15499        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15500                + " reason=" + app.adjType);
15501
15502        // By default, we use the computed adjustment.  It may be changed if
15503        // there are applications dependent on our services or providers, but
15504        // this gives us a baseline and makes sure we don't get into an
15505        // infinite recursion.
15506        app.adjSeq = mAdjSeq;
15507        app.curRawAdj = adj;
15508        app.hasStartedServices = false;
15509
15510        if (mBackupTarget != null && app == mBackupTarget.app) {
15511            // If possible we want to avoid killing apps while they're being backed up
15512            if (adj > ProcessList.BACKUP_APP_ADJ) {
15513                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15514                adj = ProcessList.BACKUP_APP_ADJ;
15515                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15516                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15517                }
15518                app.adjType = "backup";
15519                app.cached = false;
15520            }
15521            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15522                procState = ActivityManager.PROCESS_STATE_BACKUP;
15523            }
15524        }
15525
15526        boolean mayBeTop = false;
15527
15528        for (int is = app.services.size()-1;
15529                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15530                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15531                        || procState > ActivityManager.PROCESS_STATE_TOP);
15532                is--) {
15533            ServiceRecord s = app.services.valueAt(is);
15534            if (s.startRequested) {
15535                app.hasStartedServices = true;
15536                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15537                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15538                }
15539                if (app.hasShownUi && app != mHomeProcess) {
15540                    // If this process has shown some UI, let it immediately
15541                    // go to the LRU list because it may be pretty heavy with
15542                    // UI stuff.  We'll tag it with a label just to help
15543                    // debug and understand what is going on.
15544                    if (adj > ProcessList.SERVICE_ADJ) {
15545                        app.adjType = "cch-started-ui-services";
15546                    }
15547                } else {
15548                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15549                        // This service has seen some activity within
15550                        // recent memory, so we will keep its process ahead
15551                        // of the background processes.
15552                        if (adj > ProcessList.SERVICE_ADJ) {
15553                            adj = ProcessList.SERVICE_ADJ;
15554                            app.adjType = "started-services";
15555                            app.cached = false;
15556                        }
15557                    }
15558                    // If we have let the service slide into the background
15559                    // state, still have some text describing what it is doing
15560                    // even though the service no longer has an impact.
15561                    if (adj > ProcessList.SERVICE_ADJ) {
15562                        app.adjType = "cch-started-services";
15563                    }
15564                }
15565            }
15566            for (int conni = s.connections.size()-1;
15567                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15568                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15569                            || procState > ActivityManager.PROCESS_STATE_TOP);
15570                    conni--) {
15571                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15572                for (int i = 0;
15573                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15574                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15575                                || procState > ActivityManager.PROCESS_STATE_TOP);
15576                        i++) {
15577                    // XXX should compute this based on the max of
15578                    // all connected clients.
15579                    ConnectionRecord cr = clist.get(i);
15580                    if (cr.binding.client == app) {
15581                        // Binding to ourself is not interesting.
15582                        continue;
15583                    }
15584                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15585                        ProcessRecord client = cr.binding.client;
15586                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15587                                TOP_APP, doingAll, now);
15588                        int clientProcState = client.curProcState;
15589                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15590                            // If the other app is cached for any reason, for purposes here
15591                            // we are going to consider it empty.  The specific cached state
15592                            // doesn't propagate except under certain conditions.
15593                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15594                        }
15595                        String adjType = null;
15596                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15597                            // Not doing bind OOM management, so treat
15598                            // this guy more like a started service.
15599                            if (app.hasShownUi && app != mHomeProcess) {
15600                                // If this process has shown some UI, let it immediately
15601                                // go to the LRU list because it may be pretty heavy with
15602                                // UI stuff.  We'll tag it with a label just to help
15603                                // debug and understand what is going on.
15604                                if (adj > clientAdj) {
15605                                    adjType = "cch-bound-ui-services";
15606                                }
15607                                app.cached = false;
15608                                clientAdj = adj;
15609                                clientProcState = procState;
15610                            } else {
15611                                if (now >= (s.lastActivity
15612                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15613                                    // This service has not seen activity within
15614                                    // recent memory, so allow it to drop to the
15615                                    // LRU list if there is no other reason to keep
15616                                    // it around.  We'll also tag it with a label just
15617                                    // to help debug and undertand what is going on.
15618                                    if (adj > clientAdj) {
15619                                        adjType = "cch-bound-services";
15620                                    }
15621                                    clientAdj = adj;
15622                                }
15623                            }
15624                        }
15625                        if (adj > clientAdj) {
15626                            // If this process has recently shown UI, and
15627                            // the process that is binding to it is less
15628                            // important than being visible, then we don't
15629                            // care about the binding as much as we care
15630                            // about letting this process get into the LRU
15631                            // list to be killed and restarted if needed for
15632                            // memory.
15633                            if (app.hasShownUi && app != mHomeProcess
15634                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15635                                adjType = "cch-bound-ui-services";
15636                            } else {
15637                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15638                                        |Context.BIND_IMPORTANT)) != 0) {
15639                                    adj = clientAdj;
15640                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15641                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15642                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15643                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15644                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15645                                    adj = clientAdj;
15646                                } else {
15647                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15648                                        adj = ProcessList.VISIBLE_APP_ADJ;
15649                                    }
15650                                }
15651                                if (!client.cached) {
15652                                    app.cached = false;
15653                                }
15654                                adjType = "service";
15655                            }
15656                        }
15657                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15658                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15659                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15660                            }
15661                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15662                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15663                                    // Special handling of clients who are in the top state.
15664                                    // We *may* want to consider this process to be in the
15665                                    // top state as well, but only if there is not another
15666                                    // reason for it to be running.  Being on the top is a
15667                                    // special state, meaning you are specifically running
15668                                    // for the current top app.  If the process is already
15669                                    // running in the background for some other reason, it
15670                                    // is more important to continue considering it to be
15671                                    // in the background state.
15672                                    mayBeTop = true;
15673                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15674                                } else {
15675                                    // Special handling for above-top states (persistent
15676                                    // processes).  These should not bring the current process
15677                                    // into the top state, since they are not on top.  Instead
15678                                    // give them the best state after that.
15679                                    clientProcState =
15680                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15681                                }
15682                            }
15683                        } else {
15684                            if (clientProcState <
15685                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15686                                clientProcState =
15687                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15688                            }
15689                        }
15690                        if (procState > clientProcState) {
15691                            procState = clientProcState;
15692                        }
15693                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15694                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15695                            app.pendingUiClean = true;
15696                        }
15697                        if (adjType != null) {
15698                            app.adjType = adjType;
15699                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15700                                    .REASON_SERVICE_IN_USE;
15701                            app.adjSource = cr.binding.client;
15702                            app.adjSourceProcState = clientProcState;
15703                            app.adjTarget = s.name;
15704                        }
15705                    }
15706                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15707                        app.treatLikeActivity = true;
15708                    }
15709                    final ActivityRecord a = cr.activity;
15710                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15711                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15712                                (a.visible || a.state == ActivityState.RESUMED
15713                                 || a.state == ActivityState.PAUSING)) {
15714                            adj = ProcessList.FOREGROUND_APP_ADJ;
15715                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15716                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15717                            }
15718                            app.cached = false;
15719                            app.adjType = "service";
15720                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15721                                    .REASON_SERVICE_IN_USE;
15722                            app.adjSource = a;
15723                            app.adjSourceProcState = procState;
15724                            app.adjTarget = s.name;
15725                        }
15726                    }
15727                }
15728            }
15729        }
15730
15731        for (int provi = app.pubProviders.size()-1;
15732                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15733                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15734                        || procState > ActivityManager.PROCESS_STATE_TOP);
15735                provi--) {
15736            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15737            for (int i = cpr.connections.size()-1;
15738                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15739                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15740                            || procState > ActivityManager.PROCESS_STATE_TOP);
15741                    i--) {
15742                ContentProviderConnection conn = cpr.connections.get(i);
15743                ProcessRecord client = conn.client;
15744                if (client == app) {
15745                    // Being our own client is not interesting.
15746                    continue;
15747                }
15748                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15749                int clientProcState = client.curProcState;
15750                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15751                    // If the other app is cached for any reason, for purposes here
15752                    // we are going to consider it empty.
15753                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15754                }
15755                if (adj > clientAdj) {
15756                    if (app.hasShownUi && app != mHomeProcess
15757                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15758                        app.adjType = "cch-ui-provider";
15759                    } else {
15760                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15761                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15762                        app.adjType = "provider";
15763                    }
15764                    app.cached &= client.cached;
15765                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15766                            .REASON_PROVIDER_IN_USE;
15767                    app.adjSource = client;
15768                    app.adjSourceProcState = clientProcState;
15769                    app.adjTarget = cpr.name;
15770                }
15771                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15772                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15773                        // Special handling of clients who are in the top state.
15774                        // We *may* want to consider this process to be in the
15775                        // top state as well, but only if there is not another
15776                        // reason for it to be running.  Being on the top is a
15777                        // special state, meaning you are specifically running
15778                        // for the current top app.  If the process is already
15779                        // running in the background for some other reason, it
15780                        // is more important to continue considering it to be
15781                        // in the background state.
15782                        mayBeTop = true;
15783                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15784                    } else {
15785                        // Special handling for above-top states (persistent
15786                        // processes).  These should not bring the current process
15787                        // into the top state, since they are not on top.  Instead
15788                        // give them the best state after that.
15789                        clientProcState =
15790                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15791                    }
15792                }
15793                if (procState > clientProcState) {
15794                    procState = clientProcState;
15795                }
15796                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15797                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15798                }
15799            }
15800            // If the provider has external (non-framework) process
15801            // dependencies, ensure that its adjustment is at least
15802            // FOREGROUND_APP_ADJ.
15803            if (cpr.hasExternalProcessHandles()) {
15804                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15805                    adj = ProcessList.FOREGROUND_APP_ADJ;
15806                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15807                    app.cached = false;
15808                    app.adjType = "provider";
15809                    app.adjTarget = cpr.name;
15810                }
15811                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15812                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15813                }
15814            }
15815        }
15816
15817        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15818            // A client of one of our services or providers is in the top state.  We
15819            // *may* want to be in the top state, but not if we are already running in
15820            // the background for some other reason.  For the decision here, we are going
15821            // to pick out a few specific states that we want to remain in when a client
15822            // is top (states that tend to be longer-term) and otherwise allow it to go
15823            // to the top state.
15824            switch (procState) {
15825                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15826                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15827                case ActivityManager.PROCESS_STATE_SERVICE:
15828                    // These all are longer-term states, so pull them up to the top
15829                    // of the background states, but not all the way to the top state.
15830                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15831                    break;
15832                default:
15833                    // Otherwise, top is a better choice, so take it.
15834                    procState = ActivityManager.PROCESS_STATE_TOP;
15835                    break;
15836            }
15837        }
15838
15839        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15840            if (app.hasClientActivities) {
15841                // This is a cached process, but with client activities.  Mark it so.
15842                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15843                app.adjType = "cch-client-act";
15844            } else if (app.treatLikeActivity) {
15845                // This is a cached process, but somebody wants us to treat it like it has
15846                // an activity, okay!
15847                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15848                app.adjType = "cch-as-act";
15849            }
15850        }
15851
15852        if (adj == ProcessList.SERVICE_ADJ) {
15853            if (doingAll) {
15854                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15855                mNewNumServiceProcs++;
15856                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15857                if (!app.serviceb) {
15858                    // This service isn't far enough down on the LRU list to
15859                    // normally be a B service, but if we are low on RAM and it
15860                    // is large we want to force it down since we would prefer to
15861                    // keep launcher over it.
15862                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15863                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15864                        app.serviceHighRam = true;
15865                        app.serviceb = true;
15866                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15867                    } else {
15868                        mNewNumAServiceProcs++;
15869                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15870                    }
15871                } else {
15872                    app.serviceHighRam = false;
15873                }
15874            }
15875            if (app.serviceb) {
15876                adj = ProcessList.SERVICE_B_ADJ;
15877            }
15878        }
15879
15880        app.curRawAdj = adj;
15881
15882        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15883        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15884        if (adj > app.maxAdj) {
15885            adj = app.maxAdj;
15886            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15887                schedGroup = Process.THREAD_GROUP_DEFAULT;
15888            }
15889        }
15890
15891        // Do final modification to adj.  Everything we do between here and applying
15892        // the final setAdj must be done in this function, because we will also use
15893        // it when computing the final cached adj later.  Note that we don't need to
15894        // worry about this for max adj above, since max adj will always be used to
15895        // keep it out of the cached vaues.
15896        app.curAdj = app.modifyRawOomAdj(adj);
15897        app.curSchedGroup = schedGroup;
15898        app.curProcState = procState;
15899        app.foregroundActivities = foregroundActivities;
15900
15901        return app.curRawAdj;
15902    }
15903
15904    /**
15905     * Schedule PSS collection of a process.
15906     */
15907    void requestPssLocked(ProcessRecord proc, int procState) {
15908        if (mPendingPssProcesses.contains(proc)) {
15909            return;
15910        }
15911        if (mPendingPssProcesses.size() == 0) {
15912            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15913        }
15914        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15915        proc.pssProcState = procState;
15916        mPendingPssProcesses.add(proc);
15917    }
15918
15919    /**
15920     * Schedule PSS collection of all processes.
15921     */
15922    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15923        if (!always) {
15924            if (now < (mLastFullPssTime +
15925                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15926                return;
15927            }
15928        }
15929        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15930        mLastFullPssTime = now;
15931        mFullPssPending = true;
15932        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15933        mPendingPssProcesses.clear();
15934        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15935            ProcessRecord app = mLruProcesses.get(i);
15936            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15937                app.pssProcState = app.setProcState;
15938                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15939                        isSleeping(), now);
15940                mPendingPssProcesses.add(app);
15941            }
15942        }
15943        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15944    }
15945
15946    /**
15947     * Ask a given process to GC right now.
15948     */
15949    final void performAppGcLocked(ProcessRecord app) {
15950        try {
15951            app.lastRequestedGc = SystemClock.uptimeMillis();
15952            if (app.thread != null) {
15953                if (app.reportLowMemory) {
15954                    app.reportLowMemory = false;
15955                    app.thread.scheduleLowMemory();
15956                } else {
15957                    app.thread.processInBackground();
15958                }
15959            }
15960        } catch (Exception e) {
15961            // whatever.
15962        }
15963    }
15964
15965    /**
15966     * Returns true if things are idle enough to perform GCs.
15967     */
15968    private final boolean canGcNowLocked() {
15969        boolean processingBroadcasts = false;
15970        for (BroadcastQueue q : mBroadcastQueues) {
15971            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15972                processingBroadcasts = true;
15973            }
15974        }
15975        return !processingBroadcasts
15976                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15977    }
15978
15979    /**
15980     * Perform GCs on all processes that are waiting for it, but only
15981     * if things are idle.
15982     */
15983    final void performAppGcsLocked() {
15984        final int N = mProcessesToGc.size();
15985        if (N <= 0) {
15986            return;
15987        }
15988        if (canGcNowLocked()) {
15989            while (mProcessesToGc.size() > 0) {
15990                ProcessRecord proc = mProcessesToGc.remove(0);
15991                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15992                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15993                            <= SystemClock.uptimeMillis()) {
15994                        // To avoid spamming the system, we will GC processes one
15995                        // at a time, waiting a few seconds between each.
15996                        performAppGcLocked(proc);
15997                        scheduleAppGcsLocked();
15998                        return;
15999                    } else {
16000                        // It hasn't been long enough since we last GCed this
16001                        // process...  put it in the list to wait for its time.
16002                        addProcessToGcListLocked(proc);
16003                        break;
16004                    }
16005                }
16006            }
16007
16008            scheduleAppGcsLocked();
16009        }
16010    }
16011
16012    /**
16013     * If all looks good, perform GCs on all processes waiting for them.
16014     */
16015    final void performAppGcsIfAppropriateLocked() {
16016        if (canGcNowLocked()) {
16017            performAppGcsLocked();
16018            return;
16019        }
16020        // Still not idle, wait some more.
16021        scheduleAppGcsLocked();
16022    }
16023
16024    /**
16025     * Schedule the execution of all pending app GCs.
16026     */
16027    final void scheduleAppGcsLocked() {
16028        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16029
16030        if (mProcessesToGc.size() > 0) {
16031            // Schedule a GC for the time to the next process.
16032            ProcessRecord proc = mProcessesToGc.get(0);
16033            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16034
16035            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16036            long now = SystemClock.uptimeMillis();
16037            if (when < (now+GC_TIMEOUT)) {
16038                when = now + GC_TIMEOUT;
16039            }
16040            mHandler.sendMessageAtTime(msg, when);
16041        }
16042    }
16043
16044    /**
16045     * Add a process to the array of processes waiting to be GCed.  Keeps the
16046     * list in sorted order by the last GC time.  The process can't already be
16047     * on the list.
16048     */
16049    final void addProcessToGcListLocked(ProcessRecord proc) {
16050        boolean added = false;
16051        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16052            if (mProcessesToGc.get(i).lastRequestedGc <
16053                    proc.lastRequestedGc) {
16054                added = true;
16055                mProcessesToGc.add(i+1, proc);
16056                break;
16057            }
16058        }
16059        if (!added) {
16060            mProcessesToGc.add(0, proc);
16061        }
16062    }
16063
16064    /**
16065     * Set up to ask a process to GC itself.  This will either do it
16066     * immediately, or put it on the list of processes to gc the next
16067     * time things are idle.
16068     */
16069    final void scheduleAppGcLocked(ProcessRecord app) {
16070        long now = SystemClock.uptimeMillis();
16071        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16072            return;
16073        }
16074        if (!mProcessesToGc.contains(app)) {
16075            addProcessToGcListLocked(app);
16076            scheduleAppGcsLocked();
16077        }
16078    }
16079
16080    final void checkExcessivePowerUsageLocked(boolean doKills) {
16081        updateCpuStatsNow();
16082
16083        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16084        boolean doWakeKills = doKills;
16085        boolean doCpuKills = doKills;
16086        if (mLastPowerCheckRealtime == 0) {
16087            doWakeKills = false;
16088        }
16089        if (mLastPowerCheckUptime == 0) {
16090            doCpuKills = false;
16091        }
16092        if (stats.isScreenOn()) {
16093            doWakeKills = false;
16094        }
16095        final long curRealtime = SystemClock.elapsedRealtime();
16096        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16097        final long curUptime = SystemClock.uptimeMillis();
16098        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16099        mLastPowerCheckRealtime = curRealtime;
16100        mLastPowerCheckUptime = curUptime;
16101        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16102            doWakeKills = false;
16103        }
16104        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16105            doCpuKills = false;
16106        }
16107        int i = mLruProcesses.size();
16108        while (i > 0) {
16109            i--;
16110            ProcessRecord app = mLruProcesses.get(i);
16111            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16112                long wtime;
16113                synchronized (stats) {
16114                    wtime = stats.getProcessWakeTime(app.info.uid,
16115                            app.pid, curRealtime);
16116                }
16117                long wtimeUsed = wtime - app.lastWakeTime;
16118                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16119                if (DEBUG_POWER) {
16120                    StringBuilder sb = new StringBuilder(128);
16121                    sb.append("Wake for ");
16122                    app.toShortString(sb);
16123                    sb.append(": over ");
16124                    TimeUtils.formatDuration(realtimeSince, sb);
16125                    sb.append(" used ");
16126                    TimeUtils.formatDuration(wtimeUsed, sb);
16127                    sb.append(" (");
16128                    sb.append((wtimeUsed*100)/realtimeSince);
16129                    sb.append("%)");
16130                    Slog.i(TAG, sb.toString());
16131                    sb.setLength(0);
16132                    sb.append("CPU for ");
16133                    app.toShortString(sb);
16134                    sb.append(": over ");
16135                    TimeUtils.formatDuration(uptimeSince, sb);
16136                    sb.append(" used ");
16137                    TimeUtils.formatDuration(cputimeUsed, sb);
16138                    sb.append(" (");
16139                    sb.append((cputimeUsed*100)/uptimeSince);
16140                    sb.append("%)");
16141                    Slog.i(TAG, sb.toString());
16142                }
16143                // If a process has held a wake lock for more
16144                // than 50% of the time during this period,
16145                // that sounds bad.  Kill!
16146                if (doWakeKills && realtimeSince > 0
16147                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16148                    synchronized (stats) {
16149                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16150                                realtimeSince, wtimeUsed);
16151                    }
16152                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16153                            + " during " + realtimeSince);
16154                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16155                } else if (doCpuKills && uptimeSince > 0
16156                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16157                    synchronized (stats) {
16158                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16159                                uptimeSince, cputimeUsed);
16160                    }
16161                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16162                            + " during " + uptimeSince);
16163                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16164                } else {
16165                    app.lastWakeTime = wtime;
16166                    app.lastCpuTime = app.curCpuTime;
16167                }
16168            }
16169        }
16170    }
16171
16172    private final boolean applyOomAdjLocked(ProcessRecord app,
16173            ProcessRecord TOP_APP, boolean doingAll, long now) {
16174        boolean success = true;
16175
16176        if (app.curRawAdj != app.setRawAdj) {
16177            app.setRawAdj = app.curRawAdj;
16178        }
16179
16180        int changes = 0;
16181
16182        if (app.curAdj != app.setAdj) {
16183            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16184            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16185                TAG, "Set " + app.pid + " " + app.processName +
16186                " adj " + app.curAdj + ": " + app.adjType);
16187            app.setAdj = app.curAdj;
16188        }
16189
16190        if (app.setSchedGroup != app.curSchedGroup) {
16191            app.setSchedGroup = app.curSchedGroup;
16192            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16193                    "Setting process group of " + app.processName
16194                    + " to " + app.curSchedGroup);
16195            if (app.waitingToKill != null &&
16196                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16197                killUnneededProcessLocked(app, app.waitingToKill);
16198                success = false;
16199            } else {
16200                if (true) {
16201                    long oldId = Binder.clearCallingIdentity();
16202                    try {
16203                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16204                    } catch (Exception e) {
16205                        Slog.w(TAG, "Failed setting process group of " + app.pid
16206                                + " to " + app.curSchedGroup);
16207                        e.printStackTrace();
16208                    } finally {
16209                        Binder.restoreCallingIdentity(oldId);
16210                    }
16211                } else {
16212                    if (app.thread != null) {
16213                        try {
16214                            app.thread.setSchedulingGroup(app.curSchedGroup);
16215                        } catch (RemoteException e) {
16216                        }
16217                    }
16218                }
16219                Process.setSwappiness(app.pid,
16220                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16221            }
16222        }
16223        if (app.repForegroundActivities != app.foregroundActivities) {
16224            app.repForegroundActivities = app.foregroundActivities;
16225            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16226        }
16227        if (app.repProcState != app.curProcState) {
16228            app.repProcState = app.curProcState;
16229            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16230            if (app.thread != null) {
16231                try {
16232                    if (false) {
16233                        //RuntimeException h = new RuntimeException("here");
16234                        Slog.i(TAG, "Sending new process state " + app.repProcState
16235                                + " to " + app /*, h*/);
16236                    }
16237                    app.thread.setProcessState(app.repProcState);
16238                } catch (RemoteException e) {
16239                }
16240            }
16241        }
16242        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16243                app.setProcState)) {
16244            app.lastStateTime = now;
16245            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16246                    isSleeping(), now);
16247            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16248                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16249                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16250                    + (app.nextPssTime-now) + ": " + app);
16251        } else {
16252            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16253                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16254                requestPssLocked(app, app.setProcState);
16255                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16256                        isSleeping(), now);
16257            } else if (false && DEBUG_PSS) {
16258                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16259            }
16260        }
16261        if (app.setProcState != app.curProcState) {
16262            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16263                    "Proc state change of " + app.processName
16264                    + " to " + app.curProcState);
16265            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16266            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16267            if (setImportant && !curImportant) {
16268                // This app is no longer something we consider important enough to allow to
16269                // use arbitrary amounts of battery power.  Note
16270                // its current wake lock time to later know to kill it if
16271                // it is not behaving well.
16272                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16273                synchronized (stats) {
16274                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16275                            app.pid, SystemClock.elapsedRealtime());
16276                }
16277                app.lastCpuTime = app.curCpuTime;
16278
16279            }
16280            app.setProcState = app.curProcState;
16281            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16282                app.notCachedSinceIdle = false;
16283            }
16284            if (!doingAll) {
16285                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16286            } else {
16287                app.procStateChanged = true;
16288            }
16289        }
16290
16291        if (changes != 0) {
16292            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16293            int i = mPendingProcessChanges.size()-1;
16294            ProcessChangeItem item = null;
16295            while (i >= 0) {
16296                item = mPendingProcessChanges.get(i);
16297                if (item.pid == app.pid) {
16298                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16299                    break;
16300                }
16301                i--;
16302            }
16303            if (i < 0) {
16304                // No existing item in pending changes; need a new one.
16305                final int NA = mAvailProcessChanges.size();
16306                if (NA > 0) {
16307                    item = mAvailProcessChanges.remove(NA-1);
16308                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16309                } else {
16310                    item = new ProcessChangeItem();
16311                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16312                }
16313                item.changes = 0;
16314                item.pid = app.pid;
16315                item.uid = app.info.uid;
16316                if (mPendingProcessChanges.size() == 0) {
16317                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16318                            "*** Enqueueing dispatch processes changed!");
16319                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16320                }
16321                mPendingProcessChanges.add(item);
16322            }
16323            item.changes |= changes;
16324            item.processState = app.repProcState;
16325            item.foregroundActivities = app.repForegroundActivities;
16326            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16327                    + Integer.toHexString(System.identityHashCode(item))
16328                    + " " + app.toShortString() + ": changes=" + item.changes
16329                    + " procState=" + item.processState
16330                    + " foreground=" + item.foregroundActivities
16331                    + " type=" + app.adjType + " source=" + app.adjSource
16332                    + " target=" + app.adjTarget);
16333        }
16334
16335        return success;
16336    }
16337
16338    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16339        if (proc.thread != null) {
16340            if (proc.baseProcessTracker != null) {
16341                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16342            }
16343            if (proc.repProcState >= 0) {
16344                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16345                        proc.repProcState);
16346            }
16347        }
16348    }
16349
16350    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16351            ProcessRecord TOP_APP, boolean doingAll, long now) {
16352        if (app.thread == null) {
16353            return false;
16354        }
16355
16356        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16357
16358        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16359    }
16360
16361    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16362            boolean oomAdj) {
16363        if (isForeground != proc.foregroundServices) {
16364            proc.foregroundServices = isForeground;
16365            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16366                    proc.info.uid);
16367            if (isForeground) {
16368                if (curProcs == null) {
16369                    curProcs = new ArrayList<ProcessRecord>();
16370                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16371                }
16372                if (!curProcs.contains(proc)) {
16373                    curProcs.add(proc);
16374                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16375                            proc.info.packageName, proc.info.uid);
16376                }
16377            } else {
16378                if (curProcs != null) {
16379                    if (curProcs.remove(proc)) {
16380                        mBatteryStatsService.noteEvent(
16381                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16382                                proc.info.packageName, proc.info.uid);
16383                        if (curProcs.size() <= 0) {
16384                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16385                        }
16386                    }
16387                }
16388            }
16389            if (oomAdj) {
16390                updateOomAdjLocked();
16391            }
16392        }
16393    }
16394
16395    private final ActivityRecord resumedAppLocked() {
16396        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16397        String pkg;
16398        int uid;
16399        if (act != null) {
16400            pkg = act.packageName;
16401            uid = act.info.applicationInfo.uid;
16402        } else {
16403            pkg = null;
16404            uid = -1;
16405        }
16406        // Has the UID or resumed package name changed?
16407        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16408                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16409            if (mCurResumedPackage != null) {
16410                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16411                        mCurResumedPackage, mCurResumedUid);
16412            }
16413            mCurResumedPackage = pkg;
16414            mCurResumedUid = uid;
16415            if (mCurResumedPackage != null) {
16416                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16417                        mCurResumedPackage, mCurResumedUid);
16418            }
16419        }
16420        return act;
16421    }
16422
16423    final boolean updateOomAdjLocked(ProcessRecord app) {
16424        final ActivityRecord TOP_ACT = resumedAppLocked();
16425        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16426        final boolean wasCached = app.cached;
16427
16428        mAdjSeq++;
16429
16430        // This is the desired cached adjusment we want to tell it to use.
16431        // If our app is currently cached, we know it, and that is it.  Otherwise,
16432        // we don't know it yet, and it needs to now be cached we will then
16433        // need to do a complete oom adj.
16434        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16435                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16436        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16437                SystemClock.uptimeMillis());
16438        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16439            // Changed to/from cached state, so apps after it in the LRU
16440            // list may also be changed.
16441            updateOomAdjLocked();
16442        }
16443        return success;
16444    }
16445
16446    final void updateOomAdjLocked() {
16447        final ActivityRecord TOP_ACT = resumedAppLocked();
16448        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16449        final long now = SystemClock.uptimeMillis();
16450        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16451        final int N = mLruProcesses.size();
16452
16453        if (false) {
16454            RuntimeException e = new RuntimeException();
16455            e.fillInStackTrace();
16456            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16457        }
16458
16459        mAdjSeq++;
16460        mNewNumServiceProcs = 0;
16461        mNewNumAServiceProcs = 0;
16462
16463        final int emptyProcessLimit;
16464        final int cachedProcessLimit;
16465        if (mProcessLimit <= 0) {
16466            emptyProcessLimit = cachedProcessLimit = 0;
16467        } else if (mProcessLimit == 1) {
16468            emptyProcessLimit = 1;
16469            cachedProcessLimit = 0;
16470        } else {
16471            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16472            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16473        }
16474
16475        // Let's determine how many processes we have running vs.
16476        // how many slots we have for background processes; we may want
16477        // to put multiple processes in a slot of there are enough of
16478        // them.
16479        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16480                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16481        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16482        if (numEmptyProcs > cachedProcessLimit) {
16483            // If there are more empty processes than our limit on cached
16484            // processes, then use the cached process limit for the factor.
16485            // This ensures that the really old empty processes get pushed
16486            // down to the bottom, so if we are running low on memory we will
16487            // have a better chance at keeping around more cached processes
16488            // instead of a gazillion empty processes.
16489            numEmptyProcs = cachedProcessLimit;
16490        }
16491        int emptyFactor = numEmptyProcs/numSlots;
16492        if (emptyFactor < 1) emptyFactor = 1;
16493        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16494        if (cachedFactor < 1) cachedFactor = 1;
16495        int stepCached = 0;
16496        int stepEmpty = 0;
16497        int numCached = 0;
16498        int numEmpty = 0;
16499        int numTrimming = 0;
16500
16501        mNumNonCachedProcs = 0;
16502        mNumCachedHiddenProcs = 0;
16503
16504        // First update the OOM adjustment for each of the
16505        // application processes based on their current state.
16506        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16507        int nextCachedAdj = curCachedAdj+1;
16508        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16509        int nextEmptyAdj = curEmptyAdj+2;
16510        for (int i=N-1; i>=0; i--) {
16511            ProcessRecord app = mLruProcesses.get(i);
16512            if (!app.killedByAm && app.thread != null) {
16513                app.procStateChanged = false;
16514                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16515
16516                // If we haven't yet assigned the final cached adj
16517                // to the process, do that now.
16518                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16519                    switch (app.curProcState) {
16520                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16521                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16522                            // This process is a cached process holding activities...
16523                            // assign it the next cached value for that type, and then
16524                            // step that cached level.
16525                            app.curRawAdj = curCachedAdj;
16526                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16527                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16528                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16529                                    + ")");
16530                            if (curCachedAdj != nextCachedAdj) {
16531                                stepCached++;
16532                                if (stepCached >= cachedFactor) {
16533                                    stepCached = 0;
16534                                    curCachedAdj = nextCachedAdj;
16535                                    nextCachedAdj += 2;
16536                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16537                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16538                                    }
16539                                }
16540                            }
16541                            break;
16542                        default:
16543                            // For everything else, assign next empty cached process
16544                            // level and bump that up.  Note that this means that
16545                            // long-running services that have dropped down to the
16546                            // cached level will be treated as empty (since their process
16547                            // state is still as a service), which is what we want.
16548                            app.curRawAdj = curEmptyAdj;
16549                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16550                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16551                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16552                                    + ")");
16553                            if (curEmptyAdj != nextEmptyAdj) {
16554                                stepEmpty++;
16555                                if (stepEmpty >= emptyFactor) {
16556                                    stepEmpty = 0;
16557                                    curEmptyAdj = nextEmptyAdj;
16558                                    nextEmptyAdj += 2;
16559                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16560                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16561                                    }
16562                                }
16563                            }
16564                            break;
16565                    }
16566                }
16567
16568                applyOomAdjLocked(app, TOP_APP, true, now);
16569
16570                // Count the number of process types.
16571                switch (app.curProcState) {
16572                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16573                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16574                        mNumCachedHiddenProcs++;
16575                        numCached++;
16576                        if (numCached > cachedProcessLimit) {
16577                            killUnneededProcessLocked(app, "cached #" + numCached);
16578                        }
16579                        break;
16580                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16581                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16582                                && app.lastActivityTime < oldTime) {
16583                            killUnneededProcessLocked(app, "empty for "
16584                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16585                                    / 1000) + "s");
16586                        } else {
16587                            numEmpty++;
16588                            if (numEmpty > emptyProcessLimit) {
16589                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16590                            }
16591                        }
16592                        break;
16593                    default:
16594                        mNumNonCachedProcs++;
16595                        break;
16596                }
16597
16598                if (app.isolated && app.services.size() <= 0) {
16599                    // If this is an isolated process, and there are no
16600                    // services running in it, then the process is no longer
16601                    // needed.  We agressively kill these because we can by
16602                    // definition not re-use the same process again, and it is
16603                    // good to avoid having whatever code was running in them
16604                    // left sitting around after no longer needed.
16605                    killUnneededProcessLocked(app, "isolated not needed");
16606                }
16607
16608                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16609                        && !app.killedByAm) {
16610                    numTrimming++;
16611                }
16612            }
16613        }
16614
16615        mNumServiceProcs = mNewNumServiceProcs;
16616
16617        // Now determine the memory trimming level of background processes.
16618        // Unfortunately we need to start at the back of the list to do this
16619        // properly.  We only do this if the number of background apps we
16620        // are managing to keep around is less than half the maximum we desire;
16621        // if we are keeping a good number around, we'll let them use whatever
16622        // memory they want.
16623        final int numCachedAndEmpty = numCached + numEmpty;
16624        int memFactor;
16625        if (numCached <= ProcessList.TRIM_CACHED_APPS
16626                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16627            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16628                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16629            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16630                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16631            } else {
16632                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16633            }
16634        } else {
16635            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16636        }
16637        // We always allow the memory level to go up (better).  We only allow it to go
16638        // down if we are in a state where that is allowed, *and* the total number of processes
16639        // has gone down since last time.
16640        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16641                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16642                + " last=" + mLastNumProcesses);
16643        if (memFactor > mLastMemoryLevel) {
16644            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16645                memFactor = mLastMemoryLevel;
16646                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16647            }
16648        }
16649        mLastMemoryLevel = memFactor;
16650        mLastNumProcesses = mLruProcesses.size();
16651        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16652        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16653        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16654            if (mLowRamStartTime == 0) {
16655                mLowRamStartTime = now;
16656            }
16657            int step = 0;
16658            int fgTrimLevel;
16659            switch (memFactor) {
16660                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16661                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16662                    break;
16663                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16664                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16665                    break;
16666                default:
16667                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16668                    break;
16669            }
16670            int factor = numTrimming/3;
16671            int minFactor = 2;
16672            if (mHomeProcess != null) minFactor++;
16673            if (mPreviousProcess != null) minFactor++;
16674            if (factor < minFactor) factor = minFactor;
16675            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16676            for (int i=N-1; i>=0; i--) {
16677                ProcessRecord app = mLruProcesses.get(i);
16678                if (allChanged || app.procStateChanged) {
16679                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16680                    app.procStateChanged = false;
16681                }
16682                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16683                        && !app.killedByAm) {
16684                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16685                        try {
16686                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16687                                    "Trimming memory of " + app.processName
16688                                    + " to " + curLevel);
16689                            app.thread.scheduleTrimMemory(curLevel);
16690                        } catch (RemoteException e) {
16691                        }
16692                        if (false) {
16693                            // For now we won't do this; our memory trimming seems
16694                            // to be good enough at this point that destroying
16695                            // activities causes more harm than good.
16696                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16697                                    && app != mHomeProcess && app != mPreviousProcess) {
16698                                // Need to do this on its own message because the stack may not
16699                                // be in a consistent state at this point.
16700                                // For these apps we will also finish their activities
16701                                // to help them free memory.
16702                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16703                            }
16704                        }
16705                    }
16706                    app.trimMemoryLevel = curLevel;
16707                    step++;
16708                    if (step >= factor) {
16709                        step = 0;
16710                        switch (curLevel) {
16711                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16712                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16713                                break;
16714                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16715                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16716                                break;
16717                        }
16718                    }
16719                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16720                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16721                            && app.thread != null) {
16722                        try {
16723                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16724                                    "Trimming memory of heavy-weight " + app.processName
16725                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16726                            app.thread.scheduleTrimMemory(
16727                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16728                        } catch (RemoteException e) {
16729                        }
16730                    }
16731                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16732                } else {
16733                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16734                            || app.systemNoUi) && app.pendingUiClean) {
16735                        // If this application is now in the background and it
16736                        // had done UI, then give it the special trim level to
16737                        // have it free UI resources.
16738                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16739                        if (app.trimMemoryLevel < level && app.thread != null) {
16740                            try {
16741                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16742                                        "Trimming memory of bg-ui " + app.processName
16743                                        + " to " + level);
16744                                app.thread.scheduleTrimMemory(level);
16745                            } catch (RemoteException e) {
16746                            }
16747                        }
16748                        app.pendingUiClean = false;
16749                    }
16750                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16751                        try {
16752                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16753                                    "Trimming memory of fg " + app.processName
16754                                    + " to " + fgTrimLevel);
16755                            app.thread.scheduleTrimMemory(fgTrimLevel);
16756                        } catch (RemoteException e) {
16757                        }
16758                    }
16759                    app.trimMemoryLevel = fgTrimLevel;
16760                }
16761            }
16762        } else {
16763            if (mLowRamStartTime != 0) {
16764                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16765                mLowRamStartTime = 0;
16766            }
16767            for (int i=N-1; i>=0; i--) {
16768                ProcessRecord app = mLruProcesses.get(i);
16769                if (allChanged || app.procStateChanged) {
16770                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16771                    app.procStateChanged = false;
16772                }
16773                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16774                        || app.systemNoUi) && app.pendingUiClean) {
16775                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16776                            && app.thread != null) {
16777                        try {
16778                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16779                                    "Trimming memory of ui hidden " + app.processName
16780                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16781                            app.thread.scheduleTrimMemory(
16782                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16783                        } catch (RemoteException e) {
16784                        }
16785                    }
16786                    app.pendingUiClean = false;
16787                }
16788                app.trimMemoryLevel = 0;
16789            }
16790        }
16791
16792        if (mAlwaysFinishActivities) {
16793            // Need to do this on its own message because the stack may not
16794            // be in a consistent state at this point.
16795            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16796        }
16797
16798        if (allChanged) {
16799            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16800        }
16801
16802        if (mProcessStats.shouldWriteNowLocked(now)) {
16803            mHandler.post(new Runnable() {
16804                @Override public void run() {
16805                    synchronized (ActivityManagerService.this) {
16806                        mProcessStats.writeStateAsyncLocked();
16807                    }
16808                }
16809            });
16810        }
16811
16812        if (DEBUG_OOM_ADJ) {
16813            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16814        }
16815    }
16816
16817    final void trimApplications() {
16818        synchronized (this) {
16819            int i;
16820
16821            // First remove any unused application processes whose package
16822            // has been removed.
16823            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16824                final ProcessRecord app = mRemovedProcesses.get(i);
16825                if (app.activities.size() == 0
16826                        && app.curReceiver == null && app.services.size() == 0) {
16827                    Slog.i(
16828                        TAG, "Exiting empty application process "
16829                        + app.processName + " ("
16830                        + (app.thread != null ? app.thread.asBinder() : null)
16831                        + ")\n");
16832                    if (app.pid > 0 && app.pid != MY_PID) {
16833                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16834                                app.processName, app.setAdj, "empty");
16835                        app.killedByAm = true;
16836                        Process.killProcessQuiet(app.pid);
16837                        Process.killProcessGroup(app.info.uid, app.pid);
16838                    } else {
16839                        try {
16840                            app.thread.scheduleExit();
16841                        } catch (Exception e) {
16842                            // Ignore exceptions.
16843                        }
16844                    }
16845                    cleanUpApplicationRecordLocked(app, false, true, -1);
16846                    mRemovedProcesses.remove(i);
16847
16848                    if (app.persistent) {
16849                        addAppLocked(app.info, false, null /* ABI override */);
16850                    }
16851                }
16852            }
16853
16854            // Now update the oom adj for all processes.
16855            updateOomAdjLocked();
16856        }
16857    }
16858
16859    /** This method sends the specified signal to each of the persistent apps */
16860    public void signalPersistentProcesses(int sig) throws RemoteException {
16861        if (sig != Process.SIGNAL_USR1) {
16862            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16863        }
16864
16865        synchronized (this) {
16866            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16867                    != PackageManager.PERMISSION_GRANTED) {
16868                throw new SecurityException("Requires permission "
16869                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16870            }
16871
16872            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16873                ProcessRecord r = mLruProcesses.get(i);
16874                if (r.thread != null && r.persistent) {
16875                    Process.sendSignal(r.pid, sig);
16876                }
16877            }
16878        }
16879    }
16880
16881    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16882        if (proc == null || proc == mProfileProc) {
16883            proc = mProfileProc;
16884            path = mProfileFile;
16885            profileType = mProfileType;
16886            clearProfilerLocked();
16887        }
16888        if (proc == null) {
16889            return;
16890        }
16891        try {
16892            proc.thread.profilerControl(false, path, null, profileType);
16893        } catch (RemoteException e) {
16894            throw new IllegalStateException("Process disappeared");
16895        }
16896    }
16897
16898    private void clearProfilerLocked() {
16899        if (mProfileFd != null) {
16900            try {
16901                mProfileFd.close();
16902            } catch (IOException e) {
16903            }
16904        }
16905        mProfileApp = null;
16906        mProfileProc = null;
16907        mProfileFile = null;
16908        mProfileType = 0;
16909        mAutoStopProfiler = false;
16910    }
16911
16912    public boolean profileControl(String process, int userId, boolean start,
16913            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16914
16915        try {
16916            synchronized (this) {
16917                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16918                // its own permission.
16919                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16920                        != PackageManager.PERMISSION_GRANTED) {
16921                    throw new SecurityException("Requires permission "
16922                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16923                }
16924
16925                if (start && fd == null) {
16926                    throw new IllegalArgumentException("null fd");
16927                }
16928
16929                ProcessRecord proc = null;
16930                if (process != null) {
16931                    proc = findProcessLocked(process, userId, "profileControl");
16932                }
16933
16934                if (start && (proc == null || proc.thread == null)) {
16935                    throw new IllegalArgumentException("Unknown process: " + process);
16936                }
16937
16938                if (start) {
16939                    stopProfilerLocked(null, null, 0);
16940                    setProfileApp(proc.info, proc.processName, path, fd, false);
16941                    mProfileProc = proc;
16942                    mProfileType = profileType;
16943                    try {
16944                        fd = fd.dup();
16945                    } catch (IOException e) {
16946                        fd = null;
16947                    }
16948                    proc.thread.profilerControl(start, path, fd, profileType);
16949                    fd = null;
16950                    mProfileFd = null;
16951                } else {
16952                    stopProfilerLocked(proc, path, profileType);
16953                    if (fd != null) {
16954                        try {
16955                            fd.close();
16956                        } catch (IOException e) {
16957                        }
16958                    }
16959                }
16960
16961                return true;
16962            }
16963        } catch (RemoteException e) {
16964            throw new IllegalStateException("Process disappeared");
16965        } finally {
16966            if (fd != null) {
16967                try {
16968                    fd.close();
16969                } catch (IOException e) {
16970                }
16971            }
16972        }
16973    }
16974
16975    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16976        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16977                userId, true, ALLOW_FULL_ONLY, callName, null);
16978        ProcessRecord proc = null;
16979        try {
16980            int pid = Integer.parseInt(process);
16981            synchronized (mPidsSelfLocked) {
16982                proc = mPidsSelfLocked.get(pid);
16983            }
16984        } catch (NumberFormatException e) {
16985        }
16986
16987        if (proc == null) {
16988            ArrayMap<String, SparseArray<ProcessRecord>> all
16989                    = mProcessNames.getMap();
16990            SparseArray<ProcessRecord> procs = all.get(process);
16991            if (procs != null && procs.size() > 0) {
16992                proc = procs.valueAt(0);
16993                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16994                    for (int i=1; i<procs.size(); i++) {
16995                        ProcessRecord thisProc = procs.valueAt(i);
16996                        if (thisProc.userId == userId) {
16997                            proc = thisProc;
16998                            break;
16999                        }
17000                    }
17001                }
17002            }
17003        }
17004
17005        return proc;
17006    }
17007
17008    public boolean dumpHeap(String process, int userId, boolean managed,
17009            String path, ParcelFileDescriptor fd) throws RemoteException {
17010
17011        try {
17012            synchronized (this) {
17013                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17014                // its own permission (same as profileControl).
17015                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17016                        != PackageManager.PERMISSION_GRANTED) {
17017                    throw new SecurityException("Requires permission "
17018                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17019                }
17020
17021                if (fd == null) {
17022                    throw new IllegalArgumentException("null fd");
17023                }
17024
17025                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17026                if (proc == null || proc.thread == null) {
17027                    throw new IllegalArgumentException("Unknown process: " + process);
17028                }
17029
17030                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17031                if (!isDebuggable) {
17032                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17033                        throw new SecurityException("Process not debuggable: " + proc);
17034                    }
17035                }
17036
17037                proc.thread.dumpHeap(managed, path, fd);
17038                fd = null;
17039                return true;
17040            }
17041        } catch (RemoteException e) {
17042            throw new IllegalStateException("Process disappeared");
17043        } finally {
17044            if (fd != null) {
17045                try {
17046                    fd.close();
17047                } catch (IOException e) {
17048                }
17049            }
17050        }
17051    }
17052
17053    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17054    public void monitor() {
17055        synchronized (this) { }
17056    }
17057
17058    void onCoreSettingsChange(Bundle settings) {
17059        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17060            ProcessRecord processRecord = mLruProcesses.get(i);
17061            try {
17062                if (processRecord.thread != null) {
17063                    processRecord.thread.setCoreSettings(settings);
17064                }
17065            } catch (RemoteException re) {
17066                /* ignore */
17067            }
17068        }
17069    }
17070
17071    // Multi-user methods
17072
17073    /**
17074     * Start user, if its not already running, but don't bring it to foreground.
17075     */
17076    @Override
17077    public boolean startUserInBackground(final int userId) {
17078        return startUser(userId, /* foreground */ false);
17079    }
17080
17081    /**
17082     * Refreshes the list of users related to the current user when either a
17083     * user switch happens or when a new related user is started in the
17084     * background.
17085     */
17086    private void updateCurrentProfileIdsLocked() {
17087        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17088                mCurrentUserId, false /* enabledOnly */);
17089        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17090        for (int i = 0; i < currentProfileIds.length; i++) {
17091            currentProfileIds[i] = profiles.get(i).id;
17092        }
17093        mCurrentProfileIds = currentProfileIds;
17094
17095        synchronized (mUserProfileGroupIdsSelfLocked) {
17096            mUserProfileGroupIdsSelfLocked.clear();
17097            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17098            for (int i = 0; i < users.size(); i++) {
17099                UserInfo user = users.get(i);
17100                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17101                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17102                }
17103            }
17104        }
17105    }
17106
17107    private Set getProfileIdsLocked(int userId) {
17108        Set userIds = new HashSet<Integer>();
17109        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17110                userId, false /* enabledOnly */);
17111        for (UserInfo user : profiles) {
17112            userIds.add(Integer.valueOf(user.id));
17113        }
17114        return userIds;
17115    }
17116
17117    @Override
17118    public boolean switchUser(final int userId) {
17119        return startUser(userId, /* foregound */ true);
17120    }
17121
17122    private boolean startUser(final int userId, boolean foreground) {
17123        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17124                != PackageManager.PERMISSION_GRANTED) {
17125            String msg = "Permission Denial: switchUser() from pid="
17126                    + Binder.getCallingPid()
17127                    + ", uid=" + Binder.getCallingUid()
17128                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17129            Slog.w(TAG, msg);
17130            throw new SecurityException(msg);
17131        }
17132
17133        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17134
17135        final long ident = Binder.clearCallingIdentity();
17136        try {
17137            synchronized (this) {
17138                final int oldUserId = mCurrentUserId;
17139                if (oldUserId == userId) {
17140                    return true;
17141                }
17142
17143                mStackSupervisor.setLockTaskModeLocked(null, false);
17144
17145                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17146                if (userInfo == null) {
17147                    Slog.w(TAG, "No user info for user #" + userId);
17148                    return false;
17149                }
17150
17151                if (foreground) {
17152                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17153                            R.anim.screen_user_enter);
17154                }
17155
17156                boolean needStart = false;
17157
17158                // If the user we are switching to is not currently started, then
17159                // we need to start it now.
17160                if (mStartedUsers.get(userId) == null) {
17161                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17162                    updateStartedUserArrayLocked();
17163                    needStart = true;
17164                }
17165
17166                final Integer userIdInt = Integer.valueOf(userId);
17167                mUserLru.remove(userIdInt);
17168                mUserLru.add(userIdInt);
17169
17170                if (foreground) {
17171                    mCurrentUserId = userId;
17172                    updateCurrentProfileIdsLocked();
17173                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17174                    // Once the internal notion of the active user has switched, we lock the device
17175                    // with the option to show the user switcher on the keyguard.
17176                    mWindowManager.lockNow(null);
17177                } else {
17178                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17179                    updateCurrentProfileIdsLocked();
17180                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17181                    mUserLru.remove(currentUserIdInt);
17182                    mUserLru.add(currentUserIdInt);
17183                }
17184
17185                final UserStartedState uss = mStartedUsers.get(userId);
17186
17187                // Make sure user is in the started state.  If it is currently
17188                // stopping, we need to knock that off.
17189                if (uss.mState == UserStartedState.STATE_STOPPING) {
17190                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17191                    // so we can just fairly silently bring the user back from
17192                    // the almost-dead.
17193                    uss.mState = UserStartedState.STATE_RUNNING;
17194                    updateStartedUserArrayLocked();
17195                    needStart = true;
17196                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17197                    // This means ACTION_SHUTDOWN has been sent, so we will
17198                    // need to treat this as a new boot of the user.
17199                    uss.mState = UserStartedState.STATE_BOOTING;
17200                    updateStartedUserArrayLocked();
17201                    needStart = true;
17202                }
17203
17204                if (uss.mState == UserStartedState.STATE_BOOTING) {
17205                    // Booting up a new user, need to tell system services about it.
17206                    // Note that this is on the same handler as scheduling of broadcasts,
17207                    // which is important because it needs to go first.
17208                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
17209                }
17210
17211                if (foreground) {
17212                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17213                            oldUserId));
17214                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17215                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17216                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17217                            oldUserId, userId, uss));
17218                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17219                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17220                }
17221
17222                if (needStart) {
17223                    // Send USER_STARTED broadcast
17224                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17225                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17226                            | Intent.FLAG_RECEIVER_FOREGROUND);
17227                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17228                    broadcastIntentLocked(null, null, intent,
17229                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17230                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17231                }
17232
17233                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17234                    if (userId != UserHandle.USER_OWNER) {
17235                        // Send PRE_BOOT_COMPLETED broadcasts for this new user
17236                        final ArrayList<ComponentName> doneReceivers
17237                                = new ArrayList<ComponentName>();
17238                        deliverPreBootCompleted(null, doneReceivers, userId);
17239
17240                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17241                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17242                        broadcastIntentLocked(null, null, intent, null,
17243                                new IIntentReceiver.Stub() {
17244                                    public void performReceive(Intent intent, int resultCode,
17245                                            String data, Bundle extras, boolean ordered,
17246                                            boolean sticky, int sendingUser) {
17247                                        userInitialized(uss, userId);
17248                                    }
17249                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17250                                true, false, MY_PID, Process.SYSTEM_UID,
17251                                userId);
17252                        uss.initializing = true;
17253                    } else {
17254                        getUserManagerLocked().makeInitialized(userInfo.id);
17255                    }
17256                }
17257
17258                if (foreground) {
17259                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17260                    if (homeInFront) {
17261                        startHomeActivityLocked(userId);
17262                    } else {
17263                        mStackSupervisor.resumeTopActivitiesLocked();
17264                    }
17265                    EventLogTags.writeAmSwitchUser(userId);
17266                    getUserManagerLocked().userForeground(userId);
17267                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17268                } else {
17269                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17270                }
17271
17272                if (needStart) {
17273                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17274                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17275                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17276                    broadcastIntentLocked(null, null, intent,
17277                            null, new IIntentReceiver.Stub() {
17278                                @Override
17279                                public void performReceive(Intent intent, int resultCode, String data,
17280                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17281                                        throws RemoteException {
17282                                }
17283                            }, 0, null, null,
17284                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17285                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17286                }
17287            }
17288        } finally {
17289            Binder.restoreCallingIdentity(ident);
17290        }
17291
17292        return true;
17293    }
17294
17295    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17296        long ident = Binder.clearCallingIdentity();
17297        try {
17298            Intent intent;
17299            if (oldUserId >= 0) {
17300                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17301                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17302                int count = profiles.size();
17303                for (int i = 0; i < count; i++) {
17304                    int profileUserId = profiles.get(i).id;
17305                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17306                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17307                            | Intent.FLAG_RECEIVER_FOREGROUND);
17308                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17309                    broadcastIntentLocked(null, null, intent,
17310                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17311                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17312                }
17313            }
17314            if (newUserId >= 0) {
17315                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17316                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17317                int count = profiles.size();
17318                for (int i = 0; i < count; i++) {
17319                    int profileUserId = profiles.get(i).id;
17320                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17321                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17322                            | Intent.FLAG_RECEIVER_FOREGROUND);
17323                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17324                    broadcastIntentLocked(null, null, intent,
17325                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17326                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17327                }
17328                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17329                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17330                        | Intent.FLAG_RECEIVER_FOREGROUND);
17331                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17332                broadcastIntentLocked(null, null, intent,
17333                        null, null, 0, null, null,
17334                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17335                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17336            }
17337        } finally {
17338            Binder.restoreCallingIdentity(ident);
17339        }
17340    }
17341
17342    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17343            final int newUserId) {
17344        final int N = mUserSwitchObservers.beginBroadcast();
17345        if (N > 0) {
17346            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17347                int mCount = 0;
17348                @Override
17349                public void sendResult(Bundle data) throws RemoteException {
17350                    synchronized (ActivityManagerService.this) {
17351                        if (mCurUserSwitchCallback == this) {
17352                            mCount++;
17353                            if (mCount == N) {
17354                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17355                            }
17356                        }
17357                    }
17358                }
17359            };
17360            synchronized (this) {
17361                uss.switching = true;
17362                mCurUserSwitchCallback = callback;
17363            }
17364            for (int i=0; i<N; i++) {
17365                try {
17366                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17367                            newUserId, callback);
17368                } catch (RemoteException e) {
17369                }
17370            }
17371        } else {
17372            synchronized (this) {
17373                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17374            }
17375        }
17376        mUserSwitchObservers.finishBroadcast();
17377    }
17378
17379    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17380        synchronized (this) {
17381            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17382            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17383        }
17384    }
17385
17386    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17387        mCurUserSwitchCallback = null;
17388        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17389        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17390                oldUserId, newUserId, uss));
17391    }
17392
17393    void userInitialized(UserStartedState uss, int newUserId) {
17394        completeSwitchAndInitalize(uss, newUserId, true, false);
17395    }
17396
17397    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17398        completeSwitchAndInitalize(uss, newUserId, false, true);
17399    }
17400
17401    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17402            boolean clearInitializing, boolean clearSwitching) {
17403        boolean unfrozen = false;
17404        synchronized (this) {
17405            if (clearInitializing) {
17406                uss.initializing = false;
17407                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17408            }
17409            if (clearSwitching) {
17410                uss.switching = false;
17411            }
17412            if (!uss.switching && !uss.initializing) {
17413                mWindowManager.stopFreezingScreen();
17414                unfrozen = true;
17415            }
17416        }
17417        if (unfrozen) {
17418            final int N = mUserSwitchObservers.beginBroadcast();
17419            for (int i=0; i<N; i++) {
17420                try {
17421                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17422                } catch (RemoteException e) {
17423                }
17424            }
17425            mUserSwitchObservers.finishBroadcast();
17426        }
17427    }
17428
17429    void scheduleStartProfilesLocked() {
17430        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17431            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17432                    DateUtils.SECOND_IN_MILLIS);
17433        }
17434    }
17435
17436    void startProfilesLocked() {
17437        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17438        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17439                mCurrentUserId, false /* enabledOnly */);
17440        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17441        for (UserInfo user : profiles) {
17442            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17443                    && user.id != mCurrentUserId) {
17444                toStart.add(user);
17445            }
17446        }
17447        final int n = toStart.size();
17448        int i = 0;
17449        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17450            startUserInBackground(toStart.get(i).id);
17451        }
17452        if (i < n) {
17453            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17454        }
17455    }
17456
17457    void finishUserBoot(UserStartedState uss) {
17458        synchronized (this) {
17459            if (uss.mState == UserStartedState.STATE_BOOTING
17460                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17461                uss.mState = UserStartedState.STATE_RUNNING;
17462                final int userId = uss.mHandle.getIdentifier();
17463                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17464                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17465                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17466                broadcastIntentLocked(null, null, intent,
17467                        null, null, 0, null, null,
17468                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17469                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17470            }
17471        }
17472    }
17473
17474    void finishUserSwitch(UserStartedState uss) {
17475        synchronized (this) {
17476            finishUserBoot(uss);
17477
17478            startProfilesLocked();
17479
17480            int num = mUserLru.size();
17481            int i = 0;
17482            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17483                Integer oldUserId = mUserLru.get(i);
17484                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17485                if (oldUss == null) {
17486                    // Shouldn't happen, but be sane if it does.
17487                    mUserLru.remove(i);
17488                    num--;
17489                    continue;
17490                }
17491                if (oldUss.mState == UserStartedState.STATE_STOPPING
17492                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17493                    // This user is already stopping, doesn't count.
17494                    num--;
17495                    i++;
17496                    continue;
17497                }
17498                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17499                    // Owner and current can't be stopped, but count as running.
17500                    i++;
17501                    continue;
17502                }
17503                // This is a user to be stopped.
17504                stopUserLocked(oldUserId, null);
17505                num--;
17506                i++;
17507            }
17508        }
17509    }
17510
17511    @Override
17512    public int stopUser(final int userId, final IStopUserCallback callback) {
17513        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17514                != PackageManager.PERMISSION_GRANTED) {
17515            String msg = "Permission Denial: switchUser() from pid="
17516                    + Binder.getCallingPid()
17517                    + ", uid=" + Binder.getCallingUid()
17518                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17519            Slog.w(TAG, msg);
17520            throw new SecurityException(msg);
17521        }
17522        if (userId <= 0) {
17523            throw new IllegalArgumentException("Can't stop primary user " + userId);
17524        }
17525        synchronized (this) {
17526            return stopUserLocked(userId, callback);
17527        }
17528    }
17529
17530    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17531        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17532        if (mCurrentUserId == userId) {
17533            return ActivityManager.USER_OP_IS_CURRENT;
17534        }
17535
17536        final UserStartedState uss = mStartedUsers.get(userId);
17537        if (uss == null) {
17538            // User is not started, nothing to do...  but we do need to
17539            // callback if requested.
17540            if (callback != null) {
17541                mHandler.post(new Runnable() {
17542                    @Override
17543                    public void run() {
17544                        try {
17545                            callback.userStopped(userId);
17546                        } catch (RemoteException e) {
17547                        }
17548                    }
17549                });
17550            }
17551            return ActivityManager.USER_OP_SUCCESS;
17552        }
17553
17554        if (callback != null) {
17555            uss.mStopCallbacks.add(callback);
17556        }
17557
17558        if (uss.mState != UserStartedState.STATE_STOPPING
17559                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17560            uss.mState = UserStartedState.STATE_STOPPING;
17561            updateStartedUserArrayLocked();
17562
17563            long ident = Binder.clearCallingIdentity();
17564            try {
17565                // We are going to broadcast ACTION_USER_STOPPING and then
17566                // once that is done send a final ACTION_SHUTDOWN and then
17567                // stop the user.
17568                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17569                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17570                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17571                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17572                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17573                // This is the result receiver for the final shutdown broadcast.
17574                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17575                    @Override
17576                    public void performReceive(Intent intent, int resultCode, String data,
17577                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17578                        finishUserStop(uss);
17579                    }
17580                };
17581                // This is the result receiver for the initial stopping broadcast.
17582                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17583                    @Override
17584                    public void performReceive(Intent intent, int resultCode, String data,
17585                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17586                        // On to the next.
17587                        synchronized (ActivityManagerService.this) {
17588                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17589                                // Whoops, we are being started back up.  Abort, abort!
17590                                return;
17591                            }
17592                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17593                        }
17594                        mBatteryStatsService.noteEvent(
17595                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17596                                Integer.toString(userId), userId);
17597                        mSystemServiceManager.stopUser(userId);
17598                        broadcastIntentLocked(null, null, shutdownIntent,
17599                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17600                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17601                    }
17602                };
17603                // Kick things off.
17604                broadcastIntentLocked(null, null, stoppingIntent,
17605                        null, stoppingReceiver, 0, null, null,
17606                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17607                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17608            } finally {
17609                Binder.restoreCallingIdentity(ident);
17610            }
17611        }
17612
17613        return ActivityManager.USER_OP_SUCCESS;
17614    }
17615
17616    void finishUserStop(UserStartedState uss) {
17617        final int userId = uss.mHandle.getIdentifier();
17618        boolean stopped;
17619        ArrayList<IStopUserCallback> callbacks;
17620        synchronized (this) {
17621            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17622            if (mStartedUsers.get(userId) != uss) {
17623                stopped = false;
17624            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17625                stopped = false;
17626            } else {
17627                stopped = true;
17628                // User can no longer run.
17629                mStartedUsers.remove(userId);
17630                mUserLru.remove(Integer.valueOf(userId));
17631                updateStartedUserArrayLocked();
17632
17633                // Clean up all state and processes associated with the user.
17634                // Kill all the processes for the user.
17635                forceStopUserLocked(userId, "finish user");
17636            }
17637        }
17638
17639        for (int i=0; i<callbacks.size(); i++) {
17640            try {
17641                if (stopped) callbacks.get(i).userStopped(userId);
17642                else callbacks.get(i).userStopAborted(userId);
17643            } catch (RemoteException e) {
17644            }
17645        }
17646
17647        if (stopped) {
17648            mSystemServiceManager.cleanupUser(userId);
17649            synchronized (this) {
17650                mStackSupervisor.removeUserLocked(userId);
17651            }
17652        }
17653    }
17654
17655    @Override
17656    public UserInfo getCurrentUser() {
17657        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17658                != PackageManager.PERMISSION_GRANTED) && (
17659                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17660                != PackageManager.PERMISSION_GRANTED)) {
17661            String msg = "Permission Denial: getCurrentUser() from pid="
17662                    + Binder.getCallingPid()
17663                    + ", uid=" + Binder.getCallingUid()
17664                    + " requires " + INTERACT_ACROSS_USERS;
17665            Slog.w(TAG, msg);
17666            throw new SecurityException(msg);
17667        }
17668        synchronized (this) {
17669            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17670        }
17671    }
17672
17673    int getCurrentUserIdLocked() {
17674        return mCurrentUserId;
17675    }
17676
17677    @Override
17678    public boolean isUserRunning(int userId, boolean orStopped) {
17679        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17680                != PackageManager.PERMISSION_GRANTED) {
17681            String msg = "Permission Denial: isUserRunning() from pid="
17682                    + Binder.getCallingPid()
17683                    + ", uid=" + Binder.getCallingUid()
17684                    + " requires " + INTERACT_ACROSS_USERS;
17685            Slog.w(TAG, msg);
17686            throw new SecurityException(msg);
17687        }
17688        synchronized (this) {
17689            return isUserRunningLocked(userId, orStopped);
17690        }
17691    }
17692
17693    boolean isUserRunningLocked(int userId, boolean orStopped) {
17694        UserStartedState state = mStartedUsers.get(userId);
17695        if (state == null) {
17696            return false;
17697        }
17698        if (orStopped) {
17699            return true;
17700        }
17701        return state.mState != UserStartedState.STATE_STOPPING
17702                && state.mState != UserStartedState.STATE_SHUTDOWN;
17703    }
17704
17705    @Override
17706    public int[] getRunningUserIds() {
17707        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17708                != PackageManager.PERMISSION_GRANTED) {
17709            String msg = "Permission Denial: isUserRunning() from pid="
17710                    + Binder.getCallingPid()
17711                    + ", uid=" + Binder.getCallingUid()
17712                    + " requires " + INTERACT_ACROSS_USERS;
17713            Slog.w(TAG, msg);
17714            throw new SecurityException(msg);
17715        }
17716        synchronized (this) {
17717            return mStartedUserArray;
17718        }
17719    }
17720
17721    private void updateStartedUserArrayLocked() {
17722        int num = 0;
17723        for (int i=0; i<mStartedUsers.size();  i++) {
17724            UserStartedState uss = mStartedUsers.valueAt(i);
17725            // This list does not include stopping users.
17726            if (uss.mState != UserStartedState.STATE_STOPPING
17727                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17728                num++;
17729            }
17730        }
17731        mStartedUserArray = new int[num];
17732        num = 0;
17733        for (int i=0; i<mStartedUsers.size();  i++) {
17734            UserStartedState uss = mStartedUsers.valueAt(i);
17735            if (uss.mState != UserStartedState.STATE_STOPPING
17736                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17737                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17738                num++;
17739            }
17740        }
17741    }
17742
17743    @Override
17744    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17745        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17746                != PackageManager.PERMISSION_GRANTED) {
17747            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17748                    + Binder.getCallingPid()
17749                    + ", uid=" + Binder.getCallingUid()
17750                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17751            Slog.w(TAG, msg);
17752            throw new SecurityException(msg);
17753        }
17754
17755        mUserSwitchObservers.register(observer);
17756    }
17757
17758    @Override
17759    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17760        mUserSwitchObservers.unregister(observer);
17761    }
17762
17763    private boolean userExists(int userId) {
17764        if (userId == 0) {
17765            return true;
17766        }
17767        UserManagerService ums = getUserManagerLocked();
17768        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17769    }
17770
17771    int[] getUsersLocked() {
17772        UserManagerService ums = getUserManagerLocked();
17773        return ums != null ? ums.getUserIds() : new int[] { 0 };
17774    }
17775
17776    UserManagerService getUserManagerLocked() {
17777        if (mUserManager == null) {
17778            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17779            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17780        }
17781        return mUserManager;
17782    }
17783
17784    private int applyUserId(int uid, int userId) {
17785        return UserHandle.getUid(userId, uid);
17786    }
17787
17788    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17789        if (info == null) return null;
17790        ApplicationInfo newInfo = new ApplicationInfo(info);
17791        newInfo.uid = applyUserId(info.uid, userId);
17792        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17793                + info.packageName;
17794        return newInfo;
17795    }
17796
17797    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17798        if (aInfo == null
17799                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17800            return aInfo;
17801        }
17802
17803        ActivityInfo info = new ActivityInfo(aInfo);
17804        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17805        return info;
17806    }
17807
17808    private final class LocalService extends ActivityManagerInternal {
17809        @Override
17810        public void goingToSleep() {
17811            ActivityManagerService.this.goingToSleep();
17812        }
17813
17814        @Override
17815        public void wakingUp() {
17816            ActivityManagerService.this.wakingUp();
17817        }
17818    }
17819
17820    /**
17821     * An implementation of IAppTask, that allows an app to manage its own tasks via
17822     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17823     * only the process that calls getAppTasks() can call the AppTask methods.
17824     */
17825    class AppTaskImpl extends IAppTask.Stub {
17826        private int mTaskId;
17827        private int mCallingUid;
17828
17829        public AppTaskImpl(int taskId, int callingUid) {
17830            mTaskId = taskId;
17831            mCallingUid = callingUid;
17832        }
17833
17834        @Override
17835        public void finishAndRemoveTask() {
17836            // Ensure that we are called from the same process that created this AppTask
17837            if (mCallingUid != Binder.getCallingUid()) {
17838                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17839                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17840                return;
17841            }
17842
17843            synchronized (ActivityManagerService.this) {
17844                long origId = Binder.clearCallingIdentity();
17845                try {
17846                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17847                    if (tr != null) {
17848                        // Only kill the process if we are not a new document
17849                        int flags = tr.getBaseIntent().getFlags();
17850                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17851                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17852                        removeTaskByIdLocked(mTaskId,
17853                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17854                    }
17855                } finally {
17856                    Binder.restoreCallingIdentity(origId);
17857                }
17858            }
17859        }
17860
17861        @Override
17862        public ActivityManager.RecentTaskInfo getTaskInfo() {
17863            // Ensure that we are called from the same process that created this AppTask
17864            if (mCallingUid != Binder.getCallingUid()) {
17865                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17866                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17867                return null;
17868            }
17869
17870            synchronized (ActivityManagerService.this) {
17871                long origId = Binder.clearCallingIdentity();
17872                try {
17873                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17874                    if (tr != null) {
17875                        return createRecentTaskInfoFromTaskRecord(tr);
17876                    }
17877                } finally {
17878                    Binder.restoreCallingIdentity(origId);
17879                }
17880                return null;
17881            }
17882        }
17883    }
17884}
17885