ActivityManagerService.java revision d412563922f46feb4d3c3ba1500f34bddd21d73c
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.ApplicationThreadNative;
37import android.app.IActivityContainer;
38import android.app.IActivityContainerCallback;
39import android.app.IAppTask;
40import android.app.ProfilerInfo;
41import android.app.admin.DevicePolicyManager;
42import android.app.usage.UsageEvents;
43import android.app.usage.UsageStatsManagerInternal;
44import android.appwidget.AppWidgetManager;
45import android.content.res.Resources;
46import android.graphics.Bitmap;
47import android.graphics.Point;
48import android.graphics.Rect;
49import android.os.BatteryStats;
50import android.os.PersistableBundle;
51import android.service.voice.IVoiceInteractionSession;
52import android.util.ArrayMap;
53import android.util.ArraySet;
54import android.util.SparseIntArray;
55
56import com.android.internal.R;
57import com.android.internal.annotations.GuardedBy;
58import com.android.internal.app.IAppOpsService;
59import com.android.internal.app.IVoiceInteractor;
60import com.android.internal.app.ProcessMap;
61import com.android.internal.app.ProcessStats;
62import com.android.internal.content.PackageMonitor;
63import com.android.internal.os.BackgroundThread;
64import com.android.internal.os.BatteryStatsImpl;
65import com.android.internal.os.ProcessCpuTracker;
66import com.android.internal.os.TransferPipe;
67import com.android.internal.os.Zygote;
68import com.android.internal.util.FastPrintWriter;
69import com.android.internal.util.FastXmlSerializer;
70import com.android.internal.util.MemInfoReader;
71import com.android.internal.util.Preconditions;
72import com.android.server.AppOpsService;
73import com.android.server.AttributeCache;
74import com.android.server.IntentResolver;
75import com.android.server.LocalServices;
76import com.android.server.ServiceThread;
77import com.android.server.SystemService;
78import com.android.server.SystemServiceManager;
79import com.android.server.Watchdog;
80import com.android.server.am.ActivityStack.ActivityState;
81import com.android.server.firewall.IntentFirewall;
82import com.android.server.pm.UserManagerService;
83import com.android.server.wm.AppTransition;
84import com.android.server.wm.WindowManagerService;
85import com.google.android.collect.Lists;
86import com.google.android.collect.Maps;
87
88import libcore.io.IoUtils;
89
90import org.xmlpull.v1.XmlPullParser;
91import org.xmlpull.v1.XmlPullParserException;
92import org.xmlpull.v1.XmlSerializer;
93
94import android.app.Activity;
95import android.app.ActivityManager;
96import android.app.ActivityManager.RunningTaskInfo;
97import android.app.ActivityManager.StackInfo;
98import android.app.ActivityManagerInternal;
99import android.app.ActivityManagerNative;
100import android.app.ActivityOptions;
101import android.app.ActivityThread;
102import android.app.AlertDialog;
103import android.app.AppGlobals;
104import android.app.ApplicationErrorReport;
105import android.app.Dialog;
106import android.app.IActivityController;
107import android.app.IApplicationThread;
108import android.app.IInstrumentationWatcher;
109import android.app.INotificationManager;
110import android.app.IProcessObserver;
111import android.app.IServiceConnection;
112import android.app.IStopUserCallback;
113import android.app.IUiAutomationConnection;
114import android.app.IUserSwitchObserver;
115import android.app.Instrumentation;
116import android.app.Notification;
117import android.app.NotificationManager;
118import android.app.PendingIntent;
119import android.app.backup.IBackupManager;
120import android.content.ActivityNotFoundException;
121import android.content.BroadcastReceiver;
122import android.content.ClipData;
123import android.content.ComponentCallbacks2;
124import android.content.ComponentName;
125import android.content.ContentProvider;
126import android.content.ContentResolver;
127import android.content.Context;
128import android.content.DialogInterface;
129import android.content.IContentProvider;
130import android.content.IIntentReceiver;
131import android.content.IIntentSender;
132import android.content.Intent;
133import android.content.IntentFilter;
134import android.content.IntentSender;
135import android.content.pm.ActivityInfo;
136import android.content.pm.ApplicationInfo;
137import android.content.pm.ConfigurationInfo;
138import android.content.pm.IPackageDataObserver;
139import android.content.pm.IPackageManager;
140import android.content.pm.InstrumentationInfo;
141import android.content.pm.PackageInfo;
142import android.content.pm.PackageManager;
143import android.content.pm.ParceledListSlice;
144import android.content.pm.UserInfo;
145import android.content.pm.PackageManager.NameNotFoundException;
146import android.content.pm.PathPermission;
147import android.content.pm.ProviderInfo;
148import android.content.pm.ResolveInfo;
149import android.content.pm.ServiceInfo;
150import android.content.res.CompatibilityInfo;
151import android.content.res.Configuration;
152import android.net.Proxy;
153import android.net.ProxyInfo;
154import android.net.Uri;
155import android.os.Binder;
156import android.os.Build;
157import android.os.Bundle;
158import android.os.Debug;
159import android.os.DropBoxManager;
160import android.os.Environment;
161import android.os.FactoryTest;
162import android.os.FileObserver;
163import android.os.FileUtils;
164import android.os.Handler;
165import android.os.IBinder;
166import android.os.IPermissionController;
167import android.os.IRemoteCallback;
168import android.os.IUserManager;
169import android.os.Looper;
170import android.os.Message;
171import android.os.Parcel;
172import android.os.ParcelFileDescriptor;
173import android.os.Process;
174import android.os.RemoteCallbackList;
175import android.os.RemoteException;
176import android.os.SELinux;
177import android.os.ServiceManager;
178import android.os.StrictMode;
179import android.os.SystemClock;
180import android.os.SystemProperties;
181import android.os.UpdateLock;
182import android.os.UserHandle;
183import android.os.UserManager;
184import android.provider.Settings;
185import android.text.format.DateUtils;
186import android.text.format.Time;
187import android.util.AtomicFile;
188import android.util.EventLog;
189import android.util.Log;
190import android.util.Pair;
191import android.util.PrintWriterPrinter;
192import android.util.Slog;
193import android.util.SparseArray;
194import android.util.TimeUtils;
195import android.util.Xml;
196import android.view.Gravity;
197import android.view.LayoutInflater;
198import android.view.View;
199import android.view.WindowManager;
200import dalvik.system.VMRuntime;
201
202import java.io.BufferedInputStream;
203import java.io.BufferedOutputStream;
204import java.io.DataInputStream;
205import java.io.DataOutputStream;
206import java.io.File;
207import java.io.FileDescriptor;
208import java.io.FileInputStream;
209import java.io.FileNotFoundException;
210import java.io.FileOutputStream;
211import java.io.IOException;
212import java.io.InputStreamReader;
213import java.io.PrintWriter;
214import java.io.StringWriter;
215import java.lang.ref.WeakReference;
216import java.util.ArrayList;
217import java.util.Arrays;
218import java.util.Collections;
219import java.util.Comparator;
220import java.util.HashMap;
221import java.util.HashSet;
222import java.util.Iterator;
223import java.util.List;
224import java.util.Locale;
225import java.util.Map;
226import java.util.Set;
227import java.util.concurrent.atomic.AtomicBoolean;
228import java.util.concurrent.atomic.AtomicLong;
229
230public final class ActivityManagerService extends ActivityManagerNative
231        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
232
233    private static final String USER_DATA_DIR = "/data/user/";
234    // File that stores last updated system version and called preboot receivers
235    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
236
237    static final String TAG = "ActivityManager";
238    static final String TAG_MU = "ActivityManagerServiceMU";
239    static final boolean DEBUG = false;
240    static final boolean localLOGV = DEBUG;
241    static final boolean DEBUG_BACKUP = localLOGV || false;
242    static final boolean DEBUG_BROADCAST = localLOGV || false;
243    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
244    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
245    static final boolean DEBUG_CLEANUP = localLOGV || false;
246    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
247    static final boolean DEBUG_FOCUS = false;
248    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
249    static final boolean DEBUG_MU = localLOGV || false;
250    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
251    static final boolean DEBUG_LRU = localLOGV || false;
252    static final boolean DEBUG_PAUSE = localLOGV || false;
253    static final boolean DEBUG_POWER = localLOGV || false;
254    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
255    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
256    static final boolean DEBUG_PROCESSES = localLOGV || false;
257    static final boolean DEBUG_PROVIDER = localLOGV || false;
258    static final boolean DEBUG_RESULTS = localLOGV || false;
259    static final boolean DEBUG_SERVICE = localLOGV || false;
260    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
261    static final boolean DEBUG_STACK = localLOGV || false;
262    static final boolean DEBUG_SWITCH = localLOGV || false;
263    static final boolean DEBUG_TASKS = localLOGV || false;
264    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
265    static final boolean DEBUG_TRANSITION = localLOGV || false;
266    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
267    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
268    static final boolean DEBUG_VISBILITY = localLOGV || false;
269    static final boolean DEBUG_PSS = localLOGV || false;
270    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
271    static final boolean DEBUG_RECENTS = localLOGV || false;
272    static final boolean VALIDATE_TOKENS = false;
273    static final boolean SHOW_ACTIVITY_START_TIME = true;
274
275    // Control over CPU and battery monitoring.
276    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
277    static final boolean MONITOR_CPU_USAGE = true;
278    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
279    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
280    static final boolean MONITOR_THREAD_CPU_USAGE = false;
281
282    // The flags that are set for all calls we make to the package manager.
283    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
284
285    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
286
287    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
288
289    // Maximum number recent bitmaps to keep in memory.
290    static final int MAX_RECENT_BITMAPS = 5;
291
292    // Amount of time after a call to stopAppSwitches() during which we will
293    // prevent further untrusted switches from happening.
294    static final long APP_SWITCH_DELAY_TIME = 5*1000;
295
296    // How long we wait for a launched process to attach to the activity manager
297    // before we decide it's never going to come up for real.
298    static final int PROC_START_TIMEOUT = 10*1000;
299
300    // How long we wait for a launched process to attach to the activity manager
301    // before we decide it's never going to come up for real, when the process was
302    // started with a wrapper for instrumentation (such as Valgrind) because it
303    // could take much longer than usual.
304    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
305
306    // How long to wait after going idle before forcing apps to GC.
307    static final int GC_TIMEOUT = 5*1000;
308
309    // The minimum amount of time between successive GC requests for a process.
310    static final int GC_MIN_INTERVAL = 60*1000;
311
312    // The minimum amount of time between successive PSS requests for a process.
313    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
314
315    // The minimum amount of time between successive PSS requests for a process
316    // when the request is due to the memory state being lowered.
317    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
318
319    // The rate at which we check for apps using excessive power -- 15 mins.
320    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
321
322    // The minimum sample duration we will allow before deciding we have
323    // enough data on wake locks to start killing things.
324    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
325
326    // The minimum sample duration we will allow before deciding we have
327    // enough data on CPU usage to start killing things.
328    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
329
330    // How long we allow a receiver to run before giving up on it.
331    static final int BROADCAST_FG_TIMEOUT = 10*1000;
332    static final int BROADCAST_BG_TIMEOUT = 60*1000;
333
334    // How long we wait until we timeout on key dispatching.
335    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
336
337    // How long we wait until we timeout on key dispatching during instrumentation.
338    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
339
340    // Amount of time we wait for observers to handle a user switch before
341    // giving up on them and unfreezing the screen.
342    static final int USER_SWITCH_TIMEOUT = 2*1000;
343
344    // Maximum number of users we allow to be running at a time.
345    static final int MAX_RUNNING_USERS = 3;
346
347    // How long to wait in getAssistContextExtras for the activity and foreground services
348    // to respond with the result.
349    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
350
351    // Maximum number of persisted Uri grants a package is allowed
352    static final int MAX_PERSISTED_URI_GRANTS = 128;
353
354    static final int MY_PID = Process.myPid();
355
356    static final String[] EMPTY_STRING_ARRAY = new String[0];
357
358    // How many bytes to write into the dropbox log before truncating
359    static final int DROPBOX_MAX_SIZE = 256 * 1024;
360
361    // Access modes for handleIncomingUser.
362    static final int ALLOW_NON_FULL = 0;
363    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
364    static final int ALLOW_FULL_ONLY = 2;
365
366    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
367
368    /** All system services */
369    SystemServiceManager mSystemServiceManager;
370
371    /** Run all ActivityStacks through this */
372    ActivityStackSupervisor mStackSupervisor;
373
374    public IntentFirewall mIntentFirewall;
375
376    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
377    // default actuion automatically.  Important for devices without direct input
378    // devices.
379    private boolean mShowDialogs = true;
380
381    BroadcastQueue mFgBroadcastQueue;
382    BroadcastQueue mBgBroadcastQueue;
383    // Convenient for easy iteration over the queues. Foreground is first
384    // so that dispatch of foreground broadcasts gets precedence.
385    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
386
387    BroadcastQueue broadcastQueueForIntent(Intent intent) {
388        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
389        if (DEBUG_BACKGROUND_BROADCAST) {
390            Slog.i(TAG, "Broadcast intent " + intent + " on "
391                    + (isFg ? "foreground" : "background")
392                    + " queue");
393        }
394        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
395    }
396
397    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
398        for (BroadcastQueue queue : mBroadcastQueues) {
399            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
400            if (r != null) {
401                return r;
402            }
403        }
404        return null;
405    }
406
407    /**
408     * Activity we have told the window manager to have key focus.
409     */
410    ActivityRecord mFocusedActivity = null;
411
412    /**
413     * List of intents that were used to start the most recent tasks.
414     */
415    ArrayList<TaskRecord> mRecentTasks;
416    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
417
418    /**
419     * For addAppTask: cached of the last activity component that was added.
420     */
421    ComponentName mLastAddedTaskComponent;
422
423    /**
424     * For addAppTask: cached of the last activity uid that was added.
425     */
426    int mLastAddedTaskUid;
427
428    /**
429     * For addAppTask: cached of the last ActivityInfo that was added.
430     */
431    ActivityInfo mLastAddedTaskActivity;
432
433    public class PendingAssistExtras extends Binder implements Runnable {
434        public final ActivityRecord activity;
435        public boolean haveResult = false;
436        public Bundle result = null;
437        public PendingAssistExtras(ActivityRecord _activity) {
438            activity = _activity;
439        }
440        @Override
441        public void run() {
442            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
443            synchronized (this) {
444                haveResult = true;
445                notifyAll();
446            }
447        }
448    }
449
450    final ArrayList<PendingAssistExtras> mPendingAssistExtras
451            = new ArrayList<PendingAssistExtras>();
452
453    /**
454     * Process management.
455     */
456    final ProcessList mProcessList = new ProcessList();
457
458    /**
459     * All of the applications we currently have running organized by name.
460     * The keys are strings of the application package name (as
461     * returned by the package manager), and the keys are ApplicationRecord
462     * objects.
463     */
464    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
465
466    /**
467     * Tracking long-term execution of processes to look for abuse and other
468     * bad app behavior.
469     */
470    final ProcessStatsService mProcessStats;
471
472    /**
473     * The currently running isolated processes.
474     */
475    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
476
477    /**
478     * Counter for assigning isolated process uids, to avoid frequently reusing the
479     * same ones.
480     */
481    int mNextIsolatedProcessUid = 0;
482
483    /**
484     * The currently running heavy-weight process, if any.
485     */
486    ProcessRecord mHeavyWeightProcess = null;
487
488    /**
489     * The last time that various processes have crashed.
490     */
491    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
492
493    /**
494     * Information about a process that is currently marked as bad.
495     */
496    static final class BadProcessInfo {
497        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
498            this.time = time;
499            this.shortMsg = shortMsg;
500            this.longMsg = longMsg;
501            this.stack = stack;
502        }
503
504        final long time;
505        final String shortMsg;
506        final String longMsg;
507        final String stack;
508    }
509
510    /**
511     * Set of applications that we consider to be bad, and will reject
512     * incoming broadcasts from (which the user has no control over).
513     * Processes are added to this set when they have crashed twice within
514     * a minimum amount of time; they are removed from it when they are
515     * later restarted (hopefully due to some user action).  The value is the
516     * time it was added to the list.
517     */
518    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
519
520    /**
521     * All of the processes we currently have running organized by pid.
522     * The keys are the pid running the application.
523     *
524     * <p>NOTE: This object is protected by its own lock, NOT the global
525     * activity manager lock!
526     */
527    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
528
529    /**
530     * All of the processes that have been forced to be foreground.  The key
531     * is the pid of the caller who requested it (we hold a death
532     * link on it).
533     */
534    abstract class ForegroundToken implements IBinder.DeathRecipient {
535        int pid;
536        IBinder token;
537    }
538    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
539
540    /**
541     * List of records for processes that someone had tried to start before the
542     * system was ready.  We don't start them at that point, but ensure they
543     * are started by the time booting is complete.
544     */
545    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
546
547    /**
548     * List of persistent applications that are in the process
549     * of being started.
550     */
551    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
552
553    /**
554     * Processes that are being forcibly torn down.
555     */
556    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
557
558    /**
559     * List of running applications, sorted by recent usage.
560     * The first entry in the list is the least recently used.
561     */
562    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
563
564    /**
565     * Where in mLruProcesses that the processes hosting activities start.
566     */
567    int mLruProcessActivityStart = 0;
568
569    /**
570     * Where in mLruProcesses that the processes hosting services start.
571     * This is after (lower index) than mLruProcessesActivityStart.
572     */
573    int mLruProcessServiceStart = 0;
574
575    /**
576     * List of processes that should gc as soon as things are idle.
577     */
578    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
579
580    /**
581     * Processes we want to collect PSS data from.
582     */
583    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
584
585    /**
586     * Last time we requested PSS data of all processes.
587     */
588    long mLastFullPssTime = SystemClock.uptimeMillis();
589
590    /**
591     * If set, the next time we collect PSS data we should do a full collection
592     * with data from native processes and the kernel.
593     */
594    boolean mFullPssPending = false;
595
596    /**
597     * This is the process holding what we currently consider to be
598     * the "home" activity.
599     */
600    ProcessRecord mHomeProcess;
601
602    /**
603     * This is the process holding the activity the user last visited that
604     * is in a different process from the one they are currently in.
605     */
606    ProcessRecord mPreviousProcess;
607
608    /**
609     * The time at which the previous process was last visible.
610     */
611    long mPreviousProcessVisibleTime;
612
613    /**
614     * Which uses have been started, so are allowed to run code.
615     */
616    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
617
618    /**
619     * LRU list of history of current users.  Most recently current is at the end.
620     */
621    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
622
623    /**
624     * Constant array of the users that are currently started.
625     */
626    int[] mStartedUserArray = new int[] { 0 };
627
628    /**
629     * Registered observers of the user switching mechanics.
630     */
631    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
632            = new RemoteCallbackList<IUserSwitchObserver>();
633
634    /**
635     * Currently active user switch.
636     */
637    Object mCurUserSwitchCallback;
638
639    /**
640     * Packages that the user has asked to have run in screen size
641     * compatibility mode instead of filling the screen.
642     */
643    final CompatModePackages mCompatModePackages;
644
645    /**
646     * Set of IntentSenderRecord objects that are currently active.
647     */
648    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
649            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
650
651    /**
652     * Fingerprints (hashCode()) of stack traces that we've
653     * already logged DropBox entries for.  Guarded by itself.  If
654     * something (rogue user app) forces this over
655     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
656     */
657    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
658    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
659
660    /**
661     * Strict Mode background batched logging state.
662     *
663     * The string buffer is guarded by itself, and its lock is also
664     * used to determine if another batched write is already
665     * in-flight.
666     */
667    private final StringBuilder mStrictModeBuffer = new StringBuilder();
668
669    /**
670     * Keeps track of all IIntentReceivers that have been registered for
671     * broadcasts.  Hash keys are the receiver IBinder, hash value is
672     * a ReceiverList.
673     */
674    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
675            new HashMap<IBinder, ReceiverList>();
676
677    /**
678     * Resolver for broadcast intents to registered receivers.
679     * Holds BroadcastFilter (subclass of IntentFilter).
680     */
681    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
682            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
683        @Override
684        protected boolean allowFilterResult(
685                BroadcastFilter filter, List<BroadcastFilter> dest) {
686            IBinder target = filter.receiverList.receiver.asBinder();
687            for (int i=dest.size()-1; i>=0; i--) {
688                if (dest.get(i).receiverList.receiver.asBinder() == target) {
689                    return false;
690                }
691            }
692            return true;
693        }
694
695        @Override
696        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
697            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
698                    || userId == filter.owningUserId) {
699                return super.newResult(filter, match, userId);
700            }
701            return null;
702        }
703
704        @Override
705        protected BroadcastFilter[] newArray(int size) {
706            return new BroadcastFilter[size];
707        }
708
709        @Override
710        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
711            return packageName.equals(filter.packageName);
712        }
713    };
714
715    /**
716     * State of all active sticky broadcasts per user.  Keys are the action of the
717     * sticky Intent, values are an ArrayList of all broadcasted intents with
718     * that action (which should usually be one).  The SparseArray is keyed
719     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
720     * for stickies that are sent to all users.
721     */
722    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
723            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
724
725    final ActiveServices mServices;
726
727    /**
728     * Backup/restore process management
729     */
730    String mBackupAppName = null;
731    BackupRecord mBackupTarget = null;
732
733    final ProviderMap mProviderMap;
734
735    /**
736     * List of content providers who have clients waiting for them.  The
737     * application is currently being launched and the provider will be
738     * removed from this list once it is published.
739     */
740    final ArrayList<ContentProviderRecord> mLaunchingProviders
741            = new ArrayList<ContentProviderRecord>();
742
743    /**
744     * File storing persisted {@link #mGrantedUriPermissions}.
745     */
746    private final AtomicFile mGrantFile;
747
748    /** XML constants used in {@link #mGrantFile} */
749    private static final String TAG_URI_GRANTS = "uri-grants";
750    private static final String TAG_URI_GRANT = "uri-grant";
751    private static final String ATTR_USER_HANDLE = "userHandle";
752    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
753    private static final String ATTR_TARGET_USER_ID = "targetUserId";
754    private static final String ATTR_SOURCE_PKG = "sourcePkg";
755    private static final String ATTR_TARGET_PKG = "targetPkg";
756    private static final String ATTR_URI = "uri";
757    private static final String ATTR_MODE_FLAGS = "modeFlags";
758    private static final String ATTR_CREATED_TIME = "createdTime";
759    private static final String ATTR_PREFIX = "prefix";
760
761    /**
762     * Global set of specific {@link Uri} permissions that have been granted.
763     * This optimized lookup structure maps from {@link UriPermission#targetUid}
764     * to {@link UriPermission#uri} to {@link UriPermission}.
765     */
766    @GuardedBy("this")
767    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
768            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
769
770    public static class GrantUri {
771        public final int sourceUserId;
772        public final Uri uri;
773        public boolean prefix;
774
775        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
776            this.sourceUserId = sourceUserId;
777            this.uri = uri;
778            this.prefix = prefix;
779        }
780
781        @Override
782        public int hashCode() {
783            return toString().hashCode();
784        }
785
786        @Override
787        public boolean equals(Object o) {
788            if (o instanceof GrantUri) {
789                GrantUri other = (GrantUri) o;
790                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
791                        && prefix == other.prefix;
792            }
793            return false;
794        }
795
796        @Override
797        public String toString() {
798            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
799            if (prefix) result += " [prefix]";
800            return result;
801        }
802
803        public String toSafeString() {
804            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
805            if (prefix) result += " [prefix]";
806            return result;
807        }
808
809        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
810            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
811                    ContentProvider.getUriWithoutUserId(uri), false);
812        }
813    }
814
815    CoreSettingsObserver mCoreSettingsObserver;
816
817    /**
818     * Thread-local storage used to carry caller permissions over through
819     * indirect content-provider access.
820     */
821    private class Identity {
822        public int pid;
823        public int uid;
824
825        Identity(int _pid, int _uid) {
826            pid = _pid;
827            uid = _uid;
828        }
829    }
830
831    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
832
833    /**
834     * All information we have collected about the runtime performance of
835     * any user id that can impact battery performance.
836     */
837    final BatteryStatsService mBatteryStatsService;
838
839    /**
840     * Information about component usage
841     */
842    UsageStatsManagerInternal mUsageStatsService;
843
844    /**
845     * Information about and control over application operations
846     */
847    final AppOpsService mAppOpsService;
848
849    /**
850     * Save recent tasks information across reboots.
851     */
852    final TaskPersister mTaskPersister;
853
854    /**
855     * Current configuration information.  HistoryRecord objects are given
856     * a reference to this object to indicate which configuration they are
857     * currently running in, so this object must be kept immutable.
858     */
859    Configuration mConfiguration = new Configuration();
860
861    /**
862     * Current sequencing integer of the configuration, for skipping old
863     * configurations.
864     */
865    int mConfigurationSeq = 0;
866
867    /**
868     * Hardware-reported OpenGLES version.
869     */
870    final int GL_ES_VERSION;
871
872    /**
873     * List of initialization arguments to pass to all processes when binding applications to them.
874     * For example, references to the commonly used services.
875     */
876    HashMap<String, IBinder> mAppBindArgs;
877
878    /**
879     * Temporary to avoid allocations.  Protected by main lock.
880     */
881    final StringBuilder mStringBuilder = new StringBuilder(256);
882
883    /**
884     * Used to control how we initialize the service.
885     */
886    ComponentName mTopComponent;
887    String mTopAction = Intent.ACTION_MAIN;
888    String mTopData;
889    boolean mProcessesReady = false;
890    boolean mSystemReady = false;
891    boolean mBooting = false;
892    boolean mCallFinishBooting = false;
893    boolean mBootAnimationComplete = false;
894    boolean mWaitingUpdate = false;
895    boolean mDidUpdate = false;
896    boolean mOnBattery = false;
897    boolean mLaunchWarningShown = false;
898
899    Context mContext;
900
901    int mFactoryTest;
902
903    boolean mCheckedForSetup;
904
905    /**
906     * The time at which we will allow normal application switches again,
907     * after a call to {@link #stopAppSwitches()}.
908     */
909    long mAppSwitchesAllowedTime;
910
911    /**
912     * This is set to true after the first switch after mAppSwitchesAllowedTime
913     * is set; any switches after that will clear the time.
914     */
915    boolean mDidAppSwitch;
916
917    /**
918     * Last time (in realtime) at which we checked for power usage.
919     */
920    long mLastPowerCheckRealtime;
921
922    /**
923     * Last time (in uptime) at which we checked for power usage.
924     */
925    long mLastPowerCheckUptime;
926
927    /**
928     * Set while we are wanting to sleep, to prevent any
929     * activities from being started/resumed.
930     */
931    private boolean mSleeping = false;
932
933    /**
934     * Set while we are running a voice interaction.  This overrides
935     * sleeping while it is active.
936     */
937    private boolean mRunningVoice = false;
938
939    /**
940     * Set while the keyguard is waiting for an activity to draw.
941     * In this state, if we are sleeping, we allow Activities to launch
942     * so that they can draw before Keyguard dismisses itself.
943     */
944    private boolean mKeyguardWaitingForDraw = false;
945
946    /**
947     * State of external calls telling us if the device is asleep.
948     */
949    private boolean mWentToSleep = false;
950
951    /**
952     * State of external call telling us if the lock screen is shown.
953     */
954    private boolean mLockScreenShown = false;
955
956    /**
957     * Set if we are shutting down the system, similar to sleeping.
958     */
959    boolean mShuttingDown = false;
960
961    /**
962     * Current sequence id for oom_adj computation traversal.
963     */
964    int mAdjSeq = 0;
965
966    /**
967     * Current sequence id for process LRU updating.
968     */
969    int mLruSeq = 0;
970
971    /**
972     * Keep track of the non-cached/empty process we last found, to help
973     * determine how to distribute cached/empty processes next time.
974     */
975    int mNumNonCachedProcs = 0;
976
977    /**
978     * Keep track of the number of cached hidden procs, to balance oom adj
979     * distribution between those and empty procs.
980     */
981    int mNumCachedHiddenProcs = 0;
982
983    /**
984     * Keep track of the number of service processes we last found, to
985     * determine on the next iteration which should be B services.
986     */
987    int mNumServiceProcs = 0;
988    int mNewNumAServiceProcs = 0;
989    int mNewNumServiceProcs = 0;
990
991    /**
992     * Allow the current computed overall memory level of the system to go down?
993     * This is set to false when we are killing processes for reasons other than
994     * memory management, so that the now smaller process list will not be taken as
995     * an indication that memory is tighter.
996     */
997    boolean mAllowLowerMemLevel = false;
998
999    /**
1000     * The last computed memory level, for holding when we are in a state that
1001     * processes are going away for other reasons.
1002     */
1003    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1004
1005    /**
1006     * The last total number of process we have, to determine if changes actually look
1007     * like a shrinking number of process due to lower RAM.
1008     */
1009    int mLastNumProcesses;
1010
1011    /**
1012     * The uptime of the last time we performed idle maintenance.
1013     */
1014    long mLastIdleTime = SystemClock.uptimeMillis();
1015
1016    /**
1017     * Total time spent with RAM that has been added in the past since the last idle time.
1018     */
1019    long mLowRamTimeSinceLastIdle = 0;
1020
1021    /**
1022     * If RAM is currently low, when that horrible situation started.
1023     */
1024    long mLowRamStartTime = 0;
1025
1026    /**
1027     * For reporting to battery stats the current top application.
1028     */
1029    private String mCurResumedPackage = null;
1030    private int mCurResumedUid = -1;
1031
1032    /**
1033     * For reporting to battery stats the apps currently running foreground
1034     * service.  The ProcessMap is package/uid tuples; each of these contain
1035     * an array of the currently foreground processes.
1036     */
1037    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1038            = new ProcessMap<ArrayList<ProcessRecord>>();
1039
1040    /**
1041     * This is set if we had to do a delayed dexopt of an app before launching
1042     * it, to increase the ANR timeouts in that case.
1043     */
1044    boolean mDidDexOpt;
1045
1046    /**
1047     * Set if the systemServer made a call to enterSafeMode.
1048     */
1049    boolean mSafeMode;
1050
1051    String mDebugApp = null;
1052    boolean mWaitForDebugger = false;
1053    boolean mDebugTransient = false;
1054    String mOrigDebugApp = null;
1055    boolean mOrigWaitForDebugger = false;
1056    boolean mAlwaysFinishActivities = false;
1057    IActivityController mController = null;
1058    String mProfileApp = null;
1059    ProcessRecord mProfileProc = null;
1060    String mProfileFile;
1061    ParcelFileDescriptor mProfileFd;
1062    int mSamplingInterval = 0;
1063    boolean mAutoStopProfiler = false;
1064    int mProfileType = 0;
1065    String mOpenGlTraceApp = null;
1066
1067    static class ProcessChangeItem {
1068        static final int CHANGE_ACTIVITIES = 1<<0;
1069        static final int CHANGE_PROCESS_STATE = 1<<1;
1070        int changes;
1071        int uid;
1072        int pid;
1073        int processState;
1074        boolean foregroundActivities;
1075    }
1076
1077    final RemoteCallbackList<IProcessObserver> mProcessObservers
1078            = new RemoteCallbackList<IProcessObserver>();
1079    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1080
1081    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1082            = new ArrayList<ProcessChangeItem>();
1083    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1084            = new ArrayList<ProcessChangeItem>();
1085
1086    /**
1087     * Runtime CPU use collection thread.  This object's lock is used to
1088     * perform synchronization with the thread (notifying it to run).
1089     */
1090    final Thread mProcessCpuThread;
1091
1092    /**
1093     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1094     * Must acquire this object's lock when accessing it.
1095     * NOTE: this lock will be held while doing long operations (trawling
1096     * through all processes in /proc), so it should never be acquired by
1097     * any critical paths such as when holding the main activity manager lock.
1098     */
1099    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1100            MONITOR_THREAD_CPU_USAGE);
1101    final AtomicLong mLastCpuTime = new AtomicLong(0);
1102    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1103
1104    long mLastWriteTime = 0;
1105
1106    /**
1107     * Used to retain an update lock when the foreground activity is in
1108     * immersive mode.
1109     */
1110    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1111
1112    /**
1113     * Set to true after the system has finished booting.
1114     */
1115    boolean mBooted = false;
1116
1117    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1118    int mProcessLimitOverride = -1;
1119
1120    WindowManagerService mWindowManager;
1121
1122    final ActivityThread mSystemThread;
1123
1124    // Holds the current foreground user's id
1125    int mCurrentUserId = 0;
1126    // Holds the target user's id during a user switch
1127    int mTargetUserId = UserHandle.USER_NULL;
1128    // If there are multiple profiles for the current user, their ids are here
1129    // Currently only the primary user can have managed profiles
1130    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1131
1132    /**
1133     * Mapping from each known user ID to the profile group ID it is associated with.
1134     */
1135    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1136
1137    private UserManagerService mUserManager;
1138
1139    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1140        final ProcessRecord mApp;
1141        final int mPid;
1142        final IApplicationThread mAppThread;
1143
1144        AppDeathRecipient(ProcessRecord app, int pid,
1145                IApplicationThread thread) {
1146            if (localLOGV) Slog.v(
1147                TAG, "New death recipient " + this
1148                + " for thread " + thread.asBinder());
1149            mApp = app;
1150            mPid = pid;
1151            mAppThread = thread;
1152        }
1153
1154        @Override
1155        public void binderDied() {
1156            if (localLOGV) Slog.v(
1157                TAG, "Death received in " + this
1158                + " for thread " + mAppThread.asBinder());
1159            synchronized(ActivityManagerService.this) {
1160                appDiedLocked(mApp, mPid, mAppThread);
1161            }
1162        }
1163    }
1164
1165    static final int SHOW_ERROR_MSG = 1;
1166    static final int SHOW_NOT_RESPONDING_MSG = 2;
1167    static final int SHOW_FACTORY_ERROR_MSG = 3;
1168    static final int UPDATE_CONFIGURATION_MSG = 4;
1169    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1170    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1171    static final int SERVICE_TIMEOUT_MSG = 12;
1172    static final int UPDATE_TIME_ZONE = 13;
1173    static final int SHOW_UID_ERROR_MSG = 14;
1174    static final int IM_FEELING_LUCKY_MSG = 15;
1175    static final int PROC_START_TIMEOUT_MSG = 20;
1176    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1177    static final int KILL_APPLICATION_MSG = 22;
1178    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1179    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1180    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1181    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1182    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1183    static final int CLEAR_DNS_CACHE_MSG = 28;
1184    static final int UPDATE_HTTP_PROXY_MSG = 29;
1185    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1186    static final int DISPATCH_PROCESSES_CHANGED = 31;
1187    static final int DISPATCH_PROCESS_DIED = 32;
1188    static final int REPORT_MEM_USAGE_MSG = 33;
1189    static final int REPORT_USER_SWITCH_MSG = 34;
1190    static final int CONTINUE_USER_SWITCH_MSG = 35;
1191    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1192    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1193    static final int PERSIST_URI_GRANTS_MSG = 38;
1194    static final int REQUEST_ALL_PSS_MSG = 39;
1195    static final int START_PROFILES_MSG = 40;
1196    static final int UPDATE_TIME = 41;
1197    static final int SYSTEM_USER_START_MSG = 42;
1198    static final int SYSTEM_USER_CURRENT_MSG = 43;
1199    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1200    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1201    static final int START_USER_SWITCH_MSG = 46;
1202
1203    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1204    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1205    static final int FIRST_COMPAT_MODE_MSG = 300;
1206    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1207
1208    AlertDialog mUidAlert;
1209    CompatModeDialog mCompatModeDialog;
1210    long mLastMemUsageReportTime = 0;
1211
1212    private LockToAppRequestDialog mLockToAppRequest;
1213
1214    /**
1215     * Flag whether the current user is a "monkey", i.e. whether
1216     * the UI is driven by a UI automation tool.
1217     */
1218    private boolean mUserIsMonkey;
1219
1220    /** Flag whether the device has a Recents UI */
1221    boolean mHasRecents;
1222
1223    /** The dimensions of the thumbnails in the Recents UI. */
1224    int mThumbnailWidth;
1225    int mThumbnailHeight;
1226
1227    final ServiceThread mHandlerThread;
1228    final MainHandler mHandler;
1229
1230    final class MainHandler extends Handler {
1231        public MainHandler(Looper looper) {
1232            super(looper, null, true);
1233        }
1234
1235        @Override
1236        public void handleMessage(Message msg) {
1237            switch (msg.what) {
1238            case SHOW_ERROR_MSG: {
1239                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1240                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1241                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1242                synchronized (ActivityManagerService.this) {
1243                    ProcessRecord proc = (ProcessRecord)data.get("app");
1244                    AppErrorResult res = (AppErrorResult) data.get("result");
1245                    if (proc != null && proc.crashDialog != null) {
1246                        Slog.e(TAG, "App already has crash dialog: " + proc);
1247                        if (res != null) {
1248                            res.set(0);
1249                        }
1250                        return;
1251                    }
1252                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1253                            >= Process.FIRST_APPLICATION_UID
1254                            && proc.pid != MY_PID);
1255                    for (int userId : mCurrentProfileIds) {
1256                        isBackground &= (proc.userId != userId);
1257                    }
1258                    if (isBackground && !showBackground) {
1259                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1260                        if (res != null) {
1261                            res.set(0);
1262                        }
1263                        return;
1264                    }
1265                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1266                        Dialog d = new AppErrorDialog(mContext,
1267                                ActivityManagerService.this, res, proc);
1268                        d.show();
1269                        proc.crashDialog = d;
1270                    } else {
1271                        // The device is asleep, so just pretend that the user
1272                        // saw a crash dialog and hit "force quit".
1273                        if (res != null) {
1274                            res.set(0);
1275                        }
1276                    }
1277                }
1278
1279                ensureBootCompleted();
1280            } break;
1281            case SHOW_NOT_RESPONDING_MSG: {
1282                synchronized (ActivityManagerService.this) {
1283                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1284                    ProcessRecord proc = (ProcessRecord)data.get("app");
1285                    if (proc != null && proc.anrDialog != null) {
1286                        Slog.e(TAG, "App already has anr dialog: " + proc);
1287                        return;
1288                    }
1289
1290                    Intent intent = new Intent("android.intent.action.ANR");
1291                    if (!mProcessesReady) {
1292                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1293                                | Intent.FLAG_RECEIVER_FOREGROUND);
1294                    }
1295                    broadcastIntentLocked(null, null, intent,
1296                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1297                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1298
1299                    if (mShowDialogs) {
1300                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1301                                mContext, proc, (ActivityRecord)data.get("activity"),
1302                                msg.arg1 != 0);
1303                        d.show();
1304                        proc.anrDialog = d;
1305                    } else {
1306                        // Just kill the app if there is no dialog to be shown.
1307                        killAppAtUsersRequest(proc, null);
1308                    }
1309                }
1310
1311                ensureBootCompleted();
1312            } break;
1313            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1314                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1315                synchronized (ActivityManagerService.this) {
1316                    ProcessRecord proc = (ProcessRecord) data.get("app");
1317                    if (proc == null) {
1318                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1319                        break;
1320                    }
1321                    if (proc.crashDialog != null) {
1322                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1323                        return;
1324                    }
1325                    AppErrorResult res = (AppErrorResult) data.get("result");
1326                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1327                        Dialog d = new StrictModeViolationDialog(mContext,
1328                                ActivityManagerService.this, res, proc);
1329                        d.show();
1330                        proc.crashDialog = d;
1331                    } else {
1332                        // The device is asleep, so just pretend that the user
1333                        // saw a crash dialog and hit "force quit".
1334                        res.set(0);
1335                    }
1336                }
1337                ensureBootCompleted();
1338            } break;
1339            case SHOW_FACTORY_ERROR_MSG: {
1340                Dialog d = new FactoryErrorDialog(
1341                    mContext, msg.getData().getCharSequence("msg"));
1342                d.show();
1343                ensureBootCompleted();
1344            } break;
1345            case UPDATE_CONFIGURATION_MSG: {
1346                final ContentResolver resolver = mContext.getContentResolver();
1347                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1348            } break;
1349            case GC_BACKGROUND_PROCESSES_MSG: {
1350                synchronized (ActivityManagerService.this) {
1351                    performAppGcsIfAppropriateLocked();
1352                }
1353            } break;
1354            case WAIT_FOR_DEBUGGER_MSG: {
1355                synchronized (ActivityManagerService.this) {
1356                    ProcessRecord app = (ProcessRecord)msg.obj;
1357                    if (msg.arg1 != 0) {
1358                        if (!app.waitedForDebugger) {
1359                            Dialog d = new AppWaitingForDebuggerDialog(
1360                                    ActivityManagerService.this,
1361                                    mContext, app);
1362                            app.waitDialog = d;
1363                            app.waitedForDebugger = true;
1364                            d.show();
1365                        }
1366                    } else {
1367                        if (app.waitDialog != null) {
1368                            app.waitDialog.dismiss();
1369                            app.waitDialog = null;
1370                        }
1371                    }
1372                }
1373            } break;
1374            case SERVICE_TIMEOUT_MSG: {
1375                if (mDidDexOpt) {
1376                    mDidDexOpt = false;
1377                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1378                    nmsg.obj = msg.obj;
1379                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1380                    return;
1381                }
1382                mServices.serviceTimeout((ProcessRecord)msg.obj);
1383            } break;
1384            case UPDATE_TIME_ZONE: {
1385                synchronized (ActivityManagerService.this) {
1386                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1387                        ProcessRecord r = mLruProcesses.get(i);
1388                        if (r.thread != null) {
1389                            try {
1390                                r.thread.updateTimeZone();
1391                            } catch (RemoteException ex) {
1392                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1393                            }
1394                        }
1395                    }
1396                }
1397            } break;
1398            case CLEAR_DNS_CACHE_MSG: {
1399                synchronized (ActivityManagerService.this) {
1400                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1401                        ProcessRecord r = mLruProcesses.get(i);
1402                        if (r.thread != null) {
1403                            try {
1404                                r.thread.clearDnsCache();
1405                            } catch (RemoteException ex) {
1406                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1407                            }
1408                        }
1409                    }
1410                }
1411            } break;
1412            case UPDATE_HTTP_PROXY_MSG: {
1413                ProxyInfo proxy = (ProxyInfo)msg.obj;
1414                String host = "";
1415                String port = "";
1416                String exclList = "";
1417                Uri pacFileUrl = Uri.EMPTY;
1418                if (proxy != null) {
1419                    host = proxy.getHost();
1420                    port = Integer.toString(proxy.getPort());
1421                    exclList = proxy.getExclusionListAsString();
1422                    pacFileUrl = proxy.getPacFileUrl();
1423                }
1424                synchronized (ActivityManagerService.this) {
1425                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1426                        ProcessRecord r = mLruProcesses.get(i);
1427                        if (r.thread != null) {
1428                            try {
1429                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1430                            } catch (RemoteException ex) {
1431                                Slog.w(TAG, "Failed to update http proxy for: " +
1432                                        r.info.processName);
1433                            }
1434                        }
1435                    }
1436                }
1437            } break;
1438            case SHOW_UID_ERROR_MSG: {
1439                String title = "System UIDs Inconsistent";
1440                String text = "UIDs on the system are inconsistent, you need to wipe your"
1441                        + " data partition or your device will be unstable.";
1442                Log.e(TAG, title + ": " + text);
1443                if (mShowDialogs) {
1444                    // XXX This is a temporary dialog, no need to localize.
1445                    AlertDialog d = new BaseErrorDialog(mContext);
1446                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1447                    d.setCancelable(false);
1448                    d.setTitle(title);
1449                    d.setMessage(text);
1450                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1451                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1452                    mUidAlert = d;
1453                    d.show();
1454                }
1455            } break;
1456            case IM_FEELING_LUCKY_MSG: {
1457                if (mUidAlert != null) {
1458                    mUidAlert.dismiss();
1459                    mUidAlert = null;
1460                }
1461            } break;
1462            case PROC_START_TIMEOUT_MSG: {
1463                if (mDidDexOpt) {
1464                    mDidDexOpt = false;
1465                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1466                    nmsg.obj = msg.obj;
1467                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1468                    return;
1469                }
1470                ProcessRecord app = (ProcessRecord)msg.obj;
1471                synchronized (ActivityManagerService.this) {
1472                    processStartTimedOutLocked(app);
1473                }
1474            } break;
1475            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1476                synchronized (ActivityManagerService.this) {
1477                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1478                }
1479            } break;
1480            case KILL_APPLICATION_MSG: {
1481                synchronized (ActivityManagerService.this) {
1482                    int appid = msg.arg1;
1483                    boolean restart = (msg.arg2 == 1);
1484                    Bundle bundle = (Bundle)msg.obj;
1485                    String pkg = bundle.getString("pkg");
1486                    String reason = bundle.getString("reason");
1487                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1488                            false, UserHandle.USER_ALL, reason);
1489                }
1490            } break;
1491            case FINALIZE_PENDING_INTENT_MSG: {
1492                ((PendingIntentRecord)msg.obj).completeFinalize();
1493            } break;
1494            case POST_HEAVY_NOTIFICATION_MSG: {
1495                INotificationManager inm = NotificationManager.getService();
1496                if (inm == null) {
1497                    return;
1498                }
1499
1500                ActivityRecord root = (ActivityRecord)msg.obj;
1501                ProcessRecord process = root.app;
1502                if (process == null) {
1503                    return;
1504                }
1505
1506                try {
1507                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1508                    String text = mContext.getString(R.string.heavy_weight_notification,
1509                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1510                    Notification notification = new Notification();
1511                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1512                    notification.when = 0;
1513                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1514                    notification.tickerText = text;
1515                    notification.defaults = 0; // please be quiet
1516                    notification.sound = null;
1517                    notification.vibrate = null;
1518                    notification.color = mContext.getResources().getColor(
1519                            com.android.internal.R.color.system_notification_accent_color);
1520                    notification.setLatestEventInfo(context, text,
1521                            mContext.getText(R.string.heavy_weight_notification_detail),
1522                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1523                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1524                                    new UserHandle(root.userId)));
1525
1526                    try {
1527                        int[] outId = new int[1];
1528                        inm.enqueueNotificationWithTag("android", "android", null,
1529                                R.string.heavy_weight_notification,
1530                                notification, outId, root.userId);
1531                    } catch (RuntimeException e) {
1532                        Slog.w(ActivityManagerService.TAG,
1533                                "Error showing notification for heavy-weight app", e);
1534                    } catch (RemoteException e) {
1535                    }
1536                } catch (NameNotFoundException e) {
1537                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1538                }
1539            } break;
1540            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1541                INotificationManager inm = NotificationManager.getService();
1542                if (inm == null) {
1543                    return;
1544                }
1545                try {
1546                    inm.cancelNotificationWithTag("android", null,
1547                            R.string.heavy_weight_notification,  msg.arg1);
1548                } catch (RuntimeException e) {
1549                    Slog.w(ActivityManagerService.TAG,
1550                            "Error canceling notification for service", e);
1551                } catch (RemoteException e) {
1552                }
1553            } break;
1554            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1555                synchronized (ActivityManagerService.this) {
1556                    checkExcessivePowerUsageLocked(true);
1557                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1558                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1559                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1560                }
1561            } break;
1562            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1563                synchronized (ActivityManagerService.this) {
1564                    ActivityRecord ar = (ActivityRecord)msg.obj;
1565                    if (mCompatModeDialog != null) {
1566                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1567                                ar.info.applicationInfo.packageName)) {
1568                            return;
1569                        }
1570                        mCompatModeDialog.dismiss();
1571                        mCompatModeDialog = null;
1572                    }
1573                    if (ar != null && false) {
1574                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1575                                ar.packageName)) {
1576                            int mode = mCompatModePackages.computeCompatModeLocked(
1577                                    ar.info.applicationInfo);
1578                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1579                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1580                                mCompatModeDialog = new CompatModeDialog(
1581                                        ActivityManagerService.this, mContext,
1582                                        ar.info.applicationInfo);
1583                                mCompatModeDialog.show();
1584                            }
1585                        }
1586                    }
1587                }
1588                break;
1589            }
1590            case DISPATCH_PROCESSES_CHANGED: {
1591                dispatchProcessesChanged();
1592                break;
1593            }
1594            case DISPATCH_PROCESS_DIED: {
1595                final int pid = msg.arg1;
1596                final int uid = msg.arg2;
1597                dispatchProcessDied(pid, uid);
1598                break;
1599            }
1600            case REPORT_MEM_USAGE_MSG: {
1601                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1602                Thread thread = new Thread() {
1603                    @Override public void run() {
1604                        final SparseArray<ProcessMemInfo> infoMap
1605                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1606                        for (int i=0, N=memInfos.size(); i<N; i++) {
1607                            ProcessMemInfo mi = memInfos.get(i);
1608                            infoMap.put(mi.pid, mi);
1609                        }
1610                        updateCpuStatsNow();
1611                        synchronized (mProcessCpuTracker) {
1612                            final int N = mProcessCpuTracker.countStats();
1613                            for (int i=0; i<N; i++) {
1614                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1615                                if (st.vsize > 0) {
1616                                    long pss = Debug.getPss(st.pid, null);
1617                                    if (pss > 0) {
1618                                        if (infoMap.indexOfKey(st.pid) < 0) {
1619                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1620                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1621                                            mi.pss = pss;
1622                                            memInfos.add(mi);
1623                                        }
1624                                    }
1625                                }
1626                            }
1627                        }
1628
1629                        long totalPss = 0;
1630                        for (int i=0, N=memInfos.size(); i<N; i++) {
1631                            ProcessMemInfo mi = memInfos.get(i);
1632                            if (mi.pss == 0) {
1633                                mi.pss = Debug.getPss(mi.pid, null);
1634                            }
1635                            totalPss += mi.pss;
1636                        }
1637                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1638                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1639                                if (lhs.oomAdj != rhs.oomAdj) {
1640                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1641                                }
1642                                if (lhs.pss != rhs.pss) {
1643                                    return lhs.pss < rhs.pss ? 1 : -1;
1644                                }
1645                                return 0;
1646                            }
1647                        });
1648
1649                        StringBuilder tag = new StringBuilder(128);
1650                        StringBuilder stack = new StringBuilder(128);
1651                        tag.append("Low on memory -- ");
1652                        appendMemBucket(tag, totalPss, "total", false);
1653                        appendMemBucket(stack, totalPss, "total", true);
1654
1655                        StringBuilder logBuilder = new StringBuilder(1024);
1656                        logBuilder.append("Low on memory:\n");
1657
1658                        boolean firstLine = true;
1659                        int lastOomAdj = Integer.MIN_VALUE;
1660                        for (int i=0, N=memInfos.size(); i<N; i++) {
1661                            ProcessMemInfo mi = memInfos.get(i);
1662
1663                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1664                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1665                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1666                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1667                                if (lastOomAdj != mi.oomAdj) {
1668                                    lastOomAdj = mi.oomAdj;
1669                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1670                                        tag.append(" / ");
1671                                    }
1672                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1673                                        if (firstLine) {
1674                                            stack.append(":");
1675                                            firstLine = false;
1676                                        }
1677                                        stack.append("\n\t at ");
1678                                    } else {
1679                                        stack.append("$");
1680                                    }
1681                                } else {
1682                                    tag.append(" ");
1683                                    stack.append("$");
1684                                }
1685                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1686                                    appendMemBucket(tag, mi.pss, mi.name, false);
1687                                }
1688                                appendMemBucket(stack, mi.pss, mi.name, true);
1689                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1690                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1691                                    stack.append("(");
1692                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1693                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1694                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1695                                            stack.append(":");
1696                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1697                                        }
1698                                    }
1699                                    stack.append(")");
1700                                }
1701                            }
1702
1703                            logBuilder.append("  ");
1704                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1705                            logBuilder.append(' ');
1706                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1707                            logBuilder.append(' ');
1708                            ProcessList.appendRamKb(logBuilder, mi.pss);
1709                            logBuilder.append(" kB: ");
1710                            logBuilder.append(mi.name);
1711                            logBuilder.append(" (");
1712                            logBuilder.append(mi.pid);
1713                            logBuilder.append(") ");
1714                            logBuilder.append(mi.adjType);
1715                            logBuilder.append('\n');
1716                            if (mi.adjReason != null) {
1717                                logBuilder.append("                      ");
1718                                logBuilder.append(mi.adjReason);
1719                                logBuilder.append('\n');
1720                            }
1721                        }
1722
1723                        logBuilder.append("           ");
1724                        ProcessList.appendRamKb(logBuilder, totalPss);
1725                        logBuilder.append(" kB: TOTAL\n");
1726
1727                        long[] infos = new long[Debug.MEMINFO_COUNT];
1728                        Debug.getMemInfo(infos);
1729                        logBuilder.append("  MemInfo: ");
1730                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1731                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1732                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1733                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1734                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1735                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1736                            logBuilder.append("  ZRAM: ");
1737                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1738                            logBuilder.append(" kB RAM, ");
1739                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1740                            logBuilder.append(" kB swap total, ");
1741                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1742                            logBuilder.append(" kB swap free\n");
1743                        }
1744                        Slog.i(TAG, logBuilder.toString());
1745
1746                        StringBuilder dropBuilder = new StringBuilder(1024);
1747                        /*
1748                        StringWriter oomSw = new StringWriter();
1749                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1750                        StringWriter catSw = new StringWriter();
1751                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1752                        String[] emptyArgs = new String[] { };
1753                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1754                        oomPw.flush();
1755                        String oomString = oomSw.toString();
1756                        */
1757                        dropBuilder.append(stack);
1758                        dropBuilder.append('\n');
1759                        dropBuilder.append('\n');
1760                        dropBuilder.append(logBuilder);
1761                        dropBuilder.append('\n');
1762                        /*
1763                        dropBuilder.append(oomString);
1764                        dropBuilder.append('\n');
1765                        */
1766                        StringWriter catSw = new StringWriter();
1767                        synchronized (ActivityManagerService.this) {
1768                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1769                            String[] emptyArgs = new String[] { };
1770                            catPw.println();
1771                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1772                            catPw.println();
1773                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1774                                    false, false, null);
1775                            catPw.println();
1776                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1777                            catPw.flush();
1778                        }
1779                        dropBuilder.append(catSw.toString());
1780                        addErrorToDropBox("lowmem", null, "system_server", null,
1781                                null, tag.toString(), dropBuilder.toString(), null, null);
1782                        //Slog.i(TAG, "Sent to dropbox:");
1783                        //Slog.i(TAG, dropBuilder.toString());
1784                        synchronized (ActivityManagerService.this) {
1785                            long now = SystemClock.uptimeMillis();
1786                            if (mLastMemUsageReportTime < now) {
1787                                mLastMemUsageReportTime = now;
1788                            }
1789                        }
1790                    }
1791                };
1792                thread.start();
1793                break;
1794            }
1795            case START_USER_SWITCH_MSG: {
1796                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1797                break;
1798            }
1799            case REPORT_USER_SWITCH_MSG: {
1800                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1801                break;
1802            }
1803            case CONTINUE_USER_SWITCH_MSG: {
1804                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1805                break;
1806            }
1807            case USER_SWITCH_TIMEOUT_MSG: {
1808                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1809                break;
1810            }
1811            case IMMERSIVE_MODE_LOCK_MSG: {
1812                final boolean nextState = (msg.arg1 != 0);
1813                if (mUpdateLock.isHeld() != nextState) {
1814                    if (DEBUG_IMMERSIVE) {
1815                        final ActivityRecord r = (ActivityRecord) msg.obj;
1816                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1817                    }
1818                    if (nextState) {
1819                        mUpdateLock.acquire();
1820                    } else {
1821                        mUpdateLock.release();
1822                    }
1823                }
1824                break;
1825            }
1826            case PERSIST_URI_GRANTS_MSG: {
1827                writeGrantedUriPermissions();
1828                break;
1829            }
1830            case REQUEST_ALL_PSS_MSG: {
1831                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1832                break;
1833            }
1834            case START_PROFILES_MSG: {
1835                synchronized (ActivityManagerService.this) {
1836                    startProfilesLocked();
1837                }
1838                break;
1839            }
1840            case UPDATE_TIME: {
1841                synchronized (ActivityManagerService.this) {
1842                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1843                        ProcessRecord r = mLruProcesses.get(i);
1844                        if (r.thread != null) {
1845                            try {
1846                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1847                            } catch (RemoteException ex) {
1848                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1849                            }
1850                        }
1851                    }
1852                }
1853                break;
1854            }
1855            case SYSTEM_USER_START_MSG: {
1856                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1857                        Integer.toString(msg.arg1), msg.arg1);
1858                mSystemServiceManager.startUser(msg.arg1);
1859                break;
1860            }
1861            case SYSTEM_USER_CURRENT_MSG: {
1862                mBatteryStatsService.noteEvent(
1863                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1864                        Integer.toString(msg.arg2), msg.arg2);
1865                mBatteryStatsService.noteEvent(
1866                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1867                        Integer.toString(msg.arg1), msg.arg1);
1868                mSystemServiceManager.switchUser(msg.arg1);
1869                mLockToAppRequest.clearPrompt();
1870                break;
1871            }
1872            case ENTER_ANIMATION_COMPLETE_MSG: {
1873                synchronized (ActivityManagerService.this) {
1874                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1875                    if (r != null && r.app != null && r.app.thread != null) {
1876                        try {
1877                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1878                        } catch (RemoteException e) {
1879                        }
1880                    }
1881                }
1882                break;
1883            }
1884            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1885                enableScreenAfterBoot();
1886                break;
1887            }
1888            }
1889        }
1890    };
1891
1892    static final int COLLECT_PSS_BG_MSG = 1;
1893
1894    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1895        @Override
1896        public void handleMessage(Message msg) {
1897            switch (msg.what) {
1898            case COLLECT_PSS_BG_MSG: {
1899                long start = SystemClock.uptimeMillis();
1900                MemInfoReader memInfo = null;
1901                synchronized (ActivityManagerService.this) {
1902                    if (mFullPssPending) {
1903                        mFullPssPending = false;
1904                        memInfo = new MemInfoReader();
1905                    }
1906                }
1907                if (memInfo != null) {
1908                    updateCpuStatsNow();
1909                    long nativeTotalPss = 0;
1910                    synchronized (mProcessCpuTracker) {
1911                        final int N = mProcessCpuTracker.countStats();
1912                        for (int j=0; j<N; j++) {
1913                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1914                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1915                                // This is definitely an application process; skip it.
1916                                continue;
1917                            }
1918                            synchronized (mPidsSelfLocked) {
1919                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1920                                    // This is one of our own processes; skip it.
1921                                    continue;
1922                                }
1923                            }
1924                            nativeTotalPss += Debug.getPss(st.pid, null);
1925                        }
1926                    }
1927                    memInfo.readMemInfo();
1928                    synchronized (ActivityManagerService.this) {
1929                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1930                                + (SystemClock.uptimeMillis()-start) + "ms");
1931                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1932                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1933                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1934                                        +memInfo.getSlabSizeKb(),
1935                                nativeTotalPss);
1936                    }
1937                }
1938
1939                int i=0, num=0;
1940                long[] tmp = new long[1];
1941                do {
1942                    ProcessRecord proc;
1943                    int procState;
1944                    int pid;
1945                    synchronized (ActivityManagerService.this) {
1946                        if (i >= mPendingPssProcesses.size()) {
1947                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1948                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1949                            mPendingPssProcesses.clear();
1950                            return;
1951                        }
1952                        proc = mPendingPssProcesses.get(i);
1953                        procState = proc.pssProcState;
1954                        if (proc.thread != null && procState == proc.setProcState) {
1955                            pid = proc.pid;
1956                        } else {
1957                            proc = null;
1958                            pid = 0;
1959                        }
1960                        i++;
1961                    }
1962                    if (proc != null) {
1963                        long pss = Debug.getPss(pid, tmp);
1964                        synchronized (ActivityManagerService.this) {
1965                            if (proc.thread != null && proc.setProcState == procState
1966                                    && proc.pid == pid) {
1967                                num++;
1968                                proc.lastPssTime = SystemClock.uptimeMillis();
1969                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1970                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1971                                        + ": " + pss + " lastPss=" + proc.lastPss
1972                                        + " state=" + ProcessList.makeProcStateString(procState));
1973                                if (proc.initialIdlePss == 0) {
1974                                    proc.initialIdlePss = pss;
1975                                }
1976                                proc.lastPss = pss;
1977                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1978                                    proc.lastCachedPss = pss;
1979                                }
1980                            }
1981                        }
1982                    }
1983                } while (true);
1984            }
1985            }
1986        }
1987    };
1988
1989    /**
1990     * Monitor for package changes and update our internal state.
1991     */
1992    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1993        @Override
1994        public void onPackageRemoved(String packageName, int uid) {
1995            // Remove all tasks with activities in the specified package from the list of recent tasks
1996            synchronized (ActivityManagerService.this) {
1997                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1998                    TaskRecord tr = mRecentTasks.get(i);
1999                    ComponentName cn = tr.intent.getComponent();
2000                    if (cn != null && cn.getPackageName().equals(packageName)) {
2001                        // If the package name matches, remove the task and kill the process
2002                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
2003                    }
2004                }
2005            }
2006        }
2007
2008        @Override
2009        public boolean onPackageChanged(String packageName, int uid, String[] components) {
2010            onPackageModified(packageName);
2011            return true;
2012        }
2013
2014        @Override
2015        public void onPackageModified(String packageName) {
2016            final PackageManager pm = mContext.getPackageManager();
2017            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2018                    new ArrayList<Pair<Intent, Integer>>();
2019            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2020            // Copy the list of recent tasks so that we don't hold onto the lock on
2021            // ActivityManagerService for long periods while checking if components exist.
2022            synchronized (ActivityManagerService.this) {
2023                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2024                    TaskRecord tr = mRecentTasks.get(i);
2025                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2026                }
2027            }
2028            // Check the recent tasks and filter out all tasks with components that no longer exist.
2029            Intent tmpI = new Intent();
2030            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2031                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2032                ComponentName cn = p.first.getComponent();
2033                if (cn != null && cn.getPackageName().equals(packageName)) {
2034                    try {
2035                        // Add the task to the list to remove if the component no longer exists
2036                        tmpI.setComponent(cn);
2037                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
2038                            tasksToRemove.add(p.second);
2039                        }
2040                    } catch (Exception e) {}
2041                }
2042            }
2043            // Prune all the tasks with removed components from the list of recent tasks
2044            synchronized (ActivityManagerService.this) {
2045                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2046                    // Remove the task but don't kill the process (since other components in that
2047                    // package may still be running and in the background)
2048                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2049                }
2050            }
2051        }
2052
2053        @Override
2054        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2055            // Force stop the specified packages
2056            if (packages != null) {
2057                for (String pkg : packages) {
2058                    synchronized (ActivityManagerService.this) {
2059                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2060                                "finished booting")) {
2061                            return true;
2062                        }
2063                    }
2064                }
2065            }
2066            return false;
2067        }
2068    };
2069
2070    public void setSystemProcess() {
2071        try {
2072            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2073            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2074            ServiceManager.addService("meminfo", new MemBinder(this));
2075            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2076            ServiceManager.addService("dbinfo", new DbBinder(this));
2077            if (MONITOR_CPU_USAGE) {
2078                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2079            }
2080            ServiceManager.addService("permission", new PermissionController(this));
2081
2082            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2083                    "android", STOCK_PM_FLAGS);
2084            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2085
2086            synchronized (this) {
2087                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2088                app.persistent = true;
2089                app.pid = MY_PID;
2090                app.maxAdj = ProcessList.SYSTEM_ADJ;
2091                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2092                mProcessNames.put(app.processName, app.uid, app);
2093                synchronized (mPidsSelfLocked) {
2094                    mPidsSelfLocked.put(app.pid, app);
2095                }
2096                updateLruProcessLocked(app, false, null);
2097                updateOomAdjLocked();
2098            }
2099        } catch (PackageManager.NameNotFoundException e) {
2100            throw new RuntimeException(
2101                    "Unable to find android system package", e);
2102        }
2103    }
2104
2105    public void setWindowManager(WindowManagerService wm) {
2106        mWindowManager = wm;
2107        mStackSupervisor.setWindowManager(wm);
2108    }
2109
2110    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2111        mUsageStatsService = usageStatsManager;
2112    }
2113
2114    public void startObservingNativeCrashes() {
2115        final NativeCrashListener ncl = new NativeCrashListener(this);
2116        ncl.start();
2117    }
2118
2119    public IAppOpsService getAppOpsService() {
2120        return mAppOpsService;
2121    }
2122
2123    static class MemBinder extends Binder {
2124        ActivityManagerService mActivityManagerService;
2125        MemBinder(ActivityManagerService activityManagerService) {
2126            mActivityManagerService = activityManagerService;
2127        }
2128
2129        @Override
2130        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2131            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2132                    != PackageManager.PERMISSION_GRANTED) {
2133                pw.println("Permission Denial: can't dump meminfo from from pid="
2134                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2135                        + " without permission " + android.Manifest.permission.DUMP);
2136                return;
2137            }
2138
2139            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2140        }
2141    }
2142
2143    static class GraphicsBinder extends Binder {
2144        ActivityManagerService mActivityManagerService;
2145        GraphicsBinder(ActivityManagerService activityManagerService) {
2146            mActivityManagerService = activityManagerService;
2147        }
2148
2149        @Override
2150        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2151            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2152                    != PackageManager.PERMISSION_GRANTED) {
2153                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2154                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2155                        + " without permission " + android.Manifest.permission.DUMP);
2156                return;
2157            }
2158
2159            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2160        }
2161    }
2162
2163    static class DbBinder extends Binder {
2164        ActivityManagerService mActivityManagerService;
2165        DbBinder(ActivityManagerService activityManagerService) {
2166            mActivityManagerService = activityManagerService;
2167        }
2168
2169        @Override
2170        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2171            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2172                    != PackageManager.PERMISSION_GRANTED) {
2173                pw.println("Permission Denial: can't dump dbinfo from from pid="
2174                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2175                        + " without permission " + android.Manifest.permission.DUMP);
2176                return;
2177            }
2178
2179            mActivityManagerService.dumpDbInfo(fd, pw, args);
2180        }
2181    }
2182
2183    static class CpuBinder extends Binder {
2184        ActivityManagerService mActivityManagerService;
2185        CpuBinder(ActivityManagerService activityManagerService) {
2186            mActivityManagerService = activityManagerService;
2187        }
2188
2189        @Override
2190        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2191            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2192                    != PackageManager.PERMISSION_GRANTED) {
2193                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2194                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2195                        + " without permission " + android.Manifest.permission.DUMP);
2196                return;
2197            }
2198
2199            synchronized (mActivityManagerService.mProcessCpuTracker) {
2200                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2201                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2202                        SystemClock.uptimeMillis()));
2203            }
2204        }
2205    }
2206
2207    public static final class Lifecycle extends SystemService {
2208        private final ActivityManagerService mService;
2209
2210        public Lifecycle(Context context) {
2211            super(context);
2212            mService = new ActivityManagerService(context);
2213        }
2214
2215        @Override
2216        public void onStart() {
2217            mService.start();
2218        }
2219
2220        public ActivityManagerService getService() {
2221            return mService;
2222        }
2223    }
2224
2225    // Note: This method is invoked on the main thread but may need to attach various
2226    // handlers to other threads.  So take care to be explicit about the looper.
2227    public ActivityManagerService(Context systemContext) {
2228        mContext = systemContext;
2229        mFactoryTest = FactoryTest.getMode();
2230        mSystemThread = ActivityThread.currentActivityThread();
2231
2232        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2233
2234        mHandlerThread = new ServiceThread(TAG,
2235                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2236        mHandlerThread.start();
2237        mHandler = new MainHandler(mHandlerThread.getLooper());
2238
2239        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2240                "foreground", BROADCAST_FG_TIMEOUT, false);
2241        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2242                "background", BROADCAST_BG_TIMEOUT, true);
2243        mBroadcastQueues[0] = mFgBroadcastQueue;
2244        mBroadcastQueues[1] = mBgBroadcastQueue;
2245
2246        mServices = new ActiveServices(this);
2247        mProviderMap = new ProviderMap(this);
2248
2249        // TODO: Move creation of battery stats service outside of activity manager service.
2250        File dataDir = Environment.getDataDirectory();
2251        File systemDir = new File(dataDir, "system");
2252        systemDir.mkdirs();
2253        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2254        mBatteryStatsService.getActiveStatistics().readLocked();
2255        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2256        mOnBattery = DEBUG_POWER ? true
2257                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2258        mBatteryStatsService.getActiveStatistics().setCallback(this);
2259
2260        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2261
2262        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2263
2264        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2265
2266        // User 0 is the first and only user that runs at boot.
2267        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2268        mUserLru.add(Integer.valueOf(0));
2269        updateStartedUserArrayLocked();
2270
2271        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2272            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2273
2274        mConfiguration.setToDefaults();
2275        mConfiguration.setLocale(Locale.getDefault());
2276
2277        mConfigurationSeq = mConfiguration.seq = 1;
2278        mProcessCpuTracker.init();
2279
2280        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2281        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2282        mStackSupervisor = new ActivityStackSupervisor(this);
2283        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2284
2285        mProcessCpuThread = new Thread("CpuTracker") {
2286            @Override
2287            public void run() {
2288                while (true) {
2289                    try {
2290                        try {
2291                            synchronized(this) {
2292                                final long now = SystemClock.uptimeMillis();
2293                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2294                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2295                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2296                                //        + ", write delay=" + nextWriteDelay);
2297                                if (nextWriteDelay < nextCpuDelay) {
2298                                    nextCpuDelay = nextWriteDelay;
2299                                }
2300                                if (nextCpuDelay > 0) {
2301                                    mProcessCpuMutexFree.set(true);
2302                                    this.wait(nextCpuDelay);
2303                                }
2304                            }
2305                        } catch (InterruptedException e) {
2306                        }
2307                        updateCpuStatsNow();
2308                    } catch (Exception e) {
2309                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2310                    }
2311                }
2312            }
2313        };
2314
2315        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2316
2317        Watchdog.getInstance().addMonitor(this);
2318        Watchdog.getInstance().addThread(mHandler);
2319    }
2320
2321    public void setSystemServiceManager(SystemServiceManager mgr) {
2322        mSystemServiceManager = mgr;
2323    }
2324
2325    private void start() {
2326        Process.removeAllProcessGroups();
2327        mProcessCpuThread.start();
2328
2329        mBatteryStatsService.publish(mContext);
2330        mAppOpsService.publish(mContext);
2331        Slog.d("AppOps", "AppOpsService published");
2332        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2333    }
2334
2335    public void initPowerManagement() {
2336        mStackSupervisor.initPowerManagement();
2337        mBatteryStatsService.initPowerManagement();
2338    }
2339
2340    @Override
2341    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2342            throws RemoteException {
2343        if (code == SYSPROPS_TRANSACTION) {
2344            // We need to tell all apps about the system property change.
2345            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2346            synchronized(this) {
2347                final int NP = mProcessNames.getMap().size();
2348                for (int ip=0; ip<NP; ip++) {
2349                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2350                    final int NA = apps.size();
2351                    for (int ia=0; ia<NA; ia++) {
2352                        ProcessRecord app = apps.valueAt(ia);
2353                        if (app.thread != null) {
2354                            procs.add(app.thread.asBinder());
2355                        }
2356                    }
2357                }
2358            }
2359
2360            int N = procs.size();
2361            for (int i=0; i<N; i++) {
2362                Parcel data2 = Parcel.obtain();
2363                try {
2364                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2365                } catch (RemoteException e) {
2366                }
2367                data2.recycle();
2368            }
2369        }
2370        try {
2371            return super.onTransact(code, data, reply, flags);
2372        } catch (RuntimeException e) {
2373            // The activity manager only throws security exceptions, so let's
2374            // log all others.
2375            if (!(e instanceof SecurityException)) {
2376                Slog.wtf(TAG, "Activity Manager Crash", e);
2377            }
2378            throw e;
2379        }
2380    }
2381
2382    void updateCpuStats() {
2383        final long now = SystemClock.uptimeMillis();
2384        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2385            return;
2386        }
2387        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2388            synchronized (mProcessCpuThread) {
2389                mProcessCpuThread.notify();
2390            }
2391        }
2392    }
2393
2394    void updateCpuStatsNow() {
2395        synchronized (mProcessCpuTracker) {
2396            mProcessCpuMutexFree.set(false);
2397            final long now = SystemClock.uptimeMillis();
2398            boolean haveNewCpuStats = false;
2399
2400            if (MONITOR_CPU_USAGE &&
2401                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2402                mLastCpuTime.set(now);
2403                haveNewCpuStats = true;
2404                mProcessCpuTracker.update();
2405                //Slog.i(TAG, mProcessCpu.printCurrentState());
2406                //Slog.i(TAG, "Total CPU usage: "
2407                //        + mProcessCpu.getTotalCpuPercent() + "%");
2408
2409                // Slog the cpu usage if the property is set.
2410                if ("true".equals(SystemProperties.get("events.cpu"))) {
2411                    int user = mProcessCpuTracker.getLastUserTime();
2412                    int system = mProcessCpuTracker.getLastSystemTime();
2413                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2414                    int irq = mProcessCpuTracker.getLastIrqTime();
2415                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2416                    int idle = mProcessCpuTracker.getLastIdleTime();
2417
2418                    int total = user + system + iowait + irq + softIrq + idle;
2419                    if (total == 0) total = 1;
2420
2421                    EventLog.writeEvent(EventLogTags.CPU,
2422                            ((user+system+iowait+irq+softIrq) * 100) / total,
2423                            (user * 100) / total,
2424                            (system * 100) / total,
2425                            (iowait * 100) / total,
2426                            (irq * 100) / total,
2427                            (softIrq * 100) / total);
2428                }
2429            }
2430
2431            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2432            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2433            synchronized(bstats) {
2434                synchronized(mPidsSelfLocked) {
2435                    if (haveNewCpuStats) {
2436                        if (mOnBattery) {
2437                            int perc = bstats.startAddingCpuLocked();
2438                            int totalUTime = 0;
2439                            int totalSTime = 0;
2440                            final int N = mProcessCpuTracker.countStats();
2441                            for (int i=0; i<N; i++) {
2442                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2443                                if (!st.working) {
2444                                    continue;
2445                                }
2446                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2447                                int otherUTime = (st.rel_utime*perc)/100;
2448                                int otherSTime = (st.rel_stime*perc)/100;
2449                                totalUTime += otherUTime;
2450                                totalSTime += otherSTime;
2451                                if (pr != null) {
2452                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2453                                    if (ps == null || !ps.isActive()) {
2454                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2455                                                pr.info.uid, pr.processName);
2456                                    }
2457                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2458                                            st.rel_stime-otherSTime);
2459                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2460                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2461                                } else {
2462                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2463                                    if (ps == null || !ps.isActive()) {
2464                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2465                                                bstats.mapUid(st.uid), st.name);
2466                                    }
2467                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2468                                            st.rel_stime-otherSTime);
2469                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2470                                }
2471                            }
2472                            bstats.finishAddingCpuLocked(perc, totalUTime,
2473                                    totalSTime, cpuSpeedTimes);
2474                        }
2475                    }
2476                }
2477
2478                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2479                    mLastWriteTime = now;
2480                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2481                }
2482            }
2483        }
2484    }
2485
2486    @Override
2487    public void batteryNeedsCpuUpdate() {
2488        updateCpuStatsNow();
2489    }
2490
2491    @Override
2492    public void batteryPowerChanged(boolean onBattery) {
2493        // When plugging in, update the CPU stats first before changing
2494        // the plug state.
2495        updateCpuStatsNow();
2496        synchronized (this) {
2497            synchronized(mPidsSelfLocked) {
2498                mOnBattery = DEBUG_POWER ? true : onBattery;
2499            }
2500        }
2501    }
2502
2503    /**
2504     * Initialize the application bind args. These are passed to each
2505     * process when the bindApplication() IPC is sent to the process. They're
2506     * lazily setup to make sure the services are running when they're asked for.
2507     */
2508    private HashMap<String, IBinder> getCommonServicesLocked() {
2509        if (mAppBindArgs == null) {
2510            mAppBindArgs = new HashMap<String, IBinder>();
2511
2512            // Setup the application init args
2513            mAppBindArgs.put("package", ServiceManager.getService("package"));
2514            mAppBindArgs.put("window", ServiceManager.getService("window"));
2515            mAppBindArgs.put(Context.ALARM_SERVICE,
2516                    ServiceManager.getService(Context.ALARM_SERVICE));
2517        }
2518        return mAppBindArgs;
2519    }
2520
2521    final void setFocusedActivityLocked(ActivityRecord r) {
2522        if (mFocusedActivity != r) {
2523            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2524            mFocusedActivity = r;
2525            if (r.task != null && r.task.voiceInteractor != null) {
2526                startRunningVoiceLocked();
2527            } else {
2528                finishRunningVoiceLocked();
2529            }
2530            mStackSupervisor.setFocusedStack(r);
2531            if (r != null) {
2532                mWindowManager.setFocusedApp(r.appToken, true);
2533            }
2534            applyUpdateLockStateLocked(r);
2535        }
2536    }
2537
2538    final void clearFocusedActivity(ActivityRecord r) {
2539        if (mFocusedActivity == r) {
2540            mFocusedActivity = null;
2541        }
2542    }
2543
2544    @Override
2545    public void setFocusedStack(int stackId) {
2546        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2547        synchronized (ActivityManagerService.this) {
2548            ActivityStack stack = mStackSupervisor.getStack(stackId);
2549            if (stack != null) {
2550                ActivityRecord r = stack.topRunningActivityLocked(null);
2551                if (r != null) {
2552                    setFocusedActivityLocked(r);
2553                }
2554            }
2555        }
2556    }
2557
2558    @Override
2559    public void notifyActivityDrawn(IBinder token) {
2560        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2561        synchronized (this) {
2562            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2563            if (r != null) {
2564                r.task.stack.notifyActivityDrawnLocked(r);
2565            }
2566        }
2567    }
2568
2569    final void applyUpdateLockStateLocked(ActivityRecord r) {
2570        // Modifications to the UpdateLock state are done on our handler, outside
2571        // the activity manager's locks.  The new state is determined based on the
2572        // state *now* of the relevant activity record.  The object is passed to
2573        // the handler solely for logging detail, not to be consulted/modified.
2574        final boolean nextState = r != null && r.immersive;
2575        mHandler.sendMessage(
2576                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2577    }
2578
2579    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2580        Message msg = Message.obtain();
2581        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2582        msg.obj = r.task.askedCompatMode ? null : r;
2583        mHandler.sendMessage(msg);
2584    }
2585
2586    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2587            String what, Object obj, ProcessRecord srcApp) {
2588        app.lastActivityTime = now;
2589
2590        if (app.activities.size() > 0) {
2591            // Don't want to touch dependent processes that are hosting activities.
2592            return index;
2593        }
2594
2595        int lrui = mLruProcesses.lastIndexOf(app);
2596        if (lrui < 0) {
2597            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2598                    + what + " " + obj + " from " + srcApp);
2599            return index;
2600        }
2601
2602        if (lrui >= index) {
2603            // Don't want to cause this to move dependent processes *back* in the
2604            // list as if they were less frequently used.
2605            return index;
2606        }
2607
2608        if (lrui >= mLruProcessActivityStart) {
2609            // Don't want to touch dependent processes that are hosting activities.
2610            return index;
2611        }
2612
2613        mLruProcesses.remove(lrui);
2614        if (index > 0) {
2615            index--;
2616        }
2617        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2618                + " in LRU list: " + app);
2619        mLruProcesses.add(index, app);
2620        return index;
2621    }
2622
2623    final void removeLruProcessLocked(ProcessRecord app) {
2624        int lrui = mLruProcesses.lastIndexOf(app);
2625        if (lrui >= 0) {
2626            if (!app.killed) {
2627                Slog.wtf(TAG, "Removing process that hasn't been killed: " + app);
2628                Process.killProcessQuiet(app.pid);
2629                Process.killProcessGroup(app.info.uid, app.pid);
2630            }
2631            if (lrui <= mLruProcessActivityStart) {
2632                mLruProcessActivityStart--;
2633            }
2634            if (lrui <= mLruProcessServiceStart) {
2635                mLruProcessServiceStart--;
2636            }
2637            mLruProcesses.remove(lrui);
2638        }
2639    }
2640
2641    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2642            ProcessRecord client) {
2643        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2644                || app.treatLikeActivity;
2645        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2646        if (!activityChange && hasActivity) {
2647            // The process has activities, so we are only allowing activity-based adjustments
2648            // to move it.  It should be kept in the front of the list with other
2649            // processes that have activities, and we don't want those to change their
2650            // order except due to activity operations.
2651            return;
2652        }
2653
2654        mLruSeq++;
2655        final long now = SystemClock.uptimeMillis();
2656        app.lastActivityTime = now;
2657
2658        // First a quick reject: if the app is already at the position we will
2659        // put it, then there is nothing to do.
2660        if (hasActivity) {
2661            final int N = mLruProcesses.size();
2662            if (N > 0 && mLruProcesses.get(N-1) == app) {
2663                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2664                return;
2665            }
2666        } else {
2667            if (mLruProcessServiceStart > 0
2668                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2669                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2670                return;
2671            }
2672        }
2673
2674        int lrui = mLruProcesses.lastIndexOf(app);
2675
2676        if (app.persistent && lrui >= 0) {
2677            // We don't care about the position of persistent processes, as long as
2678            // they are in the list.
2679            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2680            return;
2681        }
2682
2683        /* In progress: compute new position first, so we can avoid doing work
2684           if the process is not actually going to move.  Not yet working.
2685        int addIndex;
2686        int nextIndex;
2687        boolean inActivity = false, inService = false;
2688        if (hasActivity) {
2689            // Process has activities, put it at the very tipsy-top.
2690            addIndex = mLruProcesses.size();
2691            nextIndex = mLruProcessServiceStart;
2692            inActivity = true;
2693        } else if (hasService) {
2694            // Process has services, put it at the top of the service list.
2695            addIndex = mLruProcessActivityStart;
2696            nextIndex = mLruProcessServiceStart;
2697            inActivity = true;
2698            inService = true;
2699        } else  {
2700            // Process not otherwise of interest, it goes to the top of the non-service area.
2701            addIndex = mLruProcessServiceStart;
2702            if (client != null) {
2703                int clientIndex = mLruProcesses.lastIndexOf(client);
2704                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2705                        + app);
2706                if (clientIndex >= 0 && addIndex > clientIndex) {
2707                    addIndex = clientIndex;
2708                }
2709            }
2710            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2711        }
2712
2713        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2714                + mLruProcessActivityStart + "): " + app);
2715        */
2716
2717        if (lrui >= 0) {
2718            if (lrui < mLruProcessActivityStart) {
2719                mLruProcessActivityStart--;
2720            }
2721            if (lrui < mLruProcessServiceStart) {
2722                mLruProcessServiceStart--;
2723            }
2724            /*
2725            if (addIndex > lrui) {
2726                addIndex--;
2727            }
2728            if (nextIndex > lrui) {
2729                nextIndex--;
2730            }
2731            */
2732            mLruProcesses.remove(lrui);
2733        }
2734
2735        /*
2736        mLruProcesses.add(addIndex, app);
2737        if (inActivity) {
2738            mLruProcessActivityStart++;
2739        }
2740        if (inService) {
2741            mLruProcessActivityStart++;
2742        }
2743        */
2744
2745        int nextIndex;
2746        if (hasActivity) {
2747            final int N = mLruProcesses.size();
2748            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2749                // Process doesn't have activities, but has clients with
2750                // activities...  move it up, but one below the top (the top
2751                // should always have a real activity).
2752                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2753                mLruProcesses.add(N-1, app);
2754                // To keep it from spamming the LRU list (by making a bunch of clients),
2755                // we will push down any other entries owned by the app.
2756                final int uid = app.info.uid;
2757                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2758                    ProcessRecord subProc = mLruProcesses.get(i);
2759                    if (subProc.info.uid == uid) {
2760                        // We want to push this one down the list.  If the process after
2761                        // it is for the same uid, however, don't do so, because we don't
2762                        // want them internally to be re-ordered.
2763                        if (mLruProcesses.get(i-1).info.uid != uid) {
2764                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2765                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2766                            ProcessRecord tmp = mLruProcesses.get(i);
2767                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2768                            mLruProcesses.set(i-1, tmp);
2769                            i--;
2770                        }
2771                    } else {
2772                        // A gap, we can stop here.
2773                        break;
2774                    }
2775                }
2776            } else {
2777                // Process has activities, put it at the very tipsy-top.
2778                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2779                mLruProcesses.add(app);
2780            }
2781            nextIndex = mLruProcessServiceStart;
2782        } else if (hasService) {
2783            // Process has services, put it at the top of the service list.
2784            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2785            mLruProcesses.add(mLruProcessActivityStart, app);
2786            nextIndex = mLruProcessServiceStart;
2787            mLruProcessActivityStart++;
2788        } else  {
2789            // Process not otherwise of interest, it goes to the top of the non-service area.
2790            int index = mLruProcessServiceStart;
2791            if (client != null) {
2792                // If there is a client, don't allow the process to be moved up higher
2793                // in the list than that client.
2794                int clientIndex = mLruProcesses.lastIndexOf(client);
2795                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2796                        + " when updating " + app);
2797                if (clientIndex <= lrui) {
2798                    // Don't allow the client index restriction to push it down farther in the
2799                    // list than it already is.
2800                    clientIndex = lrui;
2801                }
2802                if (clientIndex >= 0 && index > clientIndex) {
2803                    index = clientIndex;
2804                }
2805            }
2806            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2807            mLruProcesses.add(index, app);
2808            nextIndex = index-1;
2809            mLruProcessActivityStart++;
2810            mLruProcessServiceStart++;
2811        }
2812
2813        // If the app is currently using a content provider or service,
2814        // bump those processes as well.
2815        for (int j=app.connections.size()-1; j>=0; j--) {
2816            ConnectionRecord cr = app.connections.valueAt(j);
2817            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2818                    && cr.binding.service.app != null
2819                    && cr.binding.service.app.lruSeq != mLruSeq
2820                    && !cr.binding.service.app.persistent) {
2821                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2822                        "service connection", cr, app);
2823            }
2824        }
2825        for (int j=app.conProviders.size()-1; j>=0; j--) {
2826            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2827            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2828                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2829                        "provider reference", cpr, app);
2830            }
2831        }
2832    }
2833
2834    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2835        if (uid == Process.SYSTEM_UID) {
2836            // The system gets to run in any process.  If there are multiple
2837            // processes with the same uid, just pick the first (this
2838            // should never happen).
2839            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2840            if (procs == null) return null;
2841            final int N = procs.size();
2842            for (int i = 0; i < N; i++) {
2843                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2844            }
2845        }
2846        ProcessRecord proc = mProcessNames.get(processName, uid);
2847        if (false && proc != null && !keepIfLarge
2848                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2849                && proc.lastCachedPss >= 4000) {
2850            // Turn this condition on to cause killing to happen regularly, for testing.
2851            if (proc.baseProcessTracker != null) {
2852                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2853            }
2854            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2855        } else if (proc != null && !keepIfLarge
2856                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2857                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2858            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2859            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2860                if (proc.baseProcessTracker != null) {
2861                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2862                }
2863                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2864            }
2865        }
2866        return proc;
2867    }
2868
2869    void ensurePackageDexOpt(String packageName) {
2870        IPackageManager pm = AppGlobals.getPackageManager();
2871        try {
2872            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2873                mDidDexOpt = true;
2874            }
2875        } catch (RemoteException e) {
2876        }
2877    }
2878
2879    boolean isNextTransitionForward() {
2880        int transit = mWindowManager.getPendingAppTransition();
2881        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2882                || transit == AppTransition.TRANSIT_TASK_OPEN
2883                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2884    }
2885
2886    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2887            String processName, String abiOverride, int uid, Runnable crashHandler) {
2888        synchronized(this) {
2889            ApplicationInfo info = new ApplicationInfo();
2890            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2891            // For isolated processes, the former contains the parent's uid and the latter the
2892            // actual uid of the isolated process.
2893            // In the special case introduced by this method (which is, starting an isolated
2894            // process directly from the SystemServer without an actual parent app process) the
2895            // closest thing to a parent's uid is SYSTEM_UID.
2896            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2897            // the |isolated| logic in the ProcessRecord constructor.
2898            info.uid = Process.SYSTEM_UID;
2899            info.processName = processName;
2900            info.className = entryPoint;
2901            info.packageName = "android";
2902            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2903                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2904                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2905                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2906                    crashHandler);
2907            return proc != null ? proc.pid : 0;
2908        }
2909    }
2910
2911    final ProcessRecord startProcessLocked(String processName,
2912            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2913            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2914            boolean isolated, boolean keepIfLarge) {
2915        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2916                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2917                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2918                null /* crashHandler */);
2919    }
2920
2921    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2922            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2923            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2924            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2925        long startTime = SystemClock.elapsedRealtime();
2926        ProcessRecord app;
2927        if (!isolated) {
2928            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2929            checkTime(startTime, "startProcess: after getProcessRecord");
2930        } else {
2931            // If this is an isolated process, it can't re-use an existing process.
2932            app = null;
2933        }
2934        // We don't have to do anything more if:
2935        // (1) There is an existing application record; and
2936        // (2) The caller doesn't think it is dead, OR there is no thread
2937        //     object attached to it so we know it couldn't have crashed; and
2938        // (3) There is a pid assigned to it, so it is either starting or
2939        //     already running.
2940        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2941                + " app=" + app + " knownToBeDead=" + knownToBeDead
2942                + " thread=" + (app != null ? app.thread : null)
2943                + " pid=" + (app != null ? app.pid : -1));
2944        if (app != null && app.pid > 0) {
2945            if (!knownToBeDead || app.thread == null) {
2946                // We already have the app running, or are waiting for it to
2947                // come up (we have a pid but not yet its thread), so keep it.
2948                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2949                // If this is a new package in the process, add the package to the list
2950                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2951                checkTime(startTime, "startProcess: done, added package to proc");
2952                return app;
2953            }
2954
2955            // An application record is attached to a previous process,
2956            // clean it up now.
2957            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2958            checkTime(startTime, "startProcess: bad proc running, killing");
2959            Process.killProcessGroup(app.info.uid, app.pid);
2960            handleAppDiedLocked(app, true, true);
2961            checkTime(startTime, "startProcess: done killing old proc");
2962        }
2963
2964        String hostingNameStr = hostingName != null
2965                ? hostingName.flattenToShortString() : null;
2966
2967        if (!isolated) {
2968            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2969                // If we are in the background, then check to see if this process
2970                // is bad.  If so, we will just silently fail.
2971                if (mBadProcesses.get(info.processName, info.uid) != null) {
2972                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2973                            + "/" + info.processName);
2974                    return null;
2975                }
2976            } else {
2977                // When the user is explicitly starting a process, then clear its
2978                // crash count so that we won't make it bad until they see at
2979                // least one crash dialog again, and make the process good again
2980                // if it had been bad.
2981                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2982                        + "/" + info.processName);
2983                mProcessCrashTimes.remove(info.processName, info.uid);
2984                if (mBadProcesses.get(info.processName, info.uid) != null) {
2985                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2986                            UserHandle.getUserId(info.uid), info.uid,
2987                            info.processName);
2988                    mBadProcesses.remove(info.processName, info.uid);
2989                    if (app != null) {
2990                        app.bad = false;
2991                    }
2992                }
2993            }
2994        }
2995
2996        if (app == null) {
2997            checkTime(startTime, "startProcess: creating new process record");
2998            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2999            app.crashHandler = crashHandler;
3000            if (app == null) {
3001                Slog.w(TAG, "Failed making new process record for "
3002                        + processName + "/" + info.uid + " isolated=" + isolated);
3003                return null;
3004            }
3005            mProcessNames.put(processName, app.uid, app);
3006            if (isolated) {
3007                mIsolatedProcesses.put(app.uid, app);
3008            }
3009            checkTime(startTime, "startProcess: done creating new process record");
3010        } else {
3011            // If this is a new package in the process, add the package to the list
3012            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3013            checkTime(startTime, "startProcess: added package to existing proc");
3014        }
3015
3016        // If the system is not ready yet, then hold off on starting this
3017        // process until it is.
3018        if (!mProcessesReady
3019                && !isAllowedWhileBooting(info)
3020                && !allowWhileBooting) {
3021            if (!mProcessesOnHold.contains(app)) {
3022                mProcessesOnHold.add(app);
3023            }
3024            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3025            checkTime(startTime, "startProcess: returning with proc on hold");
3026            return app;
3027        }
3028
3029        checkTime(startTime, "startProcess: stepping in to startProcess");
3030        startProcessLocked(
3031                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3032        checkTime(startTime, "startProcess: done starting proc!");
3033        return (app.pid != 0) ? app : null;
3034    }
3035
3036    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3037        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3038    }
3039
3040    private final void startProcessLocked(ProcessRecord app,
3041            String hostingType, String hostingNameStr) {
3042        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3043                null /* entryPoint */, null /* entryPointArgs */);
3044    }
3045
3046    private final void startProcessLocked(ProcessRecord app, String hostingType,
3047            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3048        long startTime = SystemClock.elapsedRealtime();
3049        if (app.pid > 0 && app.pid != MY_PID) {
3050            checkTime(startTime, "startProcess: removing from pids map");
3051            synchronized (mPidsSelfLocked) {
3052                mPidsSelfLocked.remove(app.pid);
3053                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3054            }
3055            checkTime(startTime, "startProcess: done removing from pids map");
3056            app.setPid(0);
3057        }
3058
3059        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3060                "startProcessLocked removing on hold: " + app);
3061        mProcessesOnHold.remove(app);
3062
3063        checkTime(startTime, "startProcess: starting to update cpu stats");
3064        updateCpuStats();
3065        checkTime(startTime, "startProcess: done updating cpu stats");
3066
3067        try {
3068            int uid = app.uid;
3069
3070            int[] gids = null;
3071            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3072            if (!app.isolated) {
3073                int[] permGids = null;
3074                try {
3075                    checkTime(startTime, "startProcess: getting gids from package manager");
3076                    final PackageManager pm = mContext.getPackageManager();
3077                    permGids = pm.getPackageGids(app.info.packageName);
3078
3079                    if (Environment.isExternalStorageEmulated()) {
3080                        checkTime(startTime, "startProcess: checking external storage perm");
3081                        if (pm.checkPermission(
3082                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3083                                app.info.packageName) == PERMISSION_GRANTED) {
3084                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3085                        } else {
3086                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3087                        }
3088                    }
3089                } catch (PackageManager.NameNotFoundException e) {
3090                    Slog.w(TAG, "Unable to retrieve gids", e);
3091                }
3092
3093                /*
3094                 * Add shared application and profile GIDs so applications can share some
3095                 * resources like shared libraries and access user-wide resources
3096                 */
3097                if (permGids == null) {
3098                    gids = new int[2];
3099                } else {
3100                    gids = new int[permGids.length + 2];
3101                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3102                }
3103                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3104                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3105            }
3106            checkTime(startTime, "startProcess: building args");
3107            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3108                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3109                        && mTopComponent != null
3110                        && app.processName.equals(mTopComponent.getPackageName())) {
3111                    uid = 0;
3112                }
3113                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3114                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3115                    uid = 0;
3116                }
3117            }
3118            int debugFlags = 0;
3119            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3120                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3121                // Also turn on CheckJNI for debuggable apps. It's quite
3122                // awkward to turn on otherwise.
3123                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3124            }
3125            // Run the app in safe mode if its manifest requests so or the
3126            // system is booted in safe mode.
3127            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3128                mSafeMode == true) {
3129                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3130            }
3131            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3132                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3133            }
3134            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3135                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3136            }
3137            if ("1".equals(SystemProperties.get("debug.assert"))) {
3138                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3139            }
3140
3141            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3142            if (requiredAbi == null) {
3143                requiredAbi = Build.SUPPORTED_ABIS[0];
3144            }
3145
3146            String instructionSet = null;
3147            if (app.info.primaryCpuAbi != null) {
3148                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3149            }
3150
3151            // Start the process.  It will either succeed and return a result containing
3152            // the PID of the new process, or else throw a RuntimeException.
3153            boolean isActivityProcess = (entryPoint == null);
3154            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3155            checkTime(startTime, "startProcess: asking zygote to start proc");
3156            Process.ProcessStartResult startResult = Process.start(entryPoint,
3157                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3158                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3159                    entryPointArgs);
3160            checkTime(startTime, "startProcess: returned from zygote!");
3161
3162            if (app.isolated) {
3163                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3164            }
3165            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3166            checkTime(startTime, "startProcess: done updating battery stats");
3167
3168            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3169                    UserHandle.getUserId(uid), startResult.pid, uid,
3170                    app.processName, hostingType,
3171                    hostingNameStr != null ? hostingNameStr : "");
3172
3173            if (app.persistent) {
3174                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3175            }
3176
3177            checkTime(startTime, "startProcess: building log message");
3178            StringBuilder buf = mStringBuilder;
3179            buf.setLength(0);
3180            buf.append("Start proc ");
3181            buf.append(app.processName);
3182            if (!isActivityProcess) {
3183                buf.append(" [");
3184                buf.append(entryPoint);
3185                buf.append("]");
3186            }
3187            buf.append(" for ");
3188            buf.append(hostingType);
3189            if (hostingNameStr != null) {
3190                buf.append(" ");
3191                buf.append(hostingNameStr);
3192            }
3193            buf.append(": pid=");
3194            buf.append(startResult.pid);
3195            buf.append(" uid=");
3196            buf.append(uid);
3197            buf.append(" gids={");
3198            if (gids != null) {
3199                for (int gi=0; gi<gids.length; gi++) {
3200                    if (gi != 0) buf.append(", ");
3201                    buf.append(gids[gi]);
3202
3203                }
3204            }
3205            buf.append("}");
3206            if (requiredAbi != null) {
3207                buf.append(" abi=");
3208                buf.append(requiredAbi);
3209            }
3210            Slog.i(TAG, buf.toString());
3211            app.setPid(startResult.pid);
3212            app.usingWrapper = startResult.usingWrapper;
3213            app.removed = false;
3214            app.killed = false;
3215            app.killedByAm = false;
3216            checkTime(startTime, "startProcess: starting to update pids map");
3217            synchronized (mPidsSelfLocked) {
3218                this.mPidsSelfLocked.put(startResult.pid, app);
3219                if (isActivityProcess) {
3220                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3221                    msg.obj = app;
3222                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3223                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3224                }
3225            }
3226            checkTime(startTime, "startProcess: done updating pids map");
3227        } catch (RuntimeException e) {
3228            // XXX do better error recovery.
3229            app.setPid(0);
3230            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3231            if (app.isolated) {
3232                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3233            }
3234            Slog.e(TAG, "Failure starting process " + app.processName, e);
3235        }
3236    }
3237
3238    void updateUsageStats(ActivityRecord component, boolean resumed) {
3239        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3240        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3241        if (resumed) {
3242            if (mUsageStatsService != null) {
3243                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3244                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3245            }
3246            synchronized (stats) {
3247                stats.noteActivityResumedLocked(component.app.uid);
3248            }
3249        } else {
3250            if (mUsageStatsService != null) {
3251                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3252                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3253            }
3254            synchronized (stats) {
3255                stats.noteActivityPausedLocked(component.app.uid);
3256            }
3257        }
3258    }
3259
3260    Intent getHomeIntent() {
3261        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3262        intent.setComponent(mTopComponent);
3263        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3264            intent.addCategory(Intent.CATEGORY_HOME);
3265        }
3266        return intent;
3267    }
3268
3269    boolean startHomeActivityLocked(int userId) {
3270        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3271                && mTopAction == null) {
3272            // We are running in factory test mode, but unable to find
3273            // the factory test app, so just sit around displaying the
3274            // error message and don't try to start anything.
3275            return false;
3276        }
3277        Intent intent = getHomeIntent();
3278        ActivityInfo aInfo =
3279            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3280        if (aInfo != null) {
3281            intent.setComponent(new ComponentName(
3282                    aInfo.applicationInfo.packageName, aInfo.name));
3283            // Don't do this if the home app is currently being
3284            // instrumented.
3285            aInfo = new ActivityInfo(aInfo);
3286            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3287            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3288                    aInfo.applicationInfo.uid, true);
3289            if (app == null || app.instrumentationClass == null) {
3290                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3291                mStackSupervisor.startHomeActivity(intent, aInfo);
3292            }
3293        }
3294
3295        return true;
3296    }
3297
3298    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3299        ActivityInfo ai = null;
3300        ComponentName comp = intent.getComponent();
3301        try {
3302            if (comp != null) {
3303                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3304            } else {
3305                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3306                        intent,
3307                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3308                            flags, userId);
3309
3310                if (info != null) {
3311                    ai = info.activityInfo;
3312                }
3313            }
3314        } catch (RemoteException e) {
3315            // ignore
3316        }
3317
3318        return ai;
3319    }
3320
3321    /**
3322     * Starts the "new version setup screen" if appropriate.
3323     */
3324    void startSetupActivityLocked() {
3325        // Only do this once per boot.
3326        if (mCheckedForSetup) {
3327            return;
3328        }
3329
3330        // We will show this screen if the current one is a different
3331        // version than the last one shown, and we are not running in
3332        // low-level factory test mode.
3333        final ContentResolver resolver = mContext.getContentResolver();
3334        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3335                Settings.Global.getInt(resolver,
3336                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3337            mCheckedForSetup = true;
3338
3339            // See if we should be showing the platform update setup UI.
3340            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3341            List<ResolveInfo> ris = mContext.getPackageManager()
3342                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3343
3344            // We don't allow third party apps to replace this.
3345            ResolveInfo ri = null;
3346            for (int i=0; ris != null && i<ris.size(); i++) {
3347                if ((ris.get(i).activityInfo.applicationInfo.flags
3348                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3349                    ri = ris.get(i);
3350                    break;
3351                }
3352            }
3353
3354            if (ri != null) {
3355                String vers = ri.activityInfo.metaData != null
3356                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3357                        : null;
3358                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3359                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3360                            Intent.METADATA_SETUP_VERSION);
3361                }
3362                String lastVers = Settings.Secure.getString(
3363                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3364                if (vers != null && !vers.equals(lastVers)) {
3365                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3366                    intent.setComponent(new ComponentName(
3367                            ri.activityInfo.packageName, ri.activityInfo.name));
3368                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3369                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3370                            null);
3371                }
3372            }
3373        }
3374    }
3375
3376    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3377        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3378    }
3379
3380    void enforceNotIsolatedCaller(String caller) {
3381        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3382            throw new SecurityException("Isolated process not allowed to call " + caller);
3383        }
3384    }
3385
3386    void enforceShellRestriction(String restriction, int userHandle) {
3387        if (Binder.getCallingUid() == Process.SHELL_UID) {
3388            if (userHandle < 0
3389                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3390                throw new SecurityException("Shell does not have permission to access user "
3391                        + userHandle);
3392            }
3393        }
3394    }
3395
3396    @Override
3397    public int getFrontActivityScreenCompatMode() {
3398        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3399        synchronized (this) {
3400            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3401        }
3402    }
3403
3404    @Override
3405    public void setFrontActivityScreenCompatMode(int mode) {
3406        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3407                "setFrontActivityScreenCompatMode");
3408        synchronized (this) {
3409            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3410        }
3411    }
3412
3413    @Override
3414    public int getPackageScreenCompatMode(String packageName) {
3415        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3416        synchronized (this) {
3417            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3418        }
3419    }
3420
3421    @Override
3422    public void setPackageScreenCompatMode(String packageName, int mode) {
3423        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3424                "setPackageScreenCompatMode");
3425        synchronized (this) {
3426            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3427        }
3428    }
3429
3430    @Override
3431    public boolean getPackageAskScreenCompat(String packageName) {
3432        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3433        synchronized (this) {
3434            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3435        }
3436    }
3437
3438    @Override
3439    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3440        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3441                "setPackageAskScreenCompat");
3442        synchronized (this) {
3443            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3444        }
3445    }
3446
3447    private void dispatchProcessesChanged() {
3448        int N;
3449        synchronized (this) {
3450            N = mPendingProcessChanges.size();
3451            if (mActiveProcessChanges.length < N) {
3452                mActiveProcessChanges = new ProcessChangeItem[N];
3453            }
3454            mPendingProcessChanges.toArray(mActiveProcessChanges);
3455            mAvailProcessChanges.addAll(mPendingProcessChanges);
3456            mPendingProcessChanges.clear();
3457            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3458        }
3459
3460        int i = mProcessObservers.beginBroadcast();
3461        while (i > 0) {
3462            i--;
3463            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3464            if (observer != null) {
3465                try {
3466                    for (int j=0; j<N; j++) {
3467                        ProcessChangeItem item = mActiveProcessChanges[j];
3468                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3469                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3470                                    + item.pid + " uid=" + item.uid + ": "
3471                                    + item.foregroundActivities);
3472                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3473                                    item.foregroundActivities);
3474                        }
3475                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3476                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3477                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3478                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3479                        }
3480                    }
3481                } catch (RemoteException e) {
3482                }
3483            }
3484        }
3485        mProcessObservers.finishBroadcast();
3486    }
3487
3488    private void dispatchProcessDied(int pid, int uid) {
3489        int i = mProcessObservers.beginBroadcast();
3490        while (i > 0) {
3491            i--;
3492            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3493            if (observer != null) {
3494                try {
3495                    observer.onProcessDied(pid, uid);
3496                } catch (RemoteException e) {
3497                }
3498            }
3499        }
3500        mProcessObservers.finishBroadcast();
3501    }
3502
3503    @Override
3504    public final int startActivity(IApplicationThread caller, String callingPackage,
3505            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3506            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3507        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3508            resultWho, requestCode, startFlags, profilerInfo, options,
3509            UserHandle.getCallingUserId());
3510    }
3511
3512    @Override
3513    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3514            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3515            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3516        enforceNotIsolatedCaller("startActivity");
3517        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3518                false, ALLOW_FULL_ONLY, "startActivity", null);
3519        // TODO: Switch to user app stacks here.
3520        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3521                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3522                profilerInfo, null, null, options, userId, null, null);
3523    }
3524
3525    @Override
3526    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3527            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3528            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3529
3530        // This is very dangerous -- it allows you to perform a start activity (including
3531        // permission grants) as any app that may launch one of your own activities.  So
3532        // we will only allow this to be done from activities that are part of the core framework,
3533        // and then only when they are running as the system.
3534        final ActivityRecord sourceRecord;
3535        final int targetUid;
3536        final String targetPackage;
3537        synchronized (this) {
3538            if (resultTo == null) {
3539                throw new SecurityException("Must be called from an activity");
3540            }
3541            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3542            if (sourceRecord == null) {
3543                throw new SecurityException("Called with bad activity token: " + resultTo);
3544            }
3545            if (!sourceRecord.info.packageName.equals("android")) {
3546                throw new SecurityException(
3547                        "Must be called from an activity that is declared in the android package");
3548            }
3549            if (sourceRecord.app == null) {
3550                throw new SecurityException("Called without a process attached to activity");
3551            }
3552            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3553                // This is still okay, as long as this activity is running under the
3554                // uid of the original calling activity.
3555                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3556                    throw new SecurityException(
3557                            "Calling activity in uid " + sourceRecord.app.uid
3558                                    + " must be system uid or original calling uid "
3559                                    + sourceRecord.launchedFromUid);
3560                }
3561            }
3562            targetUid = sourceRecord.launchedFromUid;
3563            targetPackage = sourceRecord.launchedFromPackage;
3564        }
3565
3566        // TODO: Switch to user app stacks here.
3567        try {
3568            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3569                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3570                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3571            return ret;
3572        } catch (SecurityException e) {
3573            // XXX need to figure out how to propagate to original app.
3574            // A SecurityException here is generally actually a fault of the original
3575            // calling activity (such as a fairly granting permissions), so propagate it
3576            // back to them.
3577            /*
3578            StringBuilder msg = new StringBuilder();
3579            msg.append("While launching");
3580            msg.append(intent.toString());
3581            msg.append(": ");
3582            msg.append(e.getMessage());
3583            */
3584            throw e;
3585        }
3586    }
3587
3588    @Override
3589    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3590            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3591            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3592        enforceNotIsolatedCaller("startActivityAndWait");
3593        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3594                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3595        WaitResult res = new WaitResult();
3596        // TODO: Switch to user app stacks here.
3597        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3598                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3599                options, userId, null, null);
3600        return res;
3601    }
3602
3603    @Override
3604    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3605            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3606            int startFlags, Configuration config, Bundle options, int userId) {
3607        enforceNotIsolatedCaller("startActivityWithConfig");
3608        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3609                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3610        // TODO: Switch to user app stacks here.
3611        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3612                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3613                null, null, config, options, userId, null, null);
3614        return ret;
3615    }
3616
3617    @Override
3618    public int startActivityIntentSender(IApplicationThread caller,
3619            IntentSender intent, Intent fillInIntent, String resolvedType,
3620            IBinder resultTo, String resultWho, int requestCode,
3621            int flagsMask, int flagsValues, Bundle options) {
3622        enforceNotIsolatedCaller("startActivityIntentSender");
3623        // Refuse possible leaked file descriptors
3624        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3625            throw new IllegalArgumentException("File descriptors passed in Intent");
3626        }
3627
3628        IIntentSender sender = intent.getTarget();
3629        if (!(sender instanceof PendingIntentRecord)) {
3630            throw new IllegalArgumentException("Bad PendingIntent object");
3631        }
3632
3633        PendingIntentRecord pir = (PendingIntentRecord)sender;
3634
3635        synchronized (this) {
3636            // If this is coming from the currently resumed activity, it is
3637            // effectively saying that app switches are allowed at this point.
3638            final ActivityStack stack = getFocusedStack();
3639            if (stack.mResumedActivity != null &&
3640                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3641                mAppSwitchesAllowedTime = 0;
3642            }
3643        }
3644        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3645                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3646        return ret;
3647    }
3648
3649    @Override
3650    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3651            Intent intent, String resolvedType, IVoiceInteractionSession session,
3652            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3653            Bundle options, int userId) {
3654        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3655                != PackageManager.PERMISSION_GRANTED) {
3656            String msg = "Permission Denial: startVoiceActivity() from pid="
3657                    + Binder.getCallingPid()
3658                    + ", uid=" + Binder.getCallingUid()
3659                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3660            Slog.w(TAG, msg);
3661            throw new SecurityException(msg);
3662        }
3663        if (session == null || interactor == null) {
3664            throw new NullPointerException("null session or interactor");
3665        }
3666        userId = handleIncomingUser(callingPid, callingUid, userId,
3667                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3668        // TODO: Switch to user app stacks here.
3669        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3670                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3671                null, options, userId, null, null);
3672    }
3673
3674    @Override
3675    public boolean startNextMatchingActivity(IBinder callingActivity,
3676            Intent intent, Bundle options) {
3677        // Refuse possible leaked file descriptors
3678        if (intent != null && intent.hasFileDescriptors() == true) {
3679            throw new IllegalArgumentException("File descriptors passed in Intent");
3680        }
3681
3682        synchronized (this) {
3683            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3684            if (r == null) {
3685                ActivityOptions.abort(options);
3686                return false;
3687            }
3688            if (r.app == null || r.app.thread == null) {
3689                // The caller is not running...  d'oh!
3690                ActivityOptions.abort(options);
3691                return false;
3692            }
3693            intent = new Intent(intent);
3694            // The caller is not allowed to change the data.
3695            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3696            // And we are resetting to find the next component...
3697            intent.setComponent(null);
3698
3699            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3700
3701            ActivityInfo aInfo = null;
3702            try {
3703                List<ResolveInfo> resolves =
3704                    AppGlobals.getPackageManager().queryIntentActivities(
3705                            intent, r.resolvedType,
3706                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3707                            UserHandle.getCallingUserId());
3708
3709                // Look for the original activity in the list...
3710                final int N = resolves != null ? resolves.size() : 0;
3711                for (int i=0; i<N; i++) {
3712                    ResolveInfo rInfo = resolves.get(i);
3713                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3714                            && rInfo.activityInfo.name.equals(r.info.name)) {
3715                        // We found the current one...  the next matching is
3716                        // after it.
3717                        i++;
3718                        if (i<N) {
3719                            aInfo = resolves.get(i).activityInfo;
3720                        }
3721                        if (debug) {
3722                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3723                                    + "/" + r.info.name);
3724                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3725                                    + "/" + aInfo.name);
3726                        }
3727                        break;
3728                    }
3729                }
3730            } catch (RemoteException e) {
3731            }
3732
3733            if (aInfo == null) {
3734                // Nobody who is next!
3735                ActivityOptions.abort(options);
3736                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3737                return false;
3738            }
3739
3740            intent.setComponent(new ComponentName(
3741                    aInfo.applicationInfo.packageName, aInfo.name));
3742            intent.setFlags(intent.getFlags()&~(
3743                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3744                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3745                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3746                    Intent.FLAG_ACTIVITY_NEW_TASK));
3747
3748            // Okay now we need to start the new activity, replacing the
3749            // currently running activity.  This is a little tricky because
3750            // we want to start the new one as if the current one is finished,
3751            // but not finish the current one first so that there is no flicker.
3752            // And thus...
3753            final boolean wasFinishing = r.finishing;
3754            r.finishing = true;
3755
3756            // Propagate reply information over to the new activity.
3757            final ActivityRecord resultTo = r.resultTo;
3758            final String resultWho = r.resultWho;
3759            final int requestCode = r.requestCode;
3760            r.resultTo = null;
3761            if (resultTo != null) {
3762                resultTo.removeResultsLocked(r, resultWho, requestCode);
3763            }
3764
3765            final long origId = Binder.clearCallingIdentity();
3766            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3767                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3768                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3769                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3770            Binder.restoreCallingIdentity(origId);
3771
3772            r.finishing = wasFinishing;
3773            if (res != ActivityManager.START_SUCCESS) {
3774                return false;
3775            }
3776            return true;
3777        }
3778    }
3779
3780    @Override
3781    public final int startActivityFromRecents(int taskId, Bundle options) {
3782        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3783            String msg = "Permission Denial: startActivityFromRecents called without " +
3784                    START_TASKS_FROM_RECENTS;
3785            Slog.w(TAG, msg);
3786            throw new SecurityException(msg);
3787        }
3788        return startActivityFromRecentsInner(taskId, options);
3789    }
3790
3791    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3792        final TaskRecord task;
3793        final int callingUid;
3794        final String callingPackage;
3795        final Intent intent;
3796        final int userId;
3797        synchronized (this) {
3798            task = recentTaskForIdLocked(taskId);
3799            if (task == null) {
3800                throw new IllegalArgumentException("Task " + taskId + " not found.");
3801            }
3802            callingUid = task.mCallingUid;
3803            callingPackage = task.mCallingPackage;
3804            intent = task.intent;
3805            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3806            userId = task.userId;
3807        }
3808        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3809                options, userId, null, task);
3810    }
3811
3812    final int startActivityInPackage(int uid, String callingPackage,
3813            Intent intent, String resolvedType, IBinder resultTo,
3814            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3815            IActivityContainer container, TaskRecord inTask) {
3816
3817        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3818                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3819
3820        // TODO: Switch to user app stacks here.
3821        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3822                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3823                null, null, null, options, userId, container, inTask);
3824        return ret;
3825    }
3826
3827    @Override
3828    public final int startActivities(IApplicationThread caller, String callingPackage,
3829            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3830            int userId) {
3831        enforceNotIsolatedCaller("startActivities");
3832        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3833                false, ALLOW_FULL_ONLY, "startActivity", null);
3834        // TODO: Switch to user app stacks here.
3835        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3836                resolvedTypes, resultTo, options, userId);
3837        return ret;
3838    }
3839
3840    final int startActivitiesInPackage(int uid, String callingPackage,
3841            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3842            Bundle options, int userId) {
3843
3844        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3845                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3846        // TODO: Switch to user app stacks here.
3847        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3848                resultTo, options, userId);
3849        return ret;
3850    }
3851
3852    //explicitly remove thd old information in mRecentTasks when removing existing user.
3853    private void removeRecentTasksForUserLocked(int userId) {
3854        if(userId <= 0) {
3855            Slog.i(TAG, "Can't remove recent task on user " + userId);
3856            return;
3857        }
3858
3859        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3860            TaskRecord tr = mRecentTasks.get(i);
3861            if (tr.userId == userId) {
3862                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3863                        + " when finishing user" + userId);
3864                mRecentTasks.remove(i);
3865                tr.removedFromRecents(mTaskPersister);
3866            }
3867        }
3868
3869        // Remove tasks from persistent storage.
3870        mTaskPersister.wakeup(null, true);
3871    }
3872
3873    // Sort by taskId
3874    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3875        @Override
3876        public int compare(TaskRecord lhs, TaskRecord rhs) {
3877            return rhs.taskId - lhs.taskId;
3878        }
3879    };
3880
3881    // Extract the affiliates of the chain containing mRecentTasks[start].
3882    private int processNextAffiliateChain(int start) {
3883        final TaskRecord startTask = mRecentTasks.get(start);
3884        final int affiliateId = startTask.mAffiliatedTaskId;
3885
3886        // Quick identification of isolated tasks. I.e. those not launched behind.
3887        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3888                startTask.mNextAffiliate == null) {
3889            // There is still a slim chance that there are other tasks that point to this task
3890            // and that the chain is so messed up that this task no longer points to them but
3891            // the gain of this optimization outweighs the risk.
3892            startTask.inRecents = true;
3893            return start + 1;
3894        }
3895
3896        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3897        mTmpRecents.clear();
3898        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3899            final TaskRecord task = mRecentTasks.get(i);
3900            if (task.mAffiliatedTaskId == affiliateId) {
3901                mRecentTasks.remove(i);
3902                mTmpRecents.add(task);
3903            }
3904        }
3905
3906        // Sort them all by taskId. That is the order they were create in and that order will
3907        // always be correct.
3908        Collections.sort(mTmpRecents, mTaskRecordComparator);
3909
3910        // Go through and fix up the linked list.
3911        // The first one is the end of the chain and has no next.
3912        final TaskRecord first = mTmpRecents.get(0);
3913        first.inRecents = true;
3914        if (first.mNextAffiliate != null) {
3915            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3916            first.setNextAffiliate(null);
3917            mTaskPersister.wakeup(first, false);
3918        }
3919        // Everything in the middle is doubly linked from next to prev.
3920        final int tmpSize = mTmpRecents.size();
3921        for (int i = 0; i < tmpSize - 1; ++i) {
3922            final TaskRecord next = mTmpRecents.get(i);
3923            final TaskRecord prev = mTmpRecents.get(i + 1);
3924            if (next.mPrevAffiliate != prev) {
3925                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3926                        " setting prev=" + prev);
3927                next.setPrevAffiliate(prev);
3928                mTaskPersister.wakeup(next, false);
3929            }
3930            if (prev.mNextAffiliate != next) {
3931                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3932                        " setting next=" + next);
3933                prev.setNextAffiliate(next);
3934                mTaskPersister.wakeup(prev, false);
3935            }
3936            prev.inRecents = true;
3937        }
3938        // The last one is the beginning of the list and has no prev.
3939        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3940        if (last.mPrevAffiliate != null) {
3941            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3942            last.setPrevAffiliate(null);
3943            mTaskPersister.wakeup(last, false);
3944        }
3945
3946        // Insert the group back into mRecentTasks at start.
3947        mRecentTasks.addAll(start, mTmpRecents);
3948
3949        // Let the caller know where we left off.
3950        return start + tmpSize;
3951    }
3952
3953    /**
3954     * Update the recent tasks lists: make sure tasks should still be here (their
3955     * applications / activities still exist), update their availability, fixup ordering
3956     * of affiliations.
3957     */
3958    void cleanupRecentTasksLocked(int userId) {
3959        if (mRecentTasks == null) {
3960            // Happens when called from the packagemanager broadcast before boot.
3961            return;
3962        }
3963
3964        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3965        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3966        final IPackageManager pm = AppGlobals.getPackageManager();
3967        final ActivityInfo dummyAct = new ActivityInfo();
3968        final ApplicationInfo dummyApp = new ApplicationInfo();
3969
3970        int N = mRecentTasks.size();
3971
3972        int[] users = userId == UserHandle.USER_ALL
3973                ? getUsersLocked() : new int[] { userId };
3974        for (int user : users) {
3975            for (int i = 0; i < N; i++) {
3976                TaskRecord task = mRecentTasks.get(i);
3977                if (task.userId != user) {
3978                    // Only look at tasks for the user ID of interest.
3979                    continue;
3980                }
3981                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3982                    // This situation is broken, and we should just get rid of it now.
3983                    mRecentTasks.remove(i);
3984                    task.removedFromRecents(mTaskPersister);
3985                    i--;
3986                    N--;
3987                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3988                    continue;
3989                }
3990                // Check whether this activity is currently available.
3991                if (task.realActivity != null) {
3992                    ActivityInfo ai = availActCache.get(task.realActivity);
3993                    if (ai == null) {
3994                        try {
3995                            ai = pm.getActivityInfo(task.realActivity,
3996                                    PackageManager.GET_UNINSTALLED_PACKAGES
3997                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3998                        } catch (RemoteException e) {
3999                            // Will never happen.
4000                            continue;
4001                        }
4002                        if (ai == null) {
4003                            ai = dummyAct;
4004                        }
4005                        availActCache.put(task.realActivity, ai);
4006                    }
4007                    if (ai == dummyAct) {
4008                        // This could be either because the activity no longer exists, or the
4009                        // app is temporarily gone.  For the former we want to remove the recents
4010                        // entry; for the latter we want to mark it as unavailable.
4011                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
4012                        if (app == null) {
4013                            try {
4014                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
4015                                        PackageManager.GET_UNINSTALLED_PACKAGES
4016                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
4017                            } catch (RemoteException e) {
4018                                // Will never happen.
4019                                continue;
4020                            }
4021                            if (app == null) {
4022                                app = dummyApp;
4023                            }
4024                            availAppCache.put(task.realActivity.getPackageName(), app);
4025                        }
4026                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4027                            // Doesn't exist any more!  Good-bye.
4028                            mRecentTasks.remove(i);
4029                            task.removedFromRecents(mTaskPersister);
4030                            i--;
4031                            N--;
4032                            Slog.w(TAG, "Removing no longer valid recent: " + task);
4033                            continue;
4034                        } else {
4035                            // Otherwise just not available for now.
4036                            if (task.isAvailable) {
4037                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4038                                        + task);
4039                            }
4040                            task.isAvailable = false;
4041                        }
4042                    } else {
4043                        if (!ai.enabled || !ai.applicationInfo.enabled
4044                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4045                            if (task.isAvailable) {
4046                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4047                                        + task + " (enabled=" + ai.enabled + "/"
4048                                        + ai.applicationInfo.enabled +  " flags="
4049                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
4050                            }
4051                            task.isAvailable = false;
4052                        } else {
4053                            if (!task.isAvailable) {
4054                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
4055                                        + task);
4056                            }
4057                            task.isAvailable = true;
4058                        }
4059                    }
4060                }
4061            }
4062        }
4063
4064        // Verify the affiliate chain for each task.
4065        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
4066        }
4067
4068        mTmpRecents.clear();
4069        // mRecentTasks is now in sorted, affiliated order.
4070    }
4071
4072    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4073        int N = mRecentTasks.size();
4074        TaskRecord top = task;
4075        int topIndex = taskIndex;
4076        while (top.mNextAffiliate != null && topIndex > 0) {
4077            top = top.mNextAffiliate;
4078            topIndex--;
4079        }
4080        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4081                + topIndex + " from intial " + taskIndex);
4082        // Find the end of the chain, doing a sanity check along the way.
4083        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4084        int endIndex = topIndex;
4085        TaskRecord prev = top;
4086        while (endIndex < N) {
4087            TaskRecord cur = mRecentTasks.get(endIndex);
4088            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4089                    + endIndex + " " + cur);
4090            if (cur == top) {
4091                // Verify start of the chain.
4092                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4093                    Slog.wtf(TAG, "Bad chain @" + endIndex
4094                            + ": first task has next affiliate: " + prev);
4095                    sane = false;
4096                    break;
4097                }
4098            } else {
4099                // Verify middle of the chain's next points back to the one before.
4100                if (cur.mNextAffiliate != prev
4101                        || cur.mNextAffiliateTaskId != prev.taskId) {
4102                    Slog.wtf(TAG, "Bad chain @" + endIndex
4103                            + ": middle task " + cur + " @" + endIndex
4104                            + " has bad next affiliate "
4105                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4106                            + ", expected " + prev);
4107                    sane = false;
4108                    break;
4109                }
4110            }
4111            if (cur.mPrevAffiliateTaskId == -1) {
4112                // Chain ends here.
4113                if (cur.mPrevAffiliate != null) {
4114                    Slog.wtf(TAG, "Bad chain @" + endIndex
4115                            + ": last task " + cur + " has previous affiliate "
4116                            + cur.mPrevAffiliate);
4117                    sane = false;
4118                }
4119                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4120                break;
4121            } else {
4122                // Verify middle of the chain's prev points to a valid item.
4123                if (cur.mPrevAffiliate == null) {
4124                    Slog.wtf(TAG, "Bad chain @" + endIndex
4125                            + ": task " + cur + " has previous affiliate "
4126                            + cur.mPrevAffiliate + " but should be id "
4127                            + cur.mPrevAffiliate);
4128                    sane = false;
4129                    break;
4130                }
4131            }
4132            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4133                Slog.wtf(TAG, "Bad chain @" + endIndex
4134                        + ": task " + cur + " has affiliated id "
4135                        + cur.mAffiliatedTaskId + " but should be "
4136                        + task.mAffiliatedTaskId);
4137                sane = false;
4138                break;
4139            }
4140            prev = cur;
4141            endIndex++;
4142            if (endIndex >= N) {
4143                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4144                        + ": last task " + prev);
4145                sane = false;
4146                break;
4147            }
4148        }
4149        if (sane) {
4150            if (endIndex < taskIndex) {
4151                Slog.wtf(TAG, "Bad chain @" + endIndex
4152                        + ": did not extend to task " + task + " @" + taskIndex);
4153                sane = false;
4154            }
4155        }
4156        if (sane) {
4157            // All looks good, we can just move all of the affiliated tasks
4158            // to the top.
4159            for (int i=topIndex; i<=endIndex; i++) {
4160                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4161                        + " from " + i + " to " + (i-topIndex));
4162                TaskRecord cur = mRecentTasks.remove(i);
4163                mRecentTasks.add(i-topIndex, cur);
4164            }
4165            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4166                    + " to " + endIndex);
4167            return true;
4168        }
4169
4170        // Whoops, couldn't do it.
4171        return false;
4172    }
4173
4174    final void addRecentTaskLocked(TaskRecord task) {
4175        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4176                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4177
4178        int N = mRecentTasks.size();
4179        // Quick case: check if the top-most recent task is the same.
4180        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4181            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4182            return;
4183        }
4184        // Another quick case: check if this is part of a set of affiliated
4185        // tasks that are at the top.
4186        if (isAffiliated && N > 0 && task.inRecents
4187                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4188            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4189                    + " at top when adding " + task);
4190            return;
4191        }
4192        // Another quick case: never add voice sessions.
4193        if (task.voiceSession != null) {
4194            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4195            return;
4196        }
4197
4198        boolean needAffiliationFix = false;
4199
4200        // Slightly less quick case: the task is already in recents, so all we need
4201        // to do is move it.
4202        if (task.inRecents) {
4203            int taskIndex = mRecentTasks.indexOf(task);
4204            if (taskIndex >= 0) {
4205                if (!isAffiliated) {
4206                    // Simple case: this is not an affiliated task, so we just move it to the front.
4207                    mRecentTasks.remove(taskIndex);
4208                    mRecentTasks.add(0, task);
4209                    notifyTaskPersisterLocked(task, false);
4210                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4211                            + " from " + taskIndex);
4212                    return;
4213                } else {
4214                    // More complicated: need to keep all affiliated tasks together.
4215                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4216                        // All went well.
4217                        return;
4218                    }
4219
4220                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4221                    // everything and then go through our general path of adding a new task.
4222                    needAffiliationFix = true;
4223                }
4224            } else {
4225                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4226                needAffiliationFix = true;
4227            }
4228        }
4229
4230        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4231        trimRecentsForTask(task, true);
4232
4233        N = mRecentTasks.size();
4234        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4235            final TaskRecord tr = mRecentTasks.remove(N - 1);
4236            tr.removedFromRecents(mTaskPersister);
4237            N--;
4238        }
4239        task.inRecents = true;
4240        if (!isAffiliated || needAffiliationFix) {
4241            // If this is a simple non-affiliated task, or we had some failure trying to
4242            // handle it as part of an affilated task, then just place it at the top.
4243            mRecentTasks.add(0, task);
4244        } else if (isAffiliated) {
4245            // If this is a new affiliated task, then move all of the affiliated tasks
4246            // to the front and insert this new one.
4247            TaskRecord other = task.mNextAffiliate;
4248            if (other == null) {
4249                other = task.mPrevAffiliate;
4250            }
4251            if (other != null) {
4252                int otherIndex = mRecentTasks.indexOf(other);
4253                if (otherIndex >= 0) {
4254                    // Insert new task at appropriate location.
4255                    int taskIndex;
4256                    if (other == task.mNextAffiliate) {
4257                        // We found the index of our next affiliation, which is who is
4258                        // before us in the list, so add after that point.
4259                        taskIndex = otherIndex+1;
4260                    } else {
4261                        // We found the index of our previous affiliation, which is who is
4262                        // after us in the list, so add at their position.
4263                        taskIndex = otherIndex;
4264                    }
4265                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4266                            + taskIndex + ": " + task);
4267                    mRecentTasks.add(taskIndex, task);
4268
4269                    // Now move everything to the front.
4270                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4271                        // All went well.
4272                        return;
4273                    }
4274
4275                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4276                    // everything and then go through our general path of adding a new task.
4277                    needAffiliationFix = true;
4278                } else {
4279                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4280                            + other);
4281                    needAffiliationFix = true;
4282                }
4283            } else {
4284                if (DEBUG_RECENTS) Slog.d(TAG,
4285                        "addRecent: adding affiliated task without next/prev:" + task);
4286                needAffiliationFix = true;
4287            }
4288        }
4289        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4290
4291        if (needAffiliationFix) {
4292            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4293            cleanupRecentTasksLocked(task.userId);
4294        }
4295    }
4296
4297    /**
4298     * If needed, remove oldest existing entries in recents that are for the same kind
4299     * of task as the given one.
4300     */
4301    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4302        int N = mRecentTasks.size();
4303        final Intent intent = task.intent;
4304        final boolean document = intent != null && intent.isDocument();
4305
4306        int maxRecents = task.maxRecents - 1;
4307        for (int i=0; i<N; i++) {
4308            final TaskRecord tr = mRecentTasks.get(i);
4309            if (task != tr) {
4310                if (task.userId != tr.userId) {
4311                    continue;
4312                }
4313                if (i > MAX_RECENT_BITMAPS) {
4314                    tr.freeLastThumbnail();
4315                }
4316                final Intent trIntent = tr.intent;
4317                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4318                    (intent == null || !intent.filterEquals(trIntent))) {
4319                    continue;
4320                }
4321                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4322                if (document && trIsDocument) {
4323                    // These are the same document activity (not necessarily the same doc).
4324                    if (maxRecents > 0) {
4325                        --maxRecents;
4326                        continue;
4327                    }
4328                    // Hit the maximum number of documents for this task. Fall through
4329                    // and remove this document from recents.
4330                } else if (document || trIsDocument) {
4331                    // Only one of these is a document. Not the droid we're looking for.
4332                    continue;
4333                }
4334            }
4335
4336            if (!doTrim) {
4337                // If the caller is not actually asking for a trim, just tell them we reached
4338                // a point where the trim would happen.
4339                return i;
4340            }
4341
4342            // Either task and tr are the same or, their affinities match or their intents match
4343            // and neither of them is a document, or they are documents using the same activity
4344            // and their maxRecents has been reached.
4345            tr.disposeThumbnail();
4346            mRecentTasks.remove(i);
4347            if (task != tr) {
4348                tr.removedFromRecents(mTaskPersister);
4349            }
4350            i--;
4351            N--;
4352            if (task.intent == null) {
4353                // If the new recent task we are adding is not fully
4354                // specified, then replace it with the existing recent task.
4355                task = tr;
4356            }
4357            notifyTaskPersisterLocked(tr, false);
4358        }
4359
4360        return -1;
4361    }
4362
4363    @Override
4364    public void reportActivityFullyDrawn(IBinder token) {
4365        synchronized (this) {
4366            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4367            if (r == null) {
4368                return;
4369            }
4370            r.reportFullyDrawnLocked();
4371        }
4372    }
4373
4374    @Override
4375    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4376        synchronized (this) {
4377            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4378            if (r == null) {
4379                return;
4380            }
4381            final long origId = Binder.clearCallingIdentity();
4382            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4383            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4384                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4385            if (config != null) {
4386                r.frozenBeforeDestroy = true;
4387                if (!updateConfigurationLocked(config, r, false, false)) {
4388                    mStackSupervisor.resumeTopActivitiesLocked();
4389                }
4390            }
4391            Binder.restoreCallingIdentity(origId);
4392        }
4393    }
4394
4395    @Override
4396    public int getRequestedOrientation(IBinder token) {
4397        synchronized (this) {
4398            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4399            if (r == null) {
4400                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4401            }
4402            return mWindowManager.getAppOrientation(r.appToken);
4403        }
4404    }
4405
4406    /**
4407     * This is the internal entry point for handling Activity.finish().
4408     *
4409     * @param token The Binder token referencing the Activity we want to finish.
4410     * @param resultCode Result code, if any, from this Activity.
4411     * @param resultData Result data (Intent), if any, from this Activity.
4412     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4413     *            the root Activity in the task.
4414     *
4415     * @return Returns true if the activity successfully finished, or false if it is still running.
4416     */
4417    @Override
4418    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4419            boolean finishTask) {
4420        // Refuse possible leaked file descriptors
4421        if (resultData != null && resultData.hasFileDescriptors() == true) {
4422            throw new IllegalArgumentException("File descriptors passed in Intent");
4423        }
4424
4425        synchronized(this) {
4426            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4427            if (r == null) {
4428                return true;
4429            }
4430            // Keep track of the root activity of the task before we finish it
4431            TaskRecord tr = r.task;
4432            ActivityRecord rootR = tr.getRootActivity();
4433            // Do not allow task to finish in Lock Task mode.
4434            if (tr == mStackSupervisor.mLockTaskModeTask) {
4435                if (rootR == r) {
4436                    mStackSupervisor.showLockTaskToast();
4437                    return false;
4438                }
4439            }
4440            if (mController != null) {
4441                // Find the first activity that is not finishing.
4442                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4443                if (next != null) {
4444                    // ask watcher if this is allowed
4445                    boolean resumeOK = true;
4446                    try {
4447                        resumeOK = mController.activityResuming(next.packageName);
4448                    } catch (RemoteException e) {
4449                        mController = null;
4450                        Watchdog.getInstance().setActivityController(null);
4451                    }
4452
4453                    if (!resumeOK) {
4454                        return false;
4455                    }
4456                }
4457            }
4458            final long origId = Binder.clearCallingIdentity();
4459            try {
4460                boolean res;
4461                if (finishTask && r == rootR) {
4462                    // If requested, remove the task that is associated to this activity only if it
4463                    // was the root activity in the task.  The result code and data is ignored because
4464                    // we don't support returning them across task boundaries.
4465                    res = removeTaskByIdLocked(tr.taskId, 0);
4466                } else {
4467                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4468                            resultData, "app-request", true);
4469                }
4470                return res;
4471            } finally {
4472                Binder.restoreCallingIdentity(origId);
4473            }
4474        }
4475    }
4476
4477    @Override
4478    public final void finishHeavyWeightApp() {
4479        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4480                != PackageManager.PERMISSION_GRANTED) {
4481            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4482                    + Binder.getCallingPid()
4483                    + ", uid=" + Binder.getCallingUid()
4484                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4485            Slog.w(TAG, msg);
4486            throw new SecurityException(msg);
4487        }
4488
4489        synchronized(this) {
4490            if (mHeavyWeightProcess == null) {
4491                return;
4492            }
4493
4494            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4495                    mHeavyWeightProcess.activities);
4496            for (int i=0; i<activities.size(); i++) {
4497                ActivityRecord r = activities.get(i);
4498                if (!r.finishing) {
4499                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4500                            null, "finish-heavy", true);
4501                }
4502            }
4503
4504            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4505                    mHeavyWeightProcess.userId, 0));
4506            mHeavyWeightProcess = null;
4507        }
4508    }
4509
4510    @Override
4511    public void crashApplication(int uid, int initialPid, String packageName,
4512            String message) {
4513        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4514                != PackageManager.PERMISSION_GRANTED) {
4515            String msg = "Permission Denial: crashApplication() from pid="
4516                    + Binder.getCallingPid()
4517                    + ", uid=" + Binder.getCallingUid()
4518                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4519            Slog.w(TAG, msg);
4520            throw new SecurityException(msg);
4521        }
4522
4523        synchronized(this) {
4524            ProcessRecord proc = null;
4525
4526            // Figure out which process to kill.  We don't trust that initialPid
4527            // still has any relation to current pids, so must scan through the
4528            // list.
4529            synchronized (mPidsSelfLocked) {
4530                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4531                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4532                    if (p.uid != uid) {
4533                        continue;
4534                    }
4535                    if (p.pid == initialPid) {
4536                        proc = p;
4537                        break;
4538                    }
4539                    if (p.pkgList.containsKey(packageName)) {
4540                        proc = p;
4541                    }
4542                }
4543            }
4544
4545            if (proc == null) {
4546                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4547                        + " initialPid=" + initialPid
4548                        + " packageName=" + packageName);
4549                return;
4550            }
4551
4552            if (proc.thread != null) {
4553                if (proc.pid == Process.myPid()) {
4554                    Log.w(TAG, "crashApplication: trying to crash self!");
4555                    return;
4556                }
4557                long ident = Binder.clearCallingIdentity();
4558                try {
4559                    proc.thread.scheduleCrash(message);
4560                } catch (RemoteException e) {
4561                }
4562                Binder.restoreCallingIdentity(ident);
4563            }
4564        }
4565    }
4566
4567    @Override
4568    public final void finishSubActivity(IBinder token, String resultWho,
4569            int requestCode) {
4570        synchronized(this) {
4571            final long origId = Binder.clearCallingIdentity();
4572            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4573            if (r != null) {
4574                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4575            }
4576            Binder.restoreCallingIdentity(origId);
4577        }
4578    }
4579
4580    @Override
4581    public boolean finishActivityAffinity(IBinder token) {
4582        synchronized(this) {
4583            final long origId = Binder.clearCallingIdentity();
4584            try {
4585                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4586
4587                ActivityRecord rootR = r.task.getRootActivity();
4588                // Do not allow task to finish in Lock Task mode.
4589                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4590                    if (rootR == r) {
4591                        mStackSupervisor.showLockTaskToast();
4592                        return false;
4593                    }
4594                }
4595                boolean res = false;
4596                if (r != null) {
4597                    res = r.task.stack.finishActivityAffinityLocked(r);
4598                }
4599                return res;
4600            } finally {
4601                Binder.restoreCallingIdentity(origId);
4602            }
4603        }
4604    }
4605
4606    @Override
4607    public void finishVoiceTask(IVoiceInteractionSession session) {
4608        synchronized(this) {
4609            final long origId = Binder.clearCallingIdentity();
4610            try {
4611                mStackSupervisor.finishVoiceTask(session);
4612            } finally {
4613                Binder.restoreCallingIdentity(origId);
4614            }
4615        }
4616
4617    }
4618
4619    @Override
4620    public boolean releaseActivityInstance(IBinder token) {
4621        synchronized(this) {
4622            final long origId = Binder.clearCallingIdentity();
4623            try {
4624                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4625                if (r.task == null || r.task.stack == null) {
4626                    return false;
4627                }
4628                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4629            } finally {
4630                Binder.restoreCallingIdentity(origId);
4631            }
4632        }
4633    }
4634
4635    @Override
4636    public void releaseSomeActivities(IApplicationThread appInt) {
4637        synchronized(this) {
4638            final long origId = Binder.clearCallingIdentity();
4639            try {
4640                ProcessRecord app = getRecordForAppLocked(appInt);
4641                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4642            } finally {
4643                Binder.restoreCallingIdentity(origId);
4644            }
4645        }
4646    }
4647
4648    @Override
4649    public boolean willActivityBeVisible(IBinder token) {
4650        synchronized(this) {
4651            ActivityStack stack = ActivityRecord.getStackLocked(token);
4652            if (stack != null) {
4653                return stack.willActivityBeVisibleLocked(token);
4654            }
4655            return false;
4656        }
4657    }
4658
4659    @Override
4660    public void overridePendingTransition(IBinder token, String packageName,
4661            int enterAnim, int exitAnim) {
4662        synchronized(this) {
4663            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4664            if (self == null) {
4665                return;
4666            }
4667
4668            final long origId = Binder.clearCallingIdentity();
4669
4670            if (self.state == ActivityState.RESUMED
4671                    || self.state == ActivityState.PAUSING) {
4672                mWindowManager.overridePendingAppTransition(packageName,
4673                        enterAnim, exitAnim, null);
4674            }
4675
4676            Binder.restoreCallingIdentity(origId);
4677        }
4678    }
4679
4680    /**
4681     * Main function for removing an existing process from the activity manager
4682     * as a result of that process going away.  Clears out all connections
4683     * to the process.
4684     */
4685    private final void handleAppDiedLocked(ProcessRecord app,
4686            boolean restarting, boolean allowRestart) {
4687        int pid = app.pid;
4688        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4689        if (!restarting) {
4690            removeLruProcessLocked(app);
4691            if (pid > 0) {
4692                ProcessList.remove(pid);
4693            }
4694        }
4695
4696        if (mProfileProc == app) {
4697            clearProfilerLocked();
4698        }
4699
4700        // Remove this application's activities from active lists.
4701        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4702
4703        app.activities.clear();
4704
4705        if (app.instrumentationClass != null) {
4706            Slog.w(TAG, "Crash of app " + app.processName
4707                  + " running instrumentation " + app.instrumentationClass);
4708            Bundle info = new Bundle();
4709            info.putString("shortMsg", "Process crashed.");
4710            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4711        }
4712
4713        if (!restarting) {
4714            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4715                // If there was nothing to resume, and we are not already
4716                // restarting this process, but there is a visible activity that
4717                // is hosted by the process...  then make sure all visible
4718                // activities are running, taking care of restarting this
4719                // process.
4720                if (hasVisibleActivities) {
4721                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4722                }
4723            }
4724        }
4725    }
4726
4727    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4728        IBinder threadBinder = thread.asBinder();
4729        // Find the application record.
4730        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4731            ProcessRecord rec = mLruProcesses.get(i);
4732            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4733                return i;
4734            }
4735        }
4736        return -1;
4737    }
4738
4739    final ProcessRecord getRecordForAppLocked(
4740            IApplicationThread thread) {
4741        if (thread == null) {
4742            return null;
4743        }
4744
4745        int appIndex = getLRURecordIndexForAppLocked(thread);
4746        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4747    }
4748
4749    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4750        // If there are no longer any background processes running,
4751        // and the app that died was not running instrumentation,
4752        // then tell everyone we are now low on memory.
4753        boolean haveBg = false;
4754        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4755            ProcessRecord rec = mLruProcesses.get(i);
4756            if (rec.thread != null
4757                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4758                haveBg = true;
4759                break;
4760            }
4761        }
4762
4763        if (!haveBg) {
4764            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4765            if (doReport) {
4766                long now = SystemClock.uptimeMillis();
4767                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4768                    doReport = false;
4769                } else {
4770                    mLastMemUsageReportTime = now;
4771                }
4772            }
4773            final ArrayList<ProcessMemInfo> memInfos
4774                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4775            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4776            long now = SystemClock.uptimeMillis();
4777            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4778                ProcessRecord rec = mLruProcesses.get(i);
4779                if (rec == dyingProc || rec.thread == null) {
4780                    continue;
4781                }
4782                if (doReport) {
4783                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4784                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4785                }
4786                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4787                    // The low memory report is overriding any current
4788                    // state for a GC request.  Make sure to do
4789                    // heavy/important/visible/foreground processes first.
4790                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4791                        rec.lastRequestedGc = 0;
4792                    } else {
4793                        rec.lastRequestedGc = rec.lastLowMemory;
4794                    }
4795                    rec.reportLowMemory = true;
4796                    rec.lastLowMemory = now;
4797                    mProcessesToGc.remove(rec);
4798                    addProcessToGcListLocked(rec);
4799                }
4800            }
4801            if (doReport) {
4802                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4803                mHandler.sendMessage(msg);
4804            }
4805            scheduleAppGcsLocked();
4806        }
4807    }
4808
4809    final void appDiedLocked(ProcessRecord app) {
4810       appDiedLocked(app, app.pid, app.thread);
4811    }
4812
4813    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4814
4815        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4816        synchronized (stats) {
4817            stats.noteProcessDiedLocked(app.info.uid, pid);
4818        }
4819
4820        Process.killProcessQuiet(pid);
4821        Process.killProcessGroup(app.info.uid, pid);
4822        app.killed = true;
4823
4824        // Clean up already done if the process has been re-started.
4825        if (app.pid == pid && app.thread != null &&
4826                app.thread.asBinder() == thread.asBinder()) {
4827            boolean doLowMem = app.instrumentationClass == null;
4828            boolean doOomAdj = doLowMem;
4829            if (!app.killedByAm) {
4830                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4831                        + ") has died.");
4832                mAllowLowerMemLevel = true;
4833            } else {
4834                // Note that we always want to do oom adj to update our state with the
4835                // new number of procs.
4836                mAllowLowerMemLevel = false;
4837                doLowMem = false;
4838            }
4839            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4840            if (DEBUG_CLEANUP) Slog.v(
4841                TAG, "Dying app: " + app + ", pid: " + pid
4842                + ", thread: " + thread.asBinder());
4843            handleAppDiedLocked(app, false, true);
4844
4845            if (doOomAdj) {
4846                updateOomAdjLocked();
4847            }
4848            if (doLowMem) {
4849                doLowMemReportIfNeededLocked(app);
4850            }
4851        } else if (app.pid != pid) {
4852            // A new process has already been started.
4853            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4854                    + ") has died and restarted (pid " + app.pid + ").");
4855            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4856        } else if (DEBUG_PROCESSES) {
4857            Slog.d(TAG, "Received spurious death notification for thread "
4858                    + thread.asBinder());
4859        }
4860    }
4861
4862    /**
4863     * If a stack trace dump file is configured, dump process stack traces.
4864     * @param clearTraces causes the dump file to be erased prior to the new
4865     *    traces being written, if true; when false, the new traces will be
4866     *    appended to any existing file content.
4867     * @param firstPids of dalvik VM processes to dump stack traces for first
4868     * @param lastPids of dalvik VM processes to dump stack traces for last
4869     * @param nativeProcs optional list of native process names to dump stack crawls
4870     * @return file containing stack traces, or null if no dump file is configured
4871     */
4872    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4873            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4874        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4875        if (tracesPath == null || tracesPath.length() == 0) {
4876            return null;
4877        }
4878
4879        File tracesFile = new File(tracesPath);
4880        try {
4881            File tracesDir = tracesFile.getParentFile();
4882            if (!tracesDir.exists()) {
4883                tracesDir.mkdirs();
4884                if (!SELinux.restorecon(tracesDir)) {
4885                    return null;
4886                }
4887            }
4888            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4889
4890            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4891            tracesFile.createNewFile();
4892            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4893        } catch (IOException e) {
4894            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4895            return null;
4896        }
4897
4898        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4899        return tracesFile;
4900    }
4901
4902    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4903            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4904        // Use a FileObserver to detect when traces finish writing.
4905        // The order of traces is considered important to maintain for legibility.
4906        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4907            @Override
4908            public synchronized void onEvent(int event, String path) { notify(); }
4909        };
4910
4911        try {
4912            observer.startWatching();
4913
4914            // First collect all of the stacks of the most important pids.
4915            if (firstPids != null) {
4916                try {
4917                    int num = firstPids.size();
4918                    for (int i = 0; i < num; i++) {
4919                        synchronized (observer) {
4920                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4921                            observer.wait(200);  // Wait for write-close, give up after 200msec
4922                        }
4923                    }
4924                } catch (InterruptedException e) {
4925                    Log.wtf(TAG, e);
4926                }
4927            }
4928
4929            // Next collect the stacks of the native pids
4930            if (nativeProcs != null) {
4931                int[] pids = Process.getPidsForCommands(nativeProcs);
4932                if (pids != null) {
4933                    for (int pid : pids) {
4934                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4935                    }
4936                }
4937            }
4938
4939            // Lastly, measure CPU usage.
4940            if (processCpuTracker != null) {
4941                processCpuTracker.init();
4942                System.gc();
4943                processCpuTracker.update();
4944                try {
4945                    synchronized (processCpuTracker) {
4946                        processCpuTracker.wait(500); // measure over 1/2 second.
4947                    }
4948                } catch (InterruptedException e) {
4949                }
4950                processCpuTracker.update();
4951
4952                // We'll take the stack crawls of just the top apps using CPU.
4953                final int N = processCpuTracker.countWorkingStats();
4954                int numProcs = 0;
4955                for (int i=0; i<N && numProcs<5; i++) {
4956                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4957                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4958                        numProcs++;
4959                        try {
4960                            synchronized (observer) {
4961                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4962                                observer.wait(200);  // Wait for write-close, give up after 200msec
4963                            }
4964                        } catch (InterruptedException e) {
4965                            Log.wtf(TAG, e);
4966                        }
4967
4968                    }
4969                }
4970            }
4971        } finally {
4972            observer.stopWatching();
4973        }
4974    }
4975
4976    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4977        if (true || IS_USER_BUILD) {
4978            return;
4979        }
4980        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4981        if (tracesPath == null || tracesPath.length() == 0) {
4982            return;
4983        }
4984
4985        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4986        StrictMode.allowThreadDiskWrites();
4987        try {
4988            final File tracesFile = new File(tracesPath);
4989            final File tracesDir = tracesFile.getParentFile();
4990            final File tracesTmp = new File(tracesDir, "__tmp__");
4991            try {
4992                if (!tracesDir.exists()) {
4993                    tracesDir.mkdirs();
4994                    if (!SELinux.restorecon(tracesDir.getPath())) {
4995                        return;
4996                    }
4997                }
4998                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4999
5000                if (tracesFile.exists()) {
5001                    tracesTmp.delete();
5002                    tracesFile.renameTo(tracesTmp);
5003                }
5004                StringBuilder sb = new StringBuilder();
5005                Time tobj = new Time();
5006                tobj.set(System.currentTimeMillis());
5007                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5008                sb.append(": ");
5009                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5010                sb.append(" since ");
5011                sb.append(msg);
5012                FileOutputStream fos = new FileOutputStream(tracesFile);
5013                fos.write(sb.toString().getBytes());
5014                if (app == null) {
5015                    fos.write("\n*** No application process!".getBytes());
5016                }
5017                fos.close();
5018                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5019            } catch (IOException e) {
5020                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5021                return;
5022            }
5023
5024            if (app != null) {
5025                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5026                firstPids.add(app.pid);
5027                dumpStackTraces(tracesPath, firstPids, null, null, null);
5028            }
5029
5030            File lastTracesFile = null;
5031            File curTracesFile = null;
5032            for (int i=9; i>=0; i--) {
5033                String name = String.format(Locale.US, "slow%02d.txt", i);
5034                curTracesFile = new File(tracesDir, name);
5035                if (curTracesFile.exists()) {
5036                    if (lastTracesFile != null) {
5037                        curTracesFile.renameTo(lastTracesFile);
5038                    } else {
5039                        curTracesFile.delete();
5040                    }
5041                }
5042                lastTracesFile = curTracesFile;
5043            }
5044            tracesFile.renameTo(curTracesFile);
5045            if (tracesTmp.exists()) {
5046                tracesTmp.renameTo(tracesFile);
5047            }
5048        } finally {
5049            StrictMode.setThreadPolicy(oldPolicy);
5050        }
5051    }
5052
5053    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5054            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5055        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5056        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5057
5058        if (mController != null) {
5059            try {
5060                // 0 == continue, -1 = kill process immediately
5061                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5062                if (res < 0 && app.pid != MY_PID) {
5063                    app.kill("anr", true);
5064                }
5065            } catch (RemoteException e) {
5066                mController = null;
5067                Watchdog.getInstance().setActivityController(null);
5068            }
5069        }
5070
5071        long anrTime = SystemClock.uptimeMillis();
5072        if (MONITOR_CPU_USAGE) {
5073            updateCpuStatsNow();
5074        }
5075
5076        synchronized (this) {
5077            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5078            if (mShuttingDown) {
5079                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5080                return;
5081            } else if (app.notResponding) {
5082                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5083                return;
5084            } else if (app.crashing) {
5085                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5086                return;
5087            }
5088
5089            // In case we come through here for the same app before completing
5090            // this one, mark as anring now so we will bail out.
5091            app.notResponding = true;
5092
5093            // Log the ANR to the event log.
5094            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5095                    app.processName, app.info.flags, annotation);
5096
5097            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5098            firstPids.add(app.pid);
5099
5100            int parentPid = app.pid;
5101            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5102            if (parentPid != app.pid) firstPids.add(parentPid);
5103
5104            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5105
5106            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5107                ProcessRecord r = mLruProcesses.get(i);
5108                if (r != null && r.thread != null) {
5109                    int pid = r.pid;
5110                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5111                        if (r.persistent) {
5112                            firstPids.add(pid);
5113                        } else {
5114                            lastPids.put(pid, Boolean.TRUE);
5115                        }
5116                    }
5117                }
5118            }
5119        }
5120
5121        // Log the ANR to the main log.
5122        StringBuilder info = new StringBuilder();
5123        info.setLength(0);
5124        info.append("ANR in ").append(app.processName);
5125        if (activity != null && activity.shortComponentName != null) {
5126            info.append(" (").append(activity.shortComponentName).append(")");
5127        }
5128        info.append("\n");
5129        info.append("PID: ").append(app.pid).append("\n");
5130        if (annotation != null) {
5131            info.append("Reason: ").append(annotation).append("\n");
5132        }
5133        if (parent != null && parent != activity) {
5134            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5135        }
5136
5137        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5138
5139        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5140                NATIVE_STACKS_OF_INTEREST);
5141
5142        String cpuInfo = null;
5143        if (MONITOR_CPU_USAGE) {
5144            updateCpuStatsNow();
5145            synchronized (mProcessCpuTracker) {
5146                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5147            }
5148            info.append(processCpuTracker.printCurrentLoad());
5149            info.append(cpuInfo);
5150        }
5151
5152        info.append(processCpuTracker.printCurrentState(anrTime));
5153
5154        Slog.e(TAG, info.toString());
5155        if (tracesFile == null) {
5156            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5157            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5158        }
5159
5160        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5161                cpuInfo, tracesFile, null);
5162
5163        if (mController != null) {
5164            try {
5165                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5166                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5167                if (res != 0) {
5168                    if (res < 0 && app.pid != MY_PID) {
5169                        app.kill("anr", true);
5170                    } else {
5171                        synchronized (this) {
5172                            mServices.scheduleServiceTimeoutLocked(app);
5173                        }
5174                    }
5175                    return;
5176                }
5177            } catch (RemoteException e) {
5178                mController = null;
5179                Watchdog.getInstance().setActivityController(null);
5180            }
5181        }
5182
5183        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5184        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5185                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5186
5187        synchronized (this) {
5188            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5189                app.kill("bg anr", true);
5190                return;
5191            }
5192
5193            // Set the app's notResponding state, and look up the errorReportReceiver
5194            makeAppNotRespondingLocked(app,
5195                    activity != null ? activity.shortComponentName : null,
5196                    annotation != null ? "ANR " + annotation : "ANR",
5197                    info.toString());
5198
5199            // Bring up the infamous App Not Responding dialog
5200            Message msg = Message.obtain();
5201            HashMap<String, Object> map = new HashMap<String, Object>();
5202            msg.what = SHOW_NOT_RESPONDING_MSG;
5203            msg.obj = map;
5204            msg.arg1 = aboveSystem ? 1 : 0;
5205            map.put("app", app);
5206            if (activity != null) {
5207                map.put("activity", activity);
5208            }
5209
5210            mHandler.sendMessage(msg);
5211        }
5212    }
5213
5214    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5215        if (!mLaunchWarningShown) {
5216            mLaunchWarningShown = true;
5217            mHandler.post(new Runnable() {
5218                @Override
5219                public void run() {
5220                    synchronized (ActivityManagerService.this) {
5221                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5222                        d.show();
5223                        mHandler.postDelayed(new Runnable() {
5224                            @Override
5225                            public void run() {
5226                                synchronized (ActivityManagerService.this) {
5227                                    d.dismiss();
5228                                    mLaunchWarningShown = false;
5229                                }
5230                            }
5231                        }, 4000);
5232                    }
5233                }
5234            });
5235        }
5236    }
5237
5238    @Override
5239    public boolean clearApplicationUserData(final String packageName,
5240            final IPackageDataObserver observer, int userId) {
5241        enforceNotIsolatedCaller("clearApplicationUserData");
5242        int uid = Binder.getCallingUid();
5243        int pid = Binder.getCallingPid();
5244        userId = handleIncomingUser(pid, uid,
5245                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5246        long callingId = Binder.clearCallingIdentity();
5247        try {
5248            IPackageManager pm = AppGlobals.getPackageManager();
5249            int pkgUid = -1;
5250            synchronized(this) {
5251                try {
5252                    pkgUid = pm.getPackageUid(packageName, userId);
5253                } catch (RemoteException e) {
5254                }
5255                if (pkgUid == -1) {
5256                    Slog.w(TAG, "Invalid packageName: " + packageName);
5257                    if (observer != null) {
5258                        try {
5259                            observer.onRemoveCompleted(packageName, false);
5260                        } catch (RemoteException e) {
5261                            Slog.i(TAG, "Observer no longer exists.");
5262                        }
5263                    }
5264                    return false;
5265                }
5266                if (uid == pkgUid || checkComponentPermission(
5267                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5268                        pid, uid, -1, true)
5269                        == PackageManager.PERMISSION_GRANTED) {
5270                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5271                } else {
5272                    throw new SecurityException("PID " + pid + " does not have permission "
5273                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5274                                    + " of package " + packageName);
5275                }
5276
5277                // Remove all tasks match the cleared application package and user
5278                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5279                    final TaskRecord tr = mRecentTasks.get(i);
5280                    final String taskPackageName =
5281                            tr.getBaseIntent().getComponent().getPackageName();
5282                    if (tr.userId != userId) continue;
5283                    if (!taskPackageName.equals(packageName)) continue;
5284                    removeTaskByIdLocked(tr.taskId, 0);
5285                }
5286            }
5287
5288            try {
5289                // Clear application user data
5290                pm.clearApplicationUserData(packageName, observer, userId);
5291
5292                synchronized(this) {
5293                    // Remove all permissions granted from/to this package
5294                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5295                }
5296
5297                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5298                        Uri.fromParts("package", packageName, null));
5299                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5300                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5301                        null, null, 0, null, null, null, false, false, userId);
5302            } catch (RemoteException e) {
5303            }
5304        } finally {
5305            Binder.restoreCallingIdentity(callingId);
5306        }
5307        return true;
5308    }
5309
5310    @Override
5311    public void killBackgroundProcesses(final String packageName, int userId) {
5312        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5313                != PackageManager.PERMISSION_GRANTED &&
5314                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5315                        != PackageManager.PERMISSION_GRANTED) {
5316            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5317                    + Binder.getCallingPid()
5318                    + ", uid=" + Binder.getCallingUid()
5319                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5320            Slog.w(TAG, msg);
5321            throw new SecurityException(msg);
5322        }
5323
5324        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5325                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5326        long callingId = Binder.clearCallingIdentity();
5327        try {
5328            IPackageManager pm = AppGlobals.getPackageManager();
5329            synchronized(this) {
5330                int appId = -1;
5331                try {
5332                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5333                } catch (RemoteException e) {
5334                }
5335                if (appId == -1) {
5336                    Slog.w(TAG, "Invalid packageName: " + packageName);
5337                    return;
5338                }
5339                killPackageProcessesLocked(packageName, appId, userId,
5340                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5341            }
5342        } finally {
5343            Binder.restoreCallingIdentity(callingId);
5344        }
5345    }
5346
5347    @Override
5348    public void killAllBackgroundProcesses() {
5349        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5350                != PackageManager.PERMISSION_GRANTED) {
5351            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5352                    + Binder.getCallingPid()
5353                    + ", uid=" + Binder.getCallingUid()
5354                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5355            Slog.w(TAG, msg);
5356            throw new SecurityException(msg);
5357        }
5358
5359        long callingId = Binder.clearCallingIdentity();
5360        try {
5361            synchronized(this) {
5362                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5363                final int NP = mProcessNames.getMap().size();
5364                for (int ip=0; ip<NP; ip++) {
5365                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5366                    final int NA = apps.size();
5367                    for (int ia=0; ia<NA; ia++) {
5368                        ProcessRecord app = apps.valueAt(ia);
5369                        if (app.persistent) {
5370                            // we don't kill persistent processes
5371                            continue;
5372                        }
5373                        if (app.removed) {
5374                            procs.add(app);
5375                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5376                            app.removed = true;
5377                            procs.add(app);
5378                        }
5379                    }
5380                }
5381
5382                int N = procs.size();
5383                for (int i=0; i<N; i++) {
5384                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5385                }
5386                mAllowLowerMemLevel = true;
5387                updateOomAdjLocked();
5388                doLowMemReportIfNeededLocked(null);
5389            }
5390        } finally {
5391            Binder.restoreCallingIdentity(callingId);
5392        }
5393    }
5394
5395    @Override
5396    public void forceStopPackage(final String packageName, int userId) {
5397        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5398                != PackageManager.PERMISSION_GRANTED) {
5399            String msg = "Permission Denial: forceStopPackage() from pid="
5400                    + Binder.getCallingPid()
5401                    + ", uid=" + Binder.getCallingUid()
5402                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5403            Slog.w(TAG, msg);
5404            throw new SecurityException(msg);
5405        }
5406        final int callingPid = Binder.getCallingPid();
5407        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5408                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5409        long callingId = Binder.clearCallingIdentity();
5410        try {
5411            IPackageManager pm = AppGlobals.getPackageManager();
5412            synchronized(this) {
5413                int[] users = userId == UserHandle.USER_ALL
5414                        ? getUsersLocked() : new int[] { userId };
5415                for (int user : users) {
5416                    int pkgUid = -1;
5417                    try {
5418                        pkgUid = pm.getPackageUid(packageName, user);
5419                    } catch (RemoteException e) {
5420                    }
5421                    if (pkgUid == -1) {
5422                        Slog.w(TAG, "Invalid packageName: " + packageName);
5423                        continue;
5424                    }
5425                    try {
5426                        pm.setPackageStoppedState(packageName, true, user);
5427                    } catch (RemoteException e) {
5428                    } catch (IllegalArgumentException e) {
5429                        Slog.w(TAG, "Failed trying to unstop package "
5430                                + packageName + ": " + e);
5431                    }
5432                    if (isUserRunningLocked(user, false)) {
5433                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5434                    }
5435                }
5436            }
5437        } finally {
5438            Binder.restoreCallingIdentity(callingId);
5439        }
5440    }
5441
5442    @Override
5443    public void addPackageDependency(String packageName) {
5444        synchronized (this) {
5445            int callingPid = Binder.getCallingPid();
5446            if (callingPid == Process.myPid()) {
5447                //  Yeah, um, no.
5448                Slog.w(TAG, "Can't addPackageDependency on system process");
5449                return;
5450            }
5451            ProcessRecord proc;
5452            synchronized (mPidsSelfLocked) {
5453                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5454            }
5455            if (proc != null) {
5456                if (proc.pkgDeps == null) {
5457                    proc.pkgDeps = new ArraySet<String>(1);
5458                }
5459                proc.pkgDeps.add(packageName);
5460            }
5461        }
5462    }
5463
5464    /*
5465     * The pkg name and app id have to be specified.
5466     */
5467    @Override
5468    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5469        if (pkg == null) {
5470            return;
5471        }
5472        // Make sure the uid is valid.
5473        if (appid < 0) {
5474            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5475            return;
5476        }
5477        int callerUid = Binder.getCallingUid();
5478        // Only the system server can kill an application
5479        if (callerUid == Process.SYSTEM_UID) {
5480            // Post an aysnc message to kill the application
5481            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5482            msg.arg1 = appid;
5483            msg.arg2 = 0;
5484            Bundle bundle = new Bundle();
5485            bundle.putString("pkg", pkg);
5486            bundle.putString("reason", reason);
5487            msg.obj = bundle;
5488            mHandler.sendMessage(msg);
5489        } else {
5490            throw new SecurityException(callerUid + " cannot kill pkg: " +
5491                    pkg);
5492        }
5493    }
5494
5495    @Override
5496    public void closeSystemDialogs(String reason) {
5497        enforceNotIsolatedCaller("closeSystemDialogs");
5498
5499        final int pid = Binder.getCallingPid();
5500        final int uid = Binder.getCallingUid();
5501        final long origId = Binder.clearCallingIdentity();
5502        try {
5503            synchronized (this) {
5504                // Only allow this from foreground processes, so that background
5505                // applications can't abuse it to prevent system UI from being shown.
5506                if (uid >= Process.FIRST_APPLICATION_UID) {
5507                    ProcessRecord proc;
5508                    synchronized (mPidsSelfLocked) {
5509                        proc = mPidsSelfLocked.get(pid);
5510                    }
5511                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5512                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5513                                + " from background process " + proc);
5514                        return;
5515                    }
5516                }
5517                closeSystemDialogsLocked(reason);
5518            }
5519        } finally {
5520            Binder.restoreCallingIdentity(origId);
5521        }
5522    }
5523
5524    void closeSystemDialogsLocked(String reason) {
5525        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5526        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5527                | Intent.FLAG_RECEIVER_FOREGROUND);
5528        if (reason != null) {
5529            intent.putExtra("reason", reason);
5530        }
5531        mWindowManager.closeSystemDialogs(reason);
5532
5533        mStackSupervisor.closeSystemDialogsLocked();
5534
5535        broadcastIntentLocked(null, null, intent, null,
5536                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5537                Process.SYSTEM_UID, UserHandle.USER_ALL);
5538    }
5539
5540    @Override
5541    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5542        enforceNotIsolatedCaller("getProcessMemoryInfo");
5543        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5544        for (int i=pids.length-1; i>=0; i--) {
5545            ProcessRecord proc;
5546            int oomAdj;
5547            synchronized (this) {
5548                synchronized (mPidsSelfLocked) {
5549                    proc = mPidsSelfLocked.get(pids[i]);
5550                    oomAdj = proc != null ? proc.setAdj : 0;
5551                }
5552            }
5553            infos[i] = new Debug.MemoryInfo();
5554            Debug.getMemoryInfo(pids[i], infos[i]);
5555            if (proc != null) {
5556                synchronized (this) {
5557                    if (proc.thread != null && proc.setAdj == oomAdj) {
5558                        // Record this for posterity if the process has been stable.
5559                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5560                                infos[i].getTotalUss(), false, proc.pkgList);
5561                    }
5562                }
5563            }
5564        }
5565        return infos;
5566    }
5567
5568    @Override
5569    public long[] getProcessPss(int[] pids) {
5570        enforceNotIsolatedCaller("getProcessPss");
5571        long[] pss = new long[pids.length];
5572        for (int i=pids.length-1; i>=0; i--) {
5573            ProcessRecord proc;
5574            int oomAdj;
5575            synchronized (this) {
5576                synchronized (mPidsSelfLocked) {
5577                    proc = mPidsSelfLocked.get(pids[i]);
5578                    oomAdj = proc != null ? proc.setAdj : 0;
5579                }
5580            }
5581            long[] tmpUss = new long[1];
5582            pss[i] = Debug.getPss(pids[i], tmpUss);
5583            if (proc != null) {
5584                synchronized (this) {
5585                    if (proc.thread != null && proc.setAdj == oomAdj) {
5586                        // Record this for posterity if the process has been stable.
5587                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5588                    }
5589                }
5590            }
5591        }
5592        return pss;
5593    }
5594
5595    @Override
5596    public void killApplicationProcess(String processName, int uid) {
5597        if (processName == null) {
5598            return;
5599        }
5600
5601        int callerUid = Binder.getCallingUid();
5602        // Only the system server can kill an application
5603        if (callerUid == Process.SYSTEM_UID) {
5604            synchronized (this) {
5605                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5606                if (app != null && app.thread != null) {
5607                    try {
5608                        app.thread.scheduleSuicide();
5609                    } catch (RemoteException e) {
5610                        // If the other end already died, then our work here is done.
5611                    }
5612                } else {
5613                    Slog.w(TAG, "Process/uid not found attempting kill of "
5614                            + processName + " / " + uid);
5615                }
5616            }
5617        } else {
5618            throw new SecurityException(callerUid + " cannot kill app process: " +
5619                    processName);
5620        }
5621    }
5622
5623    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5624        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5625                false, true, false, false, UserHandle.getUserId(uid), reason);
5626        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5627                Uri.fromParts("package", packageName, null));
5628        if (!mProcessesReady) {
5629            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5630                    | Intent.FLAG_RECEIVER_FOREGROUND);
5631        }
5632        intent.putExtra(Intent.EXTRA_UID, uid);
5633        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5634        broadcastIntentLocked(null, null, intent,
5635                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5636                false, false,
5637                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5638    }
5639
5640    private void forceStopUserLocked(int userId, String reason) {
5641        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5642        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5643        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5644                | Intent.FLAG_RECEIVER_FOREGROUND);
5645        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5646        broadcastIntentLocked(null, null, intent,
5647                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5648                false, false,
5649                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5650    }
5651
5652    private final boolean killPackageProcessesLocked(String packageName, int appId,
5653            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5654            boolean doit, boolean evenPersistent, String reason) {
5655        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5656
5657        // Remove all processes this package may have touched: all with the
5658        // same UID (except for the system or root user), and all whose name
5659        // matches the package name.
5660        final int NP = mProcessNames.getMap().size();
5661        for (int ip=0; ip<NP; ip++) {
5662            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5663            final int NA = apps.size();
5664            for (int ia=0; ia<NA; ia++) {
5665                ProcessRecord app = apps.valueAt(ia);
5666                if (app.persistent && !evenPersistent) {
5667                    // we don't kill persistent processes
5668                    continue;
5669                }
5670                if (app.removed) {
5671                    if (doit) {
5672                        procs.add(app);
5673                    }
5674                    continue;
5675                }
5676
5677                // Skip process if it doesn't meet our oom adj requirement.
5678                if (app.setAdj < minOomAdj) {
5679                    continue;
5680                }
5681
5682                // If no package is specified, we call all processes under the
5683                // give user id.
5684                if (packageName == null) {
5685                    if (app.userId != userId) {
5686                        continue;
5687                    }
5688                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5689                        continue;
5690                    }
5691                // Package has been specified, we want to hit all processes
5692                // that match it.  We need to qualify this by the processes
5693                // that are running under the specified app and user ID.
5694                } else {
5695                    final boolean isDep = app.pkgDeps != null
5696                            && app.pkgDeps.contains(packageName);
5697                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5698                        continue;
5699                    }
5700                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5701                        continue;
5702                    }
5703                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5704                        continue;
5705                    }
5706                }
5707
5708                // Process has passed all conditions, kill it!
5709                if (!doit) {
5710                    return true;
5711                }
5712                app.removed = true;
5713                procs.add(app);
5714            }
5715        }
5716
5717        int N = procs.size();
5718        for (int i=0; i<N; i++) {
5719            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5720        }
5721        updateOomAdjLocked();
5722        return N > 0;
5723    }
5724
5725    private final boolean forceStopPackageLocked(String name, int appId,
5726            boolean callerWillRestart, boolean purgeCache, boolean doit,
5727            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5728        int i;
5729        int N;
5730
5731        if (userId == UserHandle.USER_ALL && name == null) {
5732            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5733        }
5734
5735        if (appId < 0 && name != null) {
5736            try {
5737                appId = UserHandle.getAppId(
5738                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5739            } catch (RemoteException e) {
5740            }
5741        }
5742
5743        if (doit) {
5744            if (name != null) {
5745                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5746                        + " user=" + userId + ": " + reason);
5747            } else {
5748                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5749            }
5750
5751            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5752            for (int ip=pmap.size()-1; ip>=0; ip--) {
5753                SparseArray<Long> ba = pmap.valueAt(ip);
5754                for (i=ba.size()-1; i>=0; i--) {
5755                    boolean remove = false;
5756                    final int entUid = ba.keyAt(i);
5757                    if (name != null) {
5758                        if (userId == UserHandle.USER_ALL) {
5759                            if (UserHandle.getAppId(entUid) == appId) {
5760                                remove = true;
5761                            }
5762                        } else {
5763                            if (entUid == UserHandle.getUid(userId, appId)) {
5764                                remove = true;
5765                            }
5766                        }
5767                    } else if (UserHandle.getUserId(entUid) == userId) {
5768                        remove = true;
5769                    }
5770                    if (remove) {
5771                        ba.removeAt(i);
5772                    }
5773                }
5774                if (ba.size() == 0) {
5775                    pmap.removeAt(ip);
5776                }
5777            }
5778        }
5779
5780        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5781                -100, callerWillRestart, true, doit, evenPersistent,
5782                name == null ? ("stop user " + userId) : ("stop " + name));
5783
5784        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5785            if (!doit) {
5786                return true;
5787            }
5788            didSomething = true;
5789        }
5790
5791        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5792            if (!doit) {
5793                return true;
5794            }
5795            didSomething = true;
5796        }
5797
5798        if (name == null) {
5799            // Remove all sticky broadcasts from this user.
5800            mStickyBroadcasts.remove(userId);
5801        }
5802
5803        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5804        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5805                userId, providers)) {
5806            if (!doit) {
5807                return true;
5808            }
5809            didSomething = true;
5810        }
5811        N = providers.size();
5812        for (i=0; i<N; i++) {
5813            removeDyingProviderLocked(null, providers.get(i), true);
5814        }
5815
5816        // Remove transient permissions granted from/to this package/user
5817        removeUriPermissionsForPackageLocked(name, userId, false);
5818
5819        if (name == null || uninstalling) {
5820            // Remove pending intents.  For now we only do this when force
5821            // stopping users, because we have some problems when doing this
5822            // for packages -- app widgets are not currently cleaned up for
5823            // such packages, so they can be left with bad pending intents.
5824            if (mIntentSenderRecords.size() > 0) {
5825                Iterator<WeakReference<PendingIntentRecord>> it
5826                        = mIntentSenderRecords.values().iterator();
5827                while (it.hasNext()) {
5828                    WeakReference<PendingIntentRecord> wpir = it.next();
5829                    if (wpir == null) {
5830                        it.remove();
5831                        continue;
5832                    }
5833                    PendingIntentRecord pir = wpir.get();
5834                    if (pir == null) {
5835                        it.remove();
5836                        continue;
5837                    }
5838                    if (name == null) {
5839                        // Stopping user, remove all objects for the user.
5840                        if (pir.key.userId != userId) {
5841                            // Not the same user, skip it.
5842                            continue;
5843                        }
5844                    } else {
5845                        if (UserHandle.getAppId(pir.uid) != appId) {
5846                            // Different app id, skip it.
5847                            continue;
5848                        }
5849                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5850                            // Different user, skip it.
5851                            continue;
5852                        }
5853                        if (!pir.key.packageName.equals(name)) {
5854                            // Different package, skip it.
5855                            continue;
5856                        }
5857                    }
5858                    if (!doit) {
5859                        return true;
5860                    }
5861                    didSomething = true;
5862                    it.remove();
5863                    pir.canceled = true;
5864                    if (pir.key.activity != null) {
5865                        pir.key.activity.pendingResults.remove(pir.ref);
5866                    }
5867                }
5868            }
5869        }
5870
5871        if (doit) {
5872            if (purgeCache && name != null) {
5873                AttributeCache ac = AttributeCache.instance();
5874                if (ac != null) {
5875                    ac.removePackage(name);
5876                }
5877            }
5878            if (mBooted) {
5879                mStackSupervisor.resumeTopActivitiesLocked();
5880                mStackSupervisor.scheduleIdleLocked();
5881            }
5882        }
5883
5884        return didSomething;
5885    }
5886
5887    private final boolean removeProcessLocked(ProcessRecord app,
5888            boolean callerWillRestart, boolean allowRestart, String reason) {
5889        final String name = app.processName;
5890        final int uid = app.uid;
5891        if (DEBUG_PROCESSES) Slog.d(
5892            TAG, "Force removing proc " + app.toShortString() + " (" + name
5893            + "/" + uid + ")");
5894
5895        mProcessNames.remove(name, uid);
5896        mIsolatedProcesses.remove(app.uid);
5897        if (mHeavyWeightProcess == app) {
5898            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5899                    mHeavyWeightProcess.userId, 0));
5900            mHeavyWeightProcess = null;
5901        }
5902        boolean needRestart = false;
5903        if (app.pid > 0 && app.pid != MY_PID) {
5904            int pid = app.pid;
5905            synchronized (mPidsSelfLocked) {
5906                mPidsSelfLocked.remove(pid);
5907                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5908            }
5909            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5910            if (app.isolated) {
5911                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5912            }
5913            app.kill(reason, true);
5914            handleAppDiedLocked(app, true, allowRestart);
5915            removeLruProcessLocked(app);
5916
5917            if (app.persistent && !app.isolated) {
5918                if (!callerWillRestart) {
5919                    addAppLocked(app.info, false, null /* ABI override */);
5920                } else {
5921                    needRestart = true;
5922                }
5923            }
5924        } else {
5925            mRemovedProcesses.add(app);
5926        }
5927
5928        return needRestart;
5929    }
5930
5931    private final void processStartTimedOutLocked(ProcessRecord app) {
5932        final int pid = app.pid;
5933        boolean gone = false;
5934        synchronized (mPidsSelfLocked) {
5935            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5936            if (knownApp != null && knownApp.thread == null) {
5937                mPidsSelfLocked.remove(pid);
5938                gone = true;
5939            }
5940        }
5941
5942        if (gone) {
5943            Slog.w(TAG, "Process " + app + " failed to attach");
5944            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5945                    pid, app.uid, app.processName);
5946            mProcessNames.remove(app.processName, app.uid);
5947            mIsolatedProcesses.remove(app.uid);
5948            if (mHeavyWeightProcess == app) {
5949                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5950                        mHeavyWeightProcess.userId, 0));
5951                mHeavyWeightProcess = null;
5952            }
5953            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5954            if (app.isolated) {
5955                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5956            }
5957            // Take care of any launching providers waiting for this process.
5958            checkAppInLaunchingProvidersLocked(app, true);
5959            // Take care of any services that are waiting for the process.
5960            mServices.processStartTimedOutLocked(app);
5961            app.kill("start timeout", true);
5962            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5963                Slog.w(TAG, "Unattached app died before backup, skipping");
5964                try {
5965                    IBackupManager bm = IBackupManager.Stub.asInterface(
5966                            ServiceManager.getService(Context.BACKUP_SERVICE));
5967                    bm.agentDisconnected(app.info.packageName);
5968                } catch (RemoteException e) {
5969                    // Can't happen; the backup manager is local
5970                }
5971            }
5972            if (isPendingBroadcastProcessLocked(pid)) {
5973                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5974                skipPendingBroadcastLocked(pid);
5975            }
5976        } else {
5977            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5978        }
5979    }
5980
5981    private final boolean attachApplicationLocked(IApplicationThread thread,
5982            int pid) {
5983
5984        // Find the application record that is being attached...  either via
5985        // the pid if we are running in multiple processes, or just pull the
5986        // next app record if we are emulating process with anonymous threads.
5987        ProcessRecord app;
5988        if (pid != MY_PID && pid >= 0) {
5989            synchronized (mPidsSelfLocked) {
5990                app = mPidsSelfLocked.get(pid);
5991            }
5992        } else {
5993            app = null;
5994        }
5995
5996        if (app == null) {
5997            Slog.w(TAG, "No pending application record for pid " + pid
5998                    + " (IApplicationThread " + thread + "); dropping process");
5999            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6000            if (pid > 0 && pid != MY_PID) {
6001                Process.killProcessQuiet(pid);
6002                //TODO: Process.killProcessGroup(app.info.uid, pid);
6003            } else {
6004                try {
6005                    thread.scheduleExit();
6006                } catch (Exception e) {
6007                    // Ignore exceptions.
6008                }
6009            }
6010            return false;
6011        }
6012
6013        // If this application record is still attached to a previous
6014        // process, clean it up now.
6015        if (app.thread != null) {
6016            handleAppDiedLocked(app, true, true);
6017        }
6018
6019        // Tell the process all about itself.
6020
6021        if (localLOGV) Slog.v(
6022                TAG, "Binding process pid " + pid + " to record " + app);
6023
6024        final String processName = app.processName;
6025        try {
6026            AppDeathRecipient adr = new AppDeathRecipient(
6027                    app, pid, thread);
6028            thread.asBinder().linkToDeath(adr, 0);
6029            app.deathRecipient = adr;
6030        } catch (RemoteException e) {
6031            app.resetPackageList(mProcessStats);
6032            startProcessLocked(app, "link fail", processName);
6033            return false;
6034        }
6035
6036        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6037
6038        app.makeActive(thread, mProcessStats);
6039        app.curAdj = app.setAdj = -100;
6040        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6041        app.forcingToForeground = null;
6042        updateProcessForegroundLocked(app, false, false);
6043        app.hasShownUi = false;
6044        app.debugging = false;
6045        app.cached = false;
6046
6047        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6048
6049        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6050        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6051
6052        if (!normalMode) {
6053            Slog.i(TAG, "Launching preboot mode app: " + app);
6054        }
6055
6056        if (localLOGV) Slog.v(
6057            TAG, "New app record " + app
6058            + " thread=" + thread.asBinder() + " pid=" + pid);
6059        try {
6060            int testMode = IApplicationThread.DEBUG_OFF;
6061            if (mDebugApp != null && mDebugApp.equals(processName)) {
6062                testMode = mWaitForDebugger
6063                    ? IApplicationThread.DEBUG_WAIT
6064                    : IApplicationThread.DEBUG_ON;
6065                app.debugging = true;
6066                if (mDebugTransient) {
6067                    mDebugApp = mOrigDebugApp;
6068                    mWaitForDebugger = mOrigWaitForDebugger;
6069                }
6070            }
6071            String profileFile = app.instrumentationProfileFile;
6072            ParcelFileDescriptor profileFd = null;
6073            int samplingInterval = 0;
6074            boolean profileAutoStop = false;
6075            if (mProfileApp != null && mProfileApp.equals(processName)) {
6076                mProfileProc = app;
6077                profileFile = mProfileFile;
6078                profileFd = mProfileFd;
6079                samplingInterval = mSamplingInterval;
6080                profileAutoStop = mAutoStopProfiler;
6081            }
6082            boolean enableOpenGlTrace = false;
6083            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6084                enableOpenGlTrace = true;
6085                mOpenGlTraceApp = null;
6086            }
6087
6088            // If the app is being launched for restore or full backup, set it up specially
6089            boolean isRestrictedBackupMode = false;
6090            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6091                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6092                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6093                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6094            }
6095
6096            ensurePackageDexOpt(app.instrumentationInfo != null
6097                    ? app.instrumentationInfo.packageName
6098                    : app.info.packageName);
6099            if (app.instrumentationClass != null) {
6100                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6101            }
6102            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6103                    + processName + " with config " + mConfiguration);
6104            ApplicationInfo appInfo = app.instrumentationInfo != null
6105                    ? app.instrumentationInfo : app.info;
6106            app.compat = compatibilityInfoForPackageLocked(appInfo);
6107            if (profileFd != null) {
6108                profileFd = profileFd.dup();
6109            }
6110            ProfilerInfo profilerInfo = profileFile == null ? null
6111                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6112            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6113                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6114                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6115                    isRestrictedBackupMode || !normalMode, app.persistent,
6116                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6117                    mCoreSettingsObserver.getCoreSettingsLocked());
6118            updateLruProcessLocked(app, false, null);
6119            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6120        } catch (Exception e) {
6121            // todo: Yikes!  What should we do?  For now we will try to
6122            // start another process, but that could easily get us in
6123            // an infinite loop of restarting processes...
6124            Slog.w(TAG, "Exception thrown during bind!", e);
6125
6126            app.resetPackageList(mProcessStats);
6127            app.unlinkDeathRecipient();
6128            startProcessLocked(app, "bind fail", processName);
6129            return false;
6130        }
6131
6132        // Remove this record from the list of starting applications.
6133        mPersistentStartingProcesses.remove(app);
6134        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6135                "Attach application locked removing on hold: " + app);
6136        mProcessesOnHold.remove(app);
6137
6138        boolean badApp = false;
6139        boolean didSomething = false;
6140
6141        // See if the top visible activity is waiting to run in this process...
6142        if (normalMode) {
6143            try {
6144                if (mStackSupervisor.attachApplicationLocked(app)) {
6145                    didSomething = true;
6146                }
6147            } catch (Exception e) {
6148                badApp = true;
6149            }
6150        }
6151
6152        // Find any services that should be running in this process...
6153        if (!badApp) {
6154            try {
6155                didSomething |= mServices.attachApplicationLocked(app, processName);
6156            } catch (Exception e) {
6157                badApp = true;
6158            }
6159        }
6160
6161        // Check if a next-broadcast receiver is in this process...
6162        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6163            try {
6164                didSomething |= sendPendingBroadcastsLocked(app);
6165            } catch (Exception e) {
6166                // If the app died trying to launch the receiver we declare it 'bad'
6167                badApp = true;
6168            }
6169        }
6170
6171        // Check whether the next backup agent is in this process...
6172        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6173            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6174            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6175            try {
6176                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6177                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6178                        mBackupTarget.backupMode);
6179            } catch (Exception e) {
6180                Slog.w(TAG, "Exception scheduling backup agent creation: ");
6181                e.printStackTrace();
6182            }
6183        }
6184
6185        if (badApp) {
6186            // todo: Also need to kill application to deal with all
6187            // kinds of exceptions.
6188            handleAppDiedLocked(app, false, true);
6189            return false;
6190        }
6191
6192        if (!didSomething) {
6193            updateOomAdjLocked();
6194        }
6195
6196        return true;
6197    }
6198
6199    @Override
6200    public final void attachApplication(IApplicationThread thread) {
6201        synchronized (this) {
6202            int callingPid = Binder.getCallingPid();
6203            final long origId = Binder.clearCallingIdentity();
6204            attachApplicationLocked(thread, callingPid);
6205            Binder.restoreCallingIdentity(origId);
6206        }
6207    }
6208
6209    @Override
6210    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6211        final long origId = Binder.clearCallingIdentity();
6212        synchronized (this) {
6213            ActivityStack stack = ActivityRecord.getStackLocked(token);
6214            if (stack != null) {
6215                ActivityRecord r =
6216                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6217                if (stopProfiling) {
6218                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6219                        try {
6220                            mProfileFd.close();
6221                        } catch (IOException e) {
6222                        }
6223                        clearProfilerLocked();
6224                    }
6225                }
6226            }
6227        }
6228        Binder.restoreCallingIdentity(origId);
6229    }
6230
6231    void postEnableScreenAfterBootLocked() {
6232        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6233    }
6234
6235    void enableScreenAfterBoot() {
6236        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6237                SystemClock.uptimeMillis());
6238        mWindowManager.enableScreenAfterBoot();
6239
6240        synchronized (this) {
6241            updateEventDispatchingLocked();
6242        }
6243    }
6244
6245    @Override
6246    public void showBootMessage(final CharSequence msg, final boolean always) {
6247        enforceNotIsolatedCaller("showBootMessage");
6248        mWindowManager.showBootMessage(msg, always);
6249    }
6250
6251    @Override
6252    public void keyguardWaitingForActivityDrawn() {
6253        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6254        final long token = Binder.clearCallingIdentity();
6255        try {
6256            synchronized (this) {
6257                if (DEBUG_LOCKSCREEN) logLockScreen("");
6258                mWindowManager.keyguardWaitingForActivityDrawn();
6259                mKeyguardWaitingForDraw = true;
6260            }
6261        } finally {
6262            Binder.restoreCallingIdentity(token);
6263        }
6264    }
6265
6266    final void finishBooting() {
6267        synchronized (this) {
6268            if (!mBootAnimationComplete) {
6269                mCallFinishBooting = true;
6270                return;
6271            }
6272            mCallFinishBooting = false;
6273        }
6274
6275        // Register receivers to handle package update events
6276        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
6277
6278        // Let system services know.
6279        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6280
6281        synchronized (this) {
6282            // Ensure that any processes we had put on hold are now started
6283            // up.
6284            final int NP = mProcessesOnHold.size();
6285            if (NP > 0) {
6286                ArrayList<ProcessRecord> procs =
6287                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6288                for (int ip=0; ip<NP; ip++) {
6289                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6290                            + procs.get(ip));
6291                    startProcessLocked(procs.get(ip), "on-hold", null);
6292                }
6293            }
6294
6295            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6296                // Start looking for apps that are abusing wake locks.
6297                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6298                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6299                // Tell anyone interested that we are done booting!
6300                SystemProperties.set("sys.boot_completed", "1");
6301                SystemProperties.set("dev.bootcomplete", "1");
6302                for (int i=0; i<mStartedUsers.size(); i++) {
6303                    UserStartedState uss = mStartedUsers.valueAt(i);
6304                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6305                        uss.mState = UserStartedState.STATE_RUNNING;
6306                        final int userId = mStartedUsers.keyAt(i);
6307                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6308                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6309                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6310                        broadcastIntentLocked(null, null, intent, null,
6311                                new IIntentReceiver.Stub() {
6312                                    @Override
6313                                    public void performReceive(Intent intent, int resultCode,
6314                                            String data, Bundle extras, boolean ordered,
6315                                            boolean sticky, int sendingUser) {
6316                                        synchronized (ActivityManagerService.this) {
6317                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6318                                                    true, false);
6319                                        }
6320                                    }
6321                                },
6322                                0, null, null,
6323                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6324                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6325                                userId);
6326                    }
6327                }
6328                scheduleStartProfilesLocked();
6329            }
6330        }
6331    }
6332
6333    @Override
6334    public void bootAnimationComplete() {
6335        final boolean callFinishBooting;
6336        synchronized (this) {
6337            callFinishBooting = mCallFinishBooting;
6338            mBootAnimationComplete = true;
6339        }
6340        if (callFinishBooting) {
6341            finishBooting();
6342        }
6343    }
6344
6345    final void ensureBootCompleted() {
6346        boolean booting;
6347        boolean enableScreen;
6348        synchronized (this) {
6349            booting = mBooting;
6350            mBooting = false;
6351            enableScreen = !mBooted;
6352            mBooted = true;
6353        }
6354
6355        if (booting) {
6356            finishBooting();
6357        }
6358
6359        if (enableScreen) {
6360            enableScreenAfterBoot();
6361        }
6362    }
6363
6364    @Override
6365    public final void activityResumed(IBinder token) {
6366        final long origId = Binder.clearCallingIdentity();
6367        synchronized(this) {
6368            ActivityStack stack = ActivityRecord.getStackLocked(token);
6369            if (stack != null) {
6370                ActivityRecord.activityResumedLocked(token);
6371            }
6372        }
6373        Binder.restoreCallingIdentity(origId);
6374    }
6375
6376    @Override
6377    public final void activityPaused(IBinder token) {
6378        final long origId = Binder.clearCallingIdentity();
6379        synchronized(this) {
6380            ActivityStack stack = ActivityRecord.getStackLocked(token);
6381            if (stack != null) {
6382                stack.activityPausedLocked(token, false);
6383            }
6384        }
6385        Binder.restoreCallingIdentity(origId);
6386    }
6387
6388    @Override
6389    public final void activityStopped(IBinder token, Bundle icicle,
6390            PersistableBundle persistentState, CharSequence description) {
6391        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6392
6393        // Refuse possible leaked file descriptors
6394        if (icicle != null && icicle.hasFileDescriptors()) {
6395            throw new IllegalArgumentException("File descriptors passed in Bundle");
6396        }
6397
6398        final long origId = Binder.clearCallingIdentity();
6399
6400        synchronized (this) {
6401            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6402            if (r != null) {
6403                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6404            }
6405        }
6406
6407        trimApplications();
6408
6409        Binder.restoreCallingIdentity(origId);
6410    }
6411
6412    @Override
6413    public final void activityDestroyed(IBinder token) {
6414        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6415        synchronized (this) {
6416            ActivityStack stack = ActivityRecord.getStackLocked(token);
6417            if (stack != null) {
6418                stack.activityDestroyedLocked(token);
6419            }
6420        }
6421    }
6422
6423    @Override
6424    public final void backgroundResourcesReleased(IBinder token) {
6425        final long origId = Binder.clearCallingIdentity();
6426        try {
6427            synchronized (this) {
6428                ActivityStack stack = ActivityRecord.getStackLocked(token);
6429                if (stack != null) {
6430                    stack.backgroundResourcesReleased(token);
6431                }
6432            }
6433        } finally {
6434            Binder.restoreCallingIdentity(origId);
6435        }
6436    }
6437
6438    @Override
6439    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6440        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6441    }
6442
6443    @Override
6444    public final void notifyEnterAnimationComplete(IBinder token) {
6445        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6446    }
6447
6448    @Override
6449    public String getCallingPackage(IBinder token) {
6450        synchronized (this) {
6451            ActivityRecord r = getCallingRecordLocked(token);
6452            return r != null ? r.info.packageName : null;
6453        }
6454    }
6455
6456    @Override
6457    public ComponentName getCallingActivity(IBinder token) {
6458        synchronized (this) {
6459            ActivityRecord r = getCallingRecordLocked(token);
6460            return r != null ? r.intent.getComponent() : null;
6461        }
6462    }
6463
6464    private ActivityRecord getCallingRecordLocked(IBinder token) {
6465        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6466        if (r == null) {
6467            return null;
6468        }
6469        return r.resultTo;
6470    }
6471
6472    @Override
6473    public ComponentName getActivityClassForToken(IBinder token) {
6474        synchronized(this) {
6475            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6476            if (r == null) {
6477                return null;
6478            }
6479            return r.intent.getComponent();
6480        }
6481    }
6482
6483    @Override
6484    public String getPackageForToken(IBinder token) {
6485        synchronized(this) {
6486            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6487            if (r == null) {
6488                return null;
6489            }
6490            return r.packageName;
6491        }
6492    }
6493
6494    @Override
6495    public IIntentSender getIntentSender(int type,
6496            String packageName, IBinder token, String resultWho,
6497            int requestCode, Intent[] intents, String[] resolvedTypes,
6498            int flags, Bundle options, int userId) {
6499        enforceNotIsolatedCaller("getIntentSender");
6500        // Refuse possible leaked file descriptors
6501        if (intents != null) {
6502            if (intents.length < 1) {
6503                throw new IllegalArgumentException("Intents array length must be >= 1");
6504            }
6505            for (int i=0; i<intents.length; i++) {
6506                Intent intent = intents[i];
6507                if (intent != null) {
6508                    if (intent.hasFileDescriptors()) {
6509                        throw new IllegalArgumentException("File descriptors passed in Intent");
6510                    }
6511                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6512                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6513                        throw new IllegalArgumentException(
6514                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6515                    }
6516                    intents[i] = new Intent(intent);
6517                }
6518            }
6519            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6520                throw new IllegalArgumentException(
6521                        "Intent array length does not match resolvedTypes length");
6522            }
6523        }
6524        if (options != null) {
6525            if (options.hasFileDescriptors()) {
6526                throw new IllegalArgumentException("File descriptors passed in options");
6527            }
6528        }
6529
6530        synchronized(this) {
6531            int callingUid = Binder.getCallingUid();
6532            int origUserId = userId;
6533            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6534                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6535                    ALLOW_NON_FULL, "getIntentSender", null);
6536            if (origUserId == UserHandle.USER_CURRENT) {
6537                // We don't want to evaluate this until the pending intent is
6538                // actually executed.  However, we do want to always do the
6539                // security checking for it above.
6540                userId = UserHandle.USER_CURRENT;
6541            }
6542            try {
6543                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6544                    int uid = AppGlobals.getPackageManager()
6545                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6546                    if (!UserHandle.isSameApp(callingUid, uid)) {
6547                        String msg = "Permission Denial: getIntentSender() from pid="
6548                            + Binder.getCallingPid()
6549                            + ", uid=" + Binder.getCallingUid()
6550                            + ", (need uid=" + uid + ")"
6551                            + " is not allowed to send as package " + packageName;
6552                        Slog.w(TAG, msg);
6553                        throw new SecurityException(msg);
6554                    }
6555                }
6556
6557                return getIntentSenderLocked(type, packageName, callingUid, userId,
6558                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6559
6560            } catch (RemoteException e) {
6561                throw new SecurityException(e);
6562            }
6563        }
6564    }
6565
6566    IIntentSender getIntentSenderLocked(int type, String packageName,
6567            int callingUid, int userId, IBinder token, String resultWho,
6568            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6569            Bundle options) {
6570        if (DEBUG_MU)
6571            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6572        ActivityRecord activity = null;
6573        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6574            activity = ActivityRecord.isInStackLocked(token);
6575            if (activity == null) {
6576                return null;
6577            }
6578            if (activity.finishing) {
6579                return null;
6580            }
6581        }
6582
6583        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6584        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6585        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6586        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6587                |PendingIntent.FLAG_UPDATE_CURRENT);
6588
6589        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6590                type, packageName, activity, resultWho,
6591                requestCode, intents, resolvedTypes, flags, options, userId);
6592        WeakReference<PendingIntentRecord> ref;
6593        ref = mIntentSenderRecords.get(key);
6594        PendingIntentRecord rec = ref != null ? ref.get() : null;
6595        if (rec != null) {
6596            if (!cancelCurrent) {
6597                if (updateCurrent) {
6598                    if (rec.key.requestIntent != null) {
6599                        rec.key.requestIntent.replaceExtras(intents != null ?
6600                                intents[intents.length - 1] : null);
6601                    }
6602                    if (intents != null) {
6603                        intents[intents.length-1] = rec.key.requestIntent;
6604                        rec.key.allIntents = intents;
6605                        rec.key.allResolvedTypes = resolvedTypes;
6606                    } else {
6607                        rec.key.allIntents = null;
6608                        rec.key.allResolvedTypes = null;
6609                    }
6610                }
6611                return rec;
6612            }
6613            rec.canceled = true;
6614            mIntentSenderRecords.remove(key);
6615        }
6616        if (noCreate) {
6617            return rec;
6618        }
6619        rec = new PendingIntentRecord(this, key, callingUid);
6620        mIntentSenderRecords.put(key, rec.ref);
6621        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6622            if (activity.pendingResults == null) {
6623                activity.pendingResults
6624                        = new HashSet<WeakReference<PendingIntentRecord>>();
6625            }
6626            activity.pendingResults.add(rec.ref);
6627        }
6628        return rec;
6629    }
6630
6631    @Override
6632    public void cancelIntentSender(IIntentSender sender) {
6633        if (!(sender instanceof PendingIntentRecord)) {
6634            return;
6635        }
6636        synchronized(this) {
6637            PendingIntentRecord rec = (PendingIntentRecord)sender;
6638            try {
6639                int uid = AppGlobals.getPackageManager()
6640                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6641                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6642                    String msg = "Permission Denial: cancelIntentSender() from pid="
6643                        + Binder.getCallingPid()
6644                        + ", uid=" + Binder.getCallingUid()
6645                        + " is not allowed to cancel packges "
6646                        + rec.key.packageName;
6647                    Slog.w(TAG, msg);
6648                    throw new SecurityException(msg);
6649                }
6650            } catch (RemoteException e) {
6651                throw new SecurityException(e);
6652            }
6653            cancelIntentSenderLocked(rec, true);
6654        }
6655    }
6656
6657    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6658        rec.canceled = true;
6659        mIntentSenderRecords.remove(rec.key);
6660        if (cleanActivity && rec.key.activity != null) {
6661            rec.key.activity.pendingResults.remove(rec.ref);
6662        }
6663    }
6664
6665    @Override
6666    public String getPackageForIntentSender(IIntentSender pendingResult) {
6667        if (!(pendingResult instanceof PendingIntentRecord)) {
6668            return null;
6669        }
6670        try {
6671            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6672            return res.key.packageName;
6673        } catch (ClassCastException e) {
6674        }
6675        return null;
6676    }
6677
6678    @Override
6679    public int getUidForIntentSender(IIntentSender sender) {
6680        if (sender instanceof PendingIntentRecord) {
6681            try {
6682                PendingIntentRecord res = (PendingIntentRecord)sender;
6683                return res.uid;
6684            } catch (ClassCastException e) {
6685            }
6686        }
6687        return -1;
6688    }
6689
6690    @Override
6691    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6692        if (!(pendingResult instanceof PendingIntentRecord)) {
6693            return false;
6694        }
6695        try {
6696            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6697            if (res.key.allIntents == null) {
6698                return false;
6699            }
6700            for (int i=0; i<res.key.allIntents.length; i++) {
6701                Intent intent = res.key.allIntents[i];
6702                if (intent.getPackage() != null && intent.getComponent() != null) {
6703                    return false;
6704                }
6705            }
6706            return true;
6707        } catch (ClassCastException e) {
6708        }
6709        return false;
6710    }
6711
6712    @Override
6713    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6714        if (!(pendingResult instanceof PendingIntentRecord)) {
6715            return false;
6716        }
6717        try {
6718            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6719            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6720                return true;
6721            }
6722            return false;
6723        } catch (ClassCastException e) {
6724        }
6725        return false;
6726    }
6727
6728    @Override
6729    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6730        if (!(pendingResult instanceof PendingIntentRecord)) {
6731            return null;
6732        }
6733        try {
6734            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6735            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6736        } catch (ClassCastException e) {
6737        }
6738        return null;
6739    }
6740
6741    @Override
6742    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6743        if (!(pendingResult instanceof PendingIntentRecord)) {
6744            return null;
6745        }
6746        try {
6747            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6748            Intent intent = res.key.requestIntent;
6749            if (intent != null) {
6750                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6751                        || res.lastTagPrefix.equals(prefix))) {
6752                    return res.lastTag;
6753                }
6754                res.lastTagPrefix = prefix;
6755                StringBuilder sb = new StringBuilder(128);
6756                if (prefix != null) {
6757                    sb.append(prefix);
6758                }
6759                if (intent.getAction() != null) {
6760                    sb.append(intent.getAction());
6761                } else if (intent.getComponent() != null) {
6762                    intent.getComponent().appendShortString(sb);
6763                } else {
6764                    sb.append("?");
6765                }
6766                return res.lastTag = sb.toString();
6767            }
6768        } catch (ClassCastException e) {
6769        }
6770        return null;
6771    }
6772
6773    @Override
6774    public void setProcessLimit(int max) {
6775        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6776                "setProcessLimit()");
6777        synchronized (this) {
6778            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6779            mProcessLimitOverride = max;
6780        }
6781        trimApplications();
6782    }
6783
6784    @Override
6785    public int getProcessLimit() {
6786        synchronized (this) {
6787            return mProcessLimitOverride;
6788        }
6789    }
6790
6791    void foregroundTokenDied(ForegroundToken token) {
6792        synchronized (ActivityManagerService.this) {
6793            synchronized (mPidsSelfLocked) {
6794                ForegroundToken cur
6795                    = mForegroundProcesses.get(token.pid);
6796                if (cur != token) {
6797                    return;
6798                }
6799                mForegroundProcesses.remove(token.pid);
6800                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6801                if (pr == null) {
6802                    return;
6803                }
6804                pr.forcingToForeground = null;
6805                updateProcessForegroundLocked(pr, false, false);
6806            }
6807            updateOomAdjLocked();
6808        }
6809    }
6810
6811    @Override
6812    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6813        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6814                "setProcessForeground()");
6815        synchronized(this) {
6816            boolean changed = false;
6817
6818            synchronized (mPidsSelfLocked) {
6819                ProcessRecord pr = mPidsSelfLocked.get(pid);
6820                if (pr == null && isForeground) {
6821                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6822                    return;
6823                }
6824                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6825                if (oldToken != null) {
6826                    oldToken.token.unlinkToDeath(oldToken, 0);
6827                    mForegroundProcesses.remove(pid);
6828                    if (pr != null) {
6829                        pr.forcingToForeground = null;
6830                    }
6831                    changed = true;
6832                }
6833                if (isForeground && token != null) {
6834                    ForegroundToken newToken = new ForegroundToken() {
6835                        @Override
6836                        public void binderDied() {
6837                            foregroundTokenDied(this);
6838                        }
6839                    };
6840                    newToken.pid = pid;
6841                    newToken.token = token;
6842                    try {
6843                        token.linkToDeath(newToken, 0);
6844                        mForegroundProcesses.put(pid, newToken);
6845                        pr.forcingToForeground = token;
6846                        changed = true;
6847                    } catch (RemoteException e) {
6848                        // If the process died while doing this, we will later
6849                        // do the cleanup with the process death link.
6850                    }
6851                }
6852            }
6853
6854            if (changed) {
6855                updateOomAdjLocked();
6856            }
6857        }
6858    }
6859
6860    // =========================================================
6861    // PERMISSIONS
6862    // =========================================================
6863
6864    static class PermissionController extends IPermissionController.Stub {
6865        ActivityManagerService mActivityManagerService;
6866        PermissionController(ActivityManagerService activityManagerService) {
6867            mActivityManagerService = activityManagerService;
6868        }
6869
6870        @Override
6871        public boolean checkPermission(String permission, int pid, int uid) {
6872            return mActivityManagerService.checkPermission(permission, pid,
6873                    uid) == PackageManager.PERMISSION_GRANTED;
6874        }
6875    }
6876
6877    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6878        @Override
6879        public int checkComponentPermission(String permission, int pid, int uid,
6880                int owningUid, boolean exported) {
6881            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6882                    owningUid, exported);
6883        }
6884
6885        @Override
6886        public Object getAMSLock() {
6887            return ActivityManagerService.this;
6888        }
6889    }
6890
6891    /**
6892     * This can be called with or without the global lock held.
6893     */
6894    int checkComponentPermission(String permission, int pid, int uid,
6895            int owningUid, boolean exported) {
6896        // We might be performing an operation on behalf of an indirect binder
6897        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6898        // client identity accordingly before proceeding.
6899        Identity tlsIdentity = sCallerIdentity.get();
6900        if (tlsIdentity != null) {
6901            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6902                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6903            uid = tlsIdentity.uid;
6904            pid = tlsIdentity.pid;
6905        }
6906
6907        if (pid == MY_PID) {
6908            return PackageManager.PERMISSION_GRANTED;
6909        }
6910
6911        return ActivityManager.checkComponentPermission(permission, uid,
6912                owningUid, exported);
6913    }
6914
6915    /**
6916     * As the only public entry point for permissions checking, this method
6917     * can enforce the semantic that requesting a check on a null global
6918     * permission is automatically denied.  (Internally a null permission
6919     * string is used when calling {@link #checkComponentPermission} in cases
6920     * when only uid-based security is needed.)
6921     *
6922     * This can be called with or without the global lock held.
6923     */
6924    @Override
6925    public int checkPermission(String permission, int pid, int uid) {
6926        if (permission == null) {
6927            return PackageManager.PERMISSION_DENIED;
6928        }
6929        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6930    }
6931
6932    /**
6933     * Binder IPC calls go through the public entry point.
6934     * This can be called with or without the global lock held.
6935     */
6936    int checkCallingPermission(String permission) {
6937        return checkPermission(permission,
6938                Binder.getCallingPid(),
6939                UserHandle.getAppId(Binder.getCallingUid()));
6940    }
6941
6942    /**
6943     * This can be called with or without the global lock held.
6944     */
6945    void enforceCallingPermission(String permission, String func) {
6946        if (checkCallingPermission(permission)
6947                == PackageManager.PERMISSION_GRANTED) {
6948            return;
6949        }
6950
6951        String msg = "Permission Denial: " + func + " from pid="
6952                + Binder.getCallingPid()
6953                + ", uid=" + Binder.getCallingUid()
6954                + " requires " + permission;
6955        Slog.w(TAG, msg);
6956        throw new SecurityException(msg);
6957    }
6958
6959    /**
6960     * Determine if UID is holding permissions required to access {@link Uri} in
6961     * the given {@link ProviderInfo}. Final permission checking is always done
6962     * in {@link ContentProvider}.
6963     */
6964    private final boolean checkHoldingPermissionsLocked(
6965            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6966        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6967                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6968        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6969            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6970                    != PERMISSION_GRANTED) {
6971                return false;
6972            }
6973        }
6974        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6975    }
6976
6977    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6978            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6979        if (pi.applicationInfo.uid == uid) {
6980            return true;
6981        } else if (!pi.exported) {
6982            return false;
6983        }
6984
6985        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6986        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6987        try {
6988            // check if target holds top-level <provider> permissions
6989            if (!readMet && pi.readPermission != null && considerUidPermissions
6990                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6991                readMet = true;
6992            }
6993            if (!writeMet && pi.writePermission != null && considerUidPermissions
6994                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6995                writeMet = true;
6996            }
6997
6998            // track if unprotected read/write is allowed; any denied
6999            // <path-permission> below removes this ability
7000            boolean allowDefaultRead = pi.readPermission == null;
7001            boolean allowDefaultWrite = pi.writePermission == null;
7002
7003            // check if target holds any <path-permission> that match uri
7004            final PathPermission[] pps = pi.pathPermissions;
7005            if (pps != null) {
7006                final String path = grantUri.uri.getPath();
7007                int i = pps.length;
7008                while (i > 0 && (!readMet || !writeMet)) {
7009                    i--;
7010                    PathPermission pp = pps[i];
7011                    if (pp.match(path)) {
7012                        if (!readMet) {
7013                            final String pprperm = pp.getReadPermission();
7014                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7015                                    + pprperm + " for " + pp.getPath()
7016                                    + ": match=" + pp.match(path)
7017                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7018                            if (pprperm != null) {
7019                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7020                                        == PERMISSION_GRANTED) {
7021                                    readMet = true;
7022                                } else {
7023                                    allowDefaultRead = false;
7024                                }
7025                            }
7026                        }
7027                        if (!writeMet) {
7028                            final String ppwperm = pp.getWritePermission();
7029                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7030                                    + ppwperm + " for " + pp.getPath()
7031                                    + ": match=" + pp.match(path)
7032                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7033                            if (ppwperm != null) {
7034                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7035                                        == PERMISSION_GRANTED) {
7036                                    writeMet = true;
7037                                } else {
7038                                    allowDefaultWrite = false;
7039                                }
7040                            }
7041                        }
7042                    }
7043                }
7044            }
7045
7046            // grant unprotected <provider> read/write, if not blocked by
7047            // <path-permission> above
7048            if (allowDefaultRead) readMet = true;
7049            if (allowDefaultWrite) writeMet = true;
7050
7051        } catch (RemoteException e) {
7052            return false;
7053        }
7054
7055        return readMet && writeMet;
7056    }
7057
7058    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7059        ProviderInfo pi = null;
7060        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7061        if (cpr != null) {
7062            pi = cpr.info;
7063        } else {
7064            try {
7065                pi = AppGlobals.getPackageManager().resolveContentProvider(
7066                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7067            } catch (RemoteException ex) {
7068            }
7069        }
7070        return pi;
7071    }
7072
7073    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7074        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7075        if (targetUris != null) {
7076            return targetUris.get(grantUri);
7077        }
7078        return null;
7079    }
7080
7081    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7082            String targetPkg, int targetUid, GrantUri grantUri) {
7083        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7084        if (targetUris == null) {
7085            targetUris = Maps.newArrayMap();
7086            mGrantedUriPermissions.put(targetUid, targetUris);
7087        }
7088
7089        UriPermission perm = targetUris.get(grantUri);
7090        if (perm == null) {
7091            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7092            targetUris.put(grantUri, perm);
7093        }
7094
7095        return perm;
7096    }
7097
7098    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7099            final int modeFlags) {
7100        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7101        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7102                : UriPermission.STRENGTH_OWNED;
7103
7104        // Root gets to do everything.
7105        if (uid == 0) {
7106            return true;
7107        }
7108
7109        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7110        if (perms == null) return false;
7111
7112        // First look for exact match
7113        final UriPermission exactPerm = perms.get(grantUri);
7114        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7115            return true;
7116        }
7117
7118        // No exact match, look for prefixes
7119        final int N = perms.size();
7120        for (int i = 0; i < N; i++) {
7121            final UriPermission perm = perms.valueAt(i);
7122            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7123                    && perm.getStrength(modeFlags) >= minStrength) {
7124                return true;
7125            }
7126        }
7127
7128        return false;
7129    }
7130
7131    /**
7132     * @param uri This uri must NOT contain an embedded userId.
7133     * @param userId The userId in which the uri is to be resolved.
7134     */
7135    @Override
7136    public int checkUriPermission(Uri uri, int pid, int uid,
7137            final int modeFlags, int userId) {
7138        enforceNotIsolatedCaller("checkUriPermission");
7139
7140        // Another redirected-binder-call permissions check as in
7141        // {@link checkComponentPermission}.
7142        Identity tlsIdentity = sCallerIdentity.get();
7143        if (tlsIdentity != null) {
7144            uid = tlsIdentity.uid;
7145            pid = tlsIdentity.pid;
7146        }
7147
7148        // Our own process gets to do everything.
7149        if (pid == MY_PID) {
7150            return PackageManager.PERMISSION_GRANTED;
7151        }
7152        synchronized (this) {
7153            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7154                    ? PackageManager.PERMISSION_GRANTED
7155                    : PackageManager.PERMISSION_DENIED;
7156        }
7157    }
7158
7159    /**
7160     * Check if the targetPkg can be granted permission to access uri by
7161     * the callingUid using the given modeFlags.  Throws a security exception
7162     * if callingUid is not allowed to do this.  Returns the uid of the target
7163     * if the URI permission grant should be performed; returns -1 if it is not
7164     * needed (for example targetPkg already has permission to access the URI).
7165     * If you already know the uid of the target, you can supply it in
7166     * lastTargetUid else set that to -1.
7167     */
7168    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7169            final int modeFlags, int lastTargetUid) {
7170        if (!Intent.isAccessUriMode(modeFlags)) {
7171            return -1;
7172        }
7173
7174        if (targetPkg != null) {
7175            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7176                    "Checking grant " + targetPkg + " permission to " + grantUri);
7177        }
7178
7179        final IPackageManager pm = AppGlobals.getPackageManager();
7180
7181        // If this is not a content: uri, we can't do anything with it.
7182        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7183            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7184                    "Can't grant URI permission for non-content URI: " + grantUri);
7185            return -1;
7186        }
7187
7188        final String authority = grantUri.uri.getAuthority();
7189        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7190        if (pi == null) {
7191            Slog.w(TAG, "No content provider found for permission check: " +
7192                    grantUri.uri.toSafeString());
7193            return -1;
7194        }
7195
7196        int targetUid = lastTargetUid;
7197        if (targetUid < 0 && targetPkg != null) {
7198            try {
7199                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7200                if (targetUid < 0) {
7201                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7202                            "Can't grant URI permission no uid for: " + targetPkg);
7203                    return -1;
7204                }
7205            } catch (RemoteException ex) {
7206                return -1;
7207            }
7208        }
7209
7210        if (targetUid >= 0) {
7211            // First...  does the target actually need this permission?
7212            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7213                // No need to grant the target this permission.
7214                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7215                        "Target " + targetPkg + " already has full permission to " + grantUri);
7216                return -1;
7217            }
7218        } else {
7219            // First...  there is no target package, so can anyone access it?
7220            boolean allowed = pi.exported;
7221            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7222                if (pi.readPermission != null) {
7223                    allowed = false;
7224                }
7225            }
7226            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7227                if (pi.writePermission != null) {
7228                    allowed = false;
7229                }
7230            }
7231            if (allowed) {
7232                return -1;
7233            }
7234        }
7235
7236        /* There is a special cross user grant if:
7237         * - The target is on another user.
7238         * - Apps on the current user can access the uri without any uid permissions.
7239         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7240         * grant uri permissions.
7241         */
7242        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7243                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7244                modeFlags, false /*without considering the uid permissions*/);
7245
7246        // Second...  is the provider allowing granting of URI permissions?
7247        if (!specialCrossUserGrant) {
7248            if (!pi.grantUriPermissions) {
7249                throw new SecurityException("Provider " + pi.packageName
7250                        + "/" + pi.name
7251                        + " does not allow granting of Uri permissions (uri "
7252                        + grantUri + ")");
7253            }
7254            if (pi.uriPermissionPatterns != null) {
7255                final int N = pi.uriPermissionPatterns.length;
7256                boolean allowed = false;
7257                for (int i=0; i<N; i++) {
7258                    if (pi.uriPermissionPatterns[i] != null
7259                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7260                        allowed = true;
7261                        break;
7262                    }
7263                }
7264                if (!allowed) {
7265                    throw new SecurityException("Provider " + pi.packageName
7266                            + "/" + pi.name
7267                            + " does not allow granting of permission to path of Uri "
7268                            + grantUri);
7269                }
7270            }
7271        }
7272
7273        // Third...  does the caller itself have permission to access
7274        // this uri?
7275        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7276            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7277                // Require they hold a strong enough Uri permission
7278                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7279                    throw new SecurityException("Uid " + callingUid
7280                            + " does not have permission to uri " + grantUri);
7281                }
7282            }
7283        }
7284        return targetUid;
7285    }
7286
7287    /**
7288     * @param uri This uri must NOT contain an embedded userId.
7289     * @param userId The userId in which the uri is to be resolved.
7290     */
7291    @Override
7292    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7293            final int modeFlags, int userId) {
7294        enforceNotIsolatedCaller("checkGrantUriPermission");
7295        synchronized(this) {
7296            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7297                    new GrantUri(userId, uri, false), modeFlags, -1);
7298        }
7299    }
7300
7301    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7302            final int modeFlags, UriPermissionOwner owner) {
7303        if (!Intent.isAccessUriMode(modeFlags)) {
7304            return;
7305        }
7306
7307        // So here we are: the caller has the assumed permission
7308        // to the uri, and the target doesn't.  Let's now give this to
7309        // the target.
7310
7311        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7312                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7313
7314        final String authority = grantUri.uri.getAuthority();
7315        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7316        if (pi == null) {
7317            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7318            return;
7319        }
7320
7321        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7322            grantUri.prefix = true;
7323        }
7324        final UriPermission perm = findOrCreateUriPermissionLocked(
7325                pi.packageName, targetPkg, targetUid, grantUri);
7326        perm.grantModes(modeFlags, owner);
7327    }
7328
7329    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7330            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7331        if (targetPkg == null) {
7332            throw new NullPointerException("targetPkg");
7333        }
7334        int targetUid;
7335        final IPackageManager pm = AppGlobals.getPackageManager();
7336        try {
7337            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7338        } catch (RemoteException ex) {
7339            return;
7340        }
7341
7342        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7343                targetUid);
7344        if (targetUid < 0) {
7345            return;
7346        }
7347
7348        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7349                owner);
7350    }
7351
7352    static class NeededUriGrants extends ArrayList<GrantUri> {
7353        final String targetPkg;
7354        final int targetUid;
7355        final int flags;
7356
7357        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7358            this.targetPkg = targetPkg;
7359            this.targetUid = targetUid;
7360            this.flags = flags;
7361        }
7362    }
7363
7364    /**
7365     * Like checkGrantUriPermissionLocked, but takes an Intent.
7366     */
7367    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7368            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7369        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7370                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7371                + " clip=" + (intent != null ? intent.getClipData() : null)
7372                + " from " + intent + "; flags=0x"
7373                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7374
7375        if (targetPkg == null) {
7376            throw new NullPointerException("targetPkg");
7377        }
7378
7379        if (intent == null) {
7380            return null;
7381        }
7382        Uri data = intent.getData();
7383        ClipData clip = intent.getClipData();
7384        if (data == null && clip == null) {
7385            return null;
7386        }
7387        // Default userId for uris in the intent (if they don't specify it themselves)
7388        int contentUserHint = intent.getContentUserHint();
7389        if (contentUserHint == UserHandle.USER_CURRENT) {
7390            contentUserHint = UserHandle.getUserId(callingUid);
7391        }
7392        final IPackageManager pm = AppGlobals.getPackageManager();
7393        int targetUid;
7394        if (needed != null) {
7395            targetUid = needed.targetUid;
7396        } else {
7397            try {
7398                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7399            } catch (RemoteException ex) {
7400                return null;
7401            }
7402            if (targetUid < 0) {
7403                if (DEBUG_URI_PERMISSION) {
7404                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7405                            + " on user " + targetUserId);
7406                }
7407                return null;
7408            }
7409        }
7410        if (data != null) {
7411            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7412            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7413                    targetUid);
7414            if (targetUid > 0) {
7415                if (needed == null) {
7416                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7417                }
7418                needed.add(grantUri);
7419            }
7420        }
7421        if (clip != null) {
7422            for (int i=0; i<clip.getItemCount(); i++) {
7423                Uri uri = clip.getItemAt(i).getUri();
7424                if (uri != null) {
7425                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7426                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7427                            targetUid);
7428                    if (targetUid > 0) {
7429                        if (needed == null) {
7430                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7431                        }
7432                        needed.add(grantUri);
7433                    }
7434                } else {
7435                    Intent clipIntent = clip.getItemAt(i).getIntent();
7436                    if (clipIntent != null) {
7437                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7438                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7439                        if (newNeeded != null) {
7440                            needed = newNeeded;
7441                        }
7442                    }
7443                }
7444            }
7445        }
7446
7447        return needed;
7448    }
7449
7450    /**
7451     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7452     */
7453    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7454            UriPermissionOwner owner) {
7455        if (needed != null) {
7456            for (int i=0; i<needed.size(); i++) {
7457                GrantUri grantUri = needed.get(i);
7458                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7459                        grantUri, needed.flags, owner);
7460            }
7461        }
7462    }
7463
7464    void grantUriPermissionFromIntentLocked(int callingUid,
7465            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7466        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7467                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7468        if (needed == null) {
7469            return;
7470        }
7471
7472        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7473    }
7474
7475    /**
7476     * @param uri This uri must NOT contain an embedded userId.
7477     * @param userId The userId in which the uri is to be resolved.
7478     */
7479    @Override
7480    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7481            final int modeFlags, int userId) {
7482        enforceNotIsolatedCaller("grantUriPermission");
7483        GrantUri grantUri = new GrantUri(userId, uri, false);
7484        synchronized(this) {
7485            final ProcessRecord r = getRecordForAppLocked(caller);
7486            if (r == null) {
7487                throw new SecurityException("Unable to find app for caller "
7488                        + caller
7489                        + " when granting permission to uri " + grantUri);
7490            }
7491            if (targetPkg == null) {
7492                throw new IllegalArgumentException("null target");
7493            }
7494            if (grantUri == null) {
7495                throw new IllegalArgumentException("null uri");
7496            }
7497
7498            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7499                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7500                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7501                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7502
7503            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7504                    UserHandle.getUserId(r.uid));
7505        }
7506    }
7507
7508    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7509        if (perm.modeFlags == 0) {
7510            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7511                    perm.targetUid);
7512            if (perms != null) {
7513                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7514                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7515
7516                perms.remove(perm.uri);
7517                if (perms.isEmpty()) {
7518                    mGrantedUriPermissions.remove(perm.targetUid);
7519                }
7520            }
7521        }
7522    }
7523
7524    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7525        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7526
7527        final IPackageManager pm = AppGlobals.getPackageManager();
7528        final String authority = grantUri.uri.getAuthority();
7529        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7530        if (pi == null) {
7531            Slog.w(TAG, "No content provider found for permission revoke: "
7532                    + grantUri.toSafeString());
7533            return;
7534        }
7535
7536        // Does the caller have this permission on the URI?
7537        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7538            // If they don't have direct access to the URI, then revoke any
7539            // ownerless URI permissions that have been granted to them.
7540            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7541            if (perms != null) {
7542                boolean persistChanged = false;
7543                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7544                    final UriPermission perm = it.next();
7545                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7546                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7547                        if (DEBUG_URI_PERMISSION)
7548                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7549                                    " permission to " + perm.uri);
7550                        persistChanged |= perm.revokeModes(
7551                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7552                        if (perm.modeFlags == 0) {
7553                            it.remove();
7554                        }
7555                    }
7556                }
7557                if (perms.isEmpty()) {
7558                    mGrantedUriPermissions.remove(callingUid);
7559                }
7560                if (persistChanged) {
7561                    schedulePersistUriGrants();
7562                }
7563            }
7564            return;
7565        }
7566
7567        boolean persistChanged = false;
7568
7569        // Go through all of the permissions and remove any that match.
7570        int N = mGrantedUriPermissions.size();
7571        for (int i = 0; i < N; i++) {
7572            final int targetUid = mGrantedUriPermissions.keyAt(i);
7573            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7574
7575            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7576                final UriPermission perm = it.next();
7577                if (perm.uri.sourceUserId == grantUri.sourceUserId
7578                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7579                    if (DEBUG_URI_PERMISSION)
7580                        Slog.v(TAG,
7581                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7582                    persistChanged |= perm.revokeModes(
7583                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7584                    if (perm.modeFlags == 0) {
7585                        it.remove();
7586                    }
7587                }
7588            }
7589
7590            if (perms.isEmpty()) {
7591                mGrantedUriPermissions.remove(targetUid);
7592                N--;
7593                i--;
7594            }
7595        }
7596
7597        if (persistChanged) {
7598            schedulePersistUriGrants();
7599        }
7600    }
7601
7602    /**
7603     * @param uri This uri must NOT contain an embedded userId.
7604     * @param userId The userId in which the uri is to be resolved.
7605     */
7606    @Override
7607    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7608            int userId) {
7609        enforceNotIsolatedCaller("revokeUriPermission");
7610        synchronized(this) {
7611            final ProcessRecord r = getRecordForAppLocked(caller);
7612            if (r == null) {
7613                throw new SecurityException("Unable to find app for caller "
7614                        + caller
7615                        + " when revoking permission to uri " + uri);
7616            }
7617            if (uri == null) {
7618                Slog.w(TAG, "revokeUriPermission: null uri");
7619                return;
7620            }
7621
7622            if (!Intent.isAccessUriMode(modeFlags)) {
7623                return;
7624            }
7625
7626            final IPackageManager pm = AppGlobals.getPackageManager();
7627            final String authority = uri.getAuthority();
7628            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7629            if (pi == null) {
7630                Slog.w(TAG, "No content provider found for permission revoke: "
7631                        + uri.toSafeString());
7632                return;
7633            }
7634
7635            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7636        }
7637    }
7638
7639    /**
7640     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7641     * given package.
7642     *
7643     * @param packageName Package name to match, or {@code null} to apply to all
7644     *            packages.
7645     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7646     *            to all users.
7647     * @param persistable If persistable grants should be removed.
7648     */
7649    private void removeUriPermissionsForPackageLocked(
7650            String packageName, int userHandle, boolean persistable) {
7651        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7652            throw new IllegalArgumentException("Must narrow by either package or user");
7653        }
7654
7655        boolean persistChanged = false;
7656
7657        int N = mGrantedUriPermissions.size();
7658        for (int i = 0; i < N; i++) {
7659            final int targetUid = mGrantedUriPermissions.keyAt(i);
7660            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7661
7662            // Only inspect grants matching user
7663            if (userHandle == UserHandle.USER_ALL
7664                    || userHandle == UserHandle.getUserId(targetUid)) {
7665                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7666                    final UriPermission perm = it.next();
7667
7668                    // Only inspect grants matching package
7669                    if (packageName == null || perm.sourcePkg.equals(packageName)
7670                            || perm.targetPkg.equals(packageName)) {
7671                        persistChanged |= perm.revokeModes(persistable
7672                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7673
7674                        // Only remove when no modes remain; any persisted grants
7675                        // will keep this alive.
7676                        if (perm.modeFlags == 0) {
7677                            it.remove();
7678                        }
7679                    }
7680                }
7681
7682                if (perms.isEmpty()) {
7683                    mGrantedUriPermissions.remove(targetUid);
7684                    N--;
7685                    i--;
7686                }
7687            }
7688        }
7689
7690        if (persistChanged) {
7691            schedulePersistUriGrants();
7692        }
7693    }
7694
7695    @Override
7696    public IBinder newUriPermissionOwner(String name) {
7697        enforceNotIsolatedCaller("newUriPermissionOwner");
7698        synchronized(this) {
7699            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7700            return owner.getExternalTokenLocked();
7701        }
7702    }
7703
7704    /**
7705     * @param uri This uri must NOT contain an embedded userId.
7706     * @param sourceUserId The userId in which the uri is to be resolved.
7707     * @param targetUserId The userId of the app that receives the grant.
7708     */
7709    @Override
7710    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7711            final int modeFlags, int sourceUserId, int targetUserId) {
7712        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7713                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7714        synchronized(this) {
7715            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7716            if (owner == null) {
7717                throw new IllegalArgumentException("Unknown owner: " + token);
7718            }
7719            if (fromUid != Binder.getCallingUid()) {
7720                if (Binder.getCallingUid() != Process.myUid()) {
7721                    // Only system code can grant URI permissions on behalf
7722                    // of other users.
7723                    throw new SecurityException("nice try");
7724                }
7725            }
7726            if (targetPkg == null) {
7727                throw new IllegalArgumentException("null target");
7728            }
7729            if (uri == null) {
7730                throw new IllegalArgumentException("null uri");
7731            }
7732
7733            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7734                    modeFlags, owner, targetUserId);
7735        }
7736    }
7737
7738    /**
7739     * @param uri This uri must NOT contain an embedded userId.
7740     * @param userId The userId in which the uri is to be resolved.
7741     */
7742    @Override
7743    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7744        synchronized(this) {
7745            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7746            if (owner == null) {
7747                throw new IllegalArgumentException("Unknown owner: " + token);
7748            }
7749
7750            if (uri == null) {
7751                owner.removeUriPermissionsLocked(mode);
7752            } else {
7753                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7754            }
7755        }
7756    }
7757
7758    private void schedulePersistUriGrants() {
7759        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7760            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7761                    10 * DateUtils.SECOND_IN_MILLIS);
7762        }
7763    }
7764
7765    private void writeGrantedUriPermissions() {
7766        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7767
7768        // Snapshot permissions so we can persist without lock
7769        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7770        synchronized (this) {
7771            final int size = mGrantedUriPermissions.size();
7772            for (int i = 0; i < size; i++) {
7773                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7774                for (UriPermission perm : perms.values()) {
7775                    if (perm.persistedModeFlags != 0) {
7776                        persist.add(perm.snapshot());
7777                    }
7778                }
7779            }
7780        }
7781
7782        FileOutputStream fos = null;
7783        try {
7784            fos = mGrantFile.startWrite();
7785
7786            XmlSerializer out = new FastXmlSerializer();
7787            out.setOutput(fos, "utf-8");
7788            out.startDocument(null, true);
7789            out.startTag(null, TAG_URI_GRANTS);
7790            for (UriPermission.Snapshot perm : persist) {
7791                out.startTag(null, TAG_URI_GRANT);
7792                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7793                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7794                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7795                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7796                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7797                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7798                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7799                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7800                out.endTag(null, TAG_URI_GRANT);
7801            }
7802            out.endTag(null, TAG_URI_GRANTS);
7803            out.endDocument();
7804
7805            mGrantFile.finishWrite(fos);
7806        } catch (IOException e) {
7807            if (fos != null) {
7808                mGrantFile.failWrite(fos);
7809            }
7810        }
7811    }
7812
7813    private void readGrantedUriPermissionsLocked() {
7814        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7815
7816        final long now = System.currentTimeMillis();
7817
7818        FileInputStream fis = null;
7819        try {
7820            fis = mGrantFile.openRead();
7821            final XmlPullParser in = Xml.newPullParser();
7822            in.setInput(fis, null);
7823
7824            int type;
7825            while ((type = in.next()) != END_DOCUMENT) {
7826                final String tag = in.getName();
7827                if (type == START_TAG) {
7828                    if (TAG_URI_GRANT.equals(tag)) {
7829                        final int sourceUserId;
7830                        final int targetUserId;
7831                        final int userHandle = readIntAttribute(in,
7832                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7833                        if (userHandle != UserHandle.USER_NULL) {
7834                            // For backwards compatibility.
7835                            sourceUserId = userHandle;
7836                            targetUserId = userHandle;
7837                        } else {
7838                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7839                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7840                        }
7841                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7842                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7843                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7844                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7845                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7846                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7847
7848                        // Sanity check that provider still belongs to source package
7849                        final ProviderInfo pi = getProviderInfoLocked(
7850                                uri.getAuthority(), sourceUserId);
7851                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7852                            int targetUid = -1;
7853                            try {
7854                                targetUid = AppGlobals.getPackageManager()
7855                                        .getPackageUid(targetPkg, targetUserId);
7856                            } catch (RemoteException e) {
7857                            }
7858                            if (targetUid != -1) {
7859                                final UriPermission perm = findOrCreateUriPermissionLocked(
7860                                        sourcePkg, targetPkg, targetUid,
7861                                        new GrantUri(sourceUserId, uri, prefix));
7862                                perm.initPersistedModes(modeFlags, createdTime);
7863                            }
7864                        } else {
7865                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7866                                    + " but instead found " + pi);
7867                        }
7868                    }
7869                }
7870            }
7871        } catch (FileNotFoundException e) {
7872            // Missing grants is okay
7873        } catch (IOException e) {
7874            Log.wtf(TAG, "Failed reading Uri grants", e);
7875        } catch (XmlPullParserException e) {
7876            Log.wtf(TAG, "Failed reading Uri grants", e);
7877        } finally {
7878            IoUtils.closeQuietly(fis);
7879        }
7880    }
7881
7882    /**
7883     * @param uri This uri must NOT contain an embedded userId.
7884     * @param userId The userId in which the uri is to be resolved.
7885     */
7886    @Override
7887    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7888        enforceNotIsolatedCaller("takePersistableUriPermission");
7889
7890        Preconditions.checkFlagsArgument(modeFlags,
7891                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7892
7893        synchronized (this) {
7894            final int callingUid = Binder.getCallingUid();
7895            boolean persistChanged = false;
7896            GrantUri grantUri = new GrantUri(userId, uri, false);
7897
7898            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7899                    new GrantUri(userId, uri, false));
7900            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7901                    new GrantUri(userId, uri, true));
7902
7903            final boolean exactValid = (exactPerm != null)
7904                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7905            final boolean prefixValid = (prefixPerm != null)
7906                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7907
7908            if (!(exactValid || prefixValid)) {
7909                throw new SecurityException("No persistable permission grants found for UID "
7910                        + callingUid + " and Uri " + grantUri.toSafeString());
7911            }
7912
7913            if (exactValid) {
7914                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7915            }
7916            if (prefixValid) {
7917                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7918            }
7919
7920            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7921
7922            if (persistChanged) {
7923                schedulePersistUriGrants();
7924            }
7925        }
7926    }
7927
7928    /**
7929     * @param uri This uri must NOT contain an embedded userId.
7930     * @param userId The userId in which the uri is to be resolved.
7931     */
7932    @Override
7933    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7934        enforceNotIsolatedCaller("releasePersistableUriPermission");
7935
7936        Preconditions.checkFlagsArgument(modeFlags,
7937                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7938
7939        synchronized (this) {
7940            final int callingUid = Binder.getCallingUid();
7941            boolean persistChanged = false;
7942
7943            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7944                    new GrantUri(userId, uri, false));
7945            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7946                    new GrantUri(userId, uri, true));
7947            if (exactPerm == null && prefixPerm == null) {
7948                throw new SecurityException("No permission grants found for UID " + callingUid
7949                        + " and Uri " + uri.toSafeString());
7950            }
7951
7952            if (exactPerm != null) {
7953                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7954                removeUriPermissionIfNeededLocked(exactPerm);
7955            }
7956            if (prefixPerm != null) {
7957                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7958                removeUriPermissionIfNeededLocked(prefixPerm);
7959            }
7960
7961            if (persistChanged) {
7962                schedulePersistUriGrants();
7963            }
7964        }
7965    }
7966
7967    /**
7968     * Prune any older {@link UriPermission} for the given UID until outstanding
7969     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7970     *
7971     * @return if any mutations occured that require persisting.
7972     */
7973    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7974        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7975        if (perms == null) return false;
7976        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7977
7978        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7979        for (UriPermission perm : perms.values()) {
7980            if (perm.persistedModeFlags != 0) {
7981                persisted.add(perm);
7982            }
7983        }
7984
7985        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7986        if (trimCount <= 0) return false;
7987
7988        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7989        for (int i = 0; i < trimCount; i++) {
7990            final UriPermission perm = persisted.get(i);
7991
7992            if (DEBUG_URI_PERMISSION) {
7993                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7994            }
7995
7996            perm.releasePersistableModes(~0);
7997            removeUriPermissionIfNeededLocked(perm);
7998        }
7999
8000        return true;
8001    }
8002
8003    @Override
8004    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8005            String packageName, boolean incoming) {
8006        enforceNotIsolatedCaller("getPersistedUriPermissions");
8007        Preconditions.checkNotNull(packageName, "packageName");
8008
8009        final int callingUid = Binder.getCallingUid();
8010        final IPackageManager pm = AppGlobals.getPackageManager();
8011        try {
8012            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8013            if (packageUid != callingUid) {
8014                throw new SecurityException(
8015                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8016            }
8017        } catch (RemoteException e) {
8018            throw new SecurityException("Failed to verify package name ownership");
8019        }
8020
8021        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8022        synchronized (this) {
8023            if (incoming) {
8024                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8025                        callingUid);
8026                if (perms == null) {
8027                    Slog.w(TAG, "No permission grants found for " + packageName);
8028                } else {
8029                    for (UriPermission perm : perms.values()) {
8030                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8031                            result.add(perm.buildPersistedPublicApiObject());
8032                        }
8033                    }
8034                }
8035            } else {
8036                final int size = mGrantedUriPermissions.size();
8037                for (int i = 0; i < size; i++) {
8038                    final ArrayMap<GrantUri, UriPermission> perms =
8039                            mGrantedUriPermissions.valueAt(i);
8040                    for (UriPermission perm : perms.values()) {
8041                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8042                            result.add(perm.buildPersistedPublicApiObject());
8043                        }
8044                    }
8045                }
8046            }
8047        }
8048        return new ParceledListSlice<android.content.UriPermission>(result);
8049    }
8050
8051    @Override
8052    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8053        synchronized (this) {
8054            ProcessRecord app =
8055                who != null ? getRecordForAppLocked(who) : null;
8056            if (app == null) return;
8057
8058            Message msg = Message.obtain();
8059            msg.what = WAIT_FOR_DEBUGGER_MSG;
8060            msg.obj = app;
8061            msg.arg1 = waiting ? 1 : 0;
8062            mHandler.sendMessage(msg);
8063        }
8064    }
8065
8066    @Override
8067    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8068        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8069        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8070        outInfo.availMem = Process.getFreeMemory();
8071        outInfo.totalMem = Process.getTotalMemory();
8072        outInfo.threshold = homeAppMem;
8073        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8074        outInfo.hiddenAppThreshold = cachedAppMem;
8075        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8076                ProcessList.SERVICE_ADJ);
8077        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8078                ProcessList.VISIBLE_APP_ADJ);
8079        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8080                ProcessList.FOREGROUND_APP_ADJ);
8081    }
8082
8083    // =========================================================
8084    // TASK MANAGEMENT
8085    // =========================================================
8086
8087    @Override
8088    public List<IAppTask> getAppTasks(String callingPackage) {
8089        int callingUid = Binder.getCallingUid();
8090        long ident = Binder.clearCallingIdentity();
8091
8092        synchronized(this) {
8093            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8094            try {
8095                if (localLOGV) Slog.v(TAG, "getAppTasks");
8096
8097                final int N = mRecentTasks.size();
8098                for (int i = 0; i < N; i++) {
8099                    TaskRecord tr = mRecentTasks.get(i);
8100                    // Skip tasks that do not match the caller.  We don't need to verify
8101                    // callingPackage, because we are also limiting to callingUid and know
8102                    // that will limit to the correct security sandbox.
8103                    if (tr.effectiveUid != callingUid) {
8104                        continue;
8105                    }
8106                    Intent intent = tr.getBaseIntent();
8107                    if (intent == null ||
8108                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8109                        continue;
8110                    }
8111                    ActivityManager.RecentTaskInfo taskInfo =
8112                            createRecentTaskInfoFromTaskRecord(tr);
8113                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8114                    list.add(taskImpl);
8115                }
8116            } finally {
8117                Binder.restoreCallingIdentity(ident);
8118            }
8119            return list;
8120        }
8121    }
8122
8123    @Override
8124    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8125        final int callingUid = Binder.getCallingUid();
8126        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8127
8128        synchronized(this) {
8129            if (localLOGV) Slog.v(
8130                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8131
8132            final boolean allowed = checkCallingPermission(
8133                    android.Manifest.permission.GET_TASKS)
8134                    == PackageManager.PERMISSION_GRANTED;
8135            if (!allowed) {
8136                Slog.w(TAG, "getTasks: caller " + callingUid
8137                        + " does not hold GET_TASKS; limiting output");
8138            }
8139
8140            // TODO: Improve with MRU list from all ActivityStacks.
8141            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8142        }
8143
8144        return list;
8145    }
8146
8147    TaskRecord getMostRecentTask() {
8148        return mRecentTasks.get(0);
8149    }
8150
8151    /**
8152     * Creates a new RecentTaskInfo from a TaskRecord.
8153     */
8154    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8155        // Update the task description to reflect any changes in the task stack
8156        tr.updateTaskDescription();
8157
8158        // Compose the recent task info
8159        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8160        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8161        rti.persistentId = tr.taskId;
8162        rti.baseIntent = new Intent(tr.getBaseIntent());
8163        rti.origActivity = tr.origActivity;
8164        rti.description = tr.lastDescription;
8165        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8166        rti.userId = tr.userId;
8167        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8168        rti.firstActiveTime = tr.firstActiveTime;
8169        rti.lastActiveTime = tr.lastActiveTime;
8170        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8171        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8172        return rti;
8173    }
8174
8175    @Override
8176    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8177        final int callingUid = Binder.getCallingUid();
8178        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8179                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8180
8181        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8182        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8183        synchronized (this) {
8184            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8185                    == PackageManager.PERMISSION_GRANTED;
8186            if (!allowed) {
8187                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8188                        + " does not hold GET_TASKS; limiting output");
8189            }
8190            final boolean detailed = checkCallingPermission(
8191                    android.Manifest.permission.GET_DETAILED_TASKS)
8192                    == PackageManager.PERMISSION_GRANTED;
8193
8194            final int N = mRecentTasks.size();
8195            ArrayList<ActivityManager.RecentTaskInfo> res
8196                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8197                            maxNum < N ? maxNum : N);
8198
8199            final Set<Integer> includedUsers;
8200            if (includeProfiles) {
8201                includedUsers = getProfileIdsLocked(userId);
8202            } else {
8203                includedUsers = new HashSet<Integer>();
8204            }
8205            includedUsers.add(Integer.valueOf(userId));
8206
8207            for (int i=0; i<N && maxNum > 0; i++) {
8208                TaskRecord tr = mRecentTasks.get(i);
8209                // Only add calling user or related users recent tasks
8210                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8211                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8212                    continue;
8213                }
8214
8215                // Return the entry if desired by the caller.  We always return
8216                // the first entry, because callers always expect this to be the
8217                // foreground app.  We may filter others if the caller has
8218                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8219                // we should exclude the entry.
8220
8221                if (i == 0
8222                        || withExcluded
8223                        || (tr.intent == null)
8224                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8225                                == 0)) {
8226                    if (!allowed) {
8227                        // If the caller doesn't have the GET_TASKS permission, then only
8228                        // allow them to see a small subset of tasks -- their own and home.
8229                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8230                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8231                            continue;
8232                        }
8233                    }
8234                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8235                        if (tr.stack != null && tr.stack.isHomeStack()) {
8236                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8237                            continue;
8238                        }
8239                    }
8240                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8241                        // Don't include auto remove tasks that are finished or finishing.
8242                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8243                                + tr);
8244                        continue;
8245                    }
8246                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8247                            && !tr.isAvailable) {
8248                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8249                        continue;
8250                    }
8251
8252                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8253                    if (!detailed) {
8254                        rti.baseIntent.replaceExtras((Bundle)null);
8255                    }
8256
8257                    res.add(rti);
8258                    maxNum--;
8259                }
8260            }
8261            return res;
8262        }
8263    }
8264
8265    private TaskRecord recentTaskForIdLocked(int id) {
8266        final int N = mRecentTasks.size();
8267            for (int i=0; i<N; i++) {
8268                TaskRecord tr = mRecentTasks.get(i);
8269                if (tr.taskId == id) {
8270                    return tr;
8271                }
8272            }
8273            return null;
8274    }
8275
8276    @Override
8277    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8278        synchronized (this) {
8279            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8280                    "getTaskThumbnail()");
8281            TaskRecord tr = recentTaskForIdLocked(id);
8282            if (tr != null) {
8283                return tr.getTaskThumbnailLocked();
8284            }
8285        }
8286        return null;
8287    }
8288
8289    @Override
8290    public int addAppTask(IBinder activityToken, Intent intent,
8291            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8292        final int callingUid = Binder.getCallingUid();
8293        final long callingIdent = Binder.clearCallingIdentity();
8294
8295        try {
8296            synchronized (this) {
8297                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8298                if (r == null) {
8299                    throw new IllegalArgumentException("Activity does not exist; token="
8300                            + activityToken);
8301                }
8302                ComponentName comp = intent.getComponent();
8303                if (comp == null) {
8304                    throw new IllegalArgumentException("Intent " + intent
8305                            + " must specify explicit component");
8306                }
8307                if (thumbnail.getWidth() != mThumbnailWidth
8308                        || thumbnail.getHeight() != mThumbnailHeight) {
8309                    throw new IllegalArgumentException("Bad thumbnail size: got "
8310                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8311                            + mThumbnailWidth + "x" + mThumbnailHeight);
8312                }
8313                if (intent.getSelector() != null) {
8314                    intent.setSelector(null);
8315                }
8316                if (intent.getSourceBounds() != null) {
8317                    intent.setSourceBounds(null);
8318                }
8319                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8320                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8321                        // The caller has added this as an auto-remove task...  that makes no
8322                        // sense, so turn off auto-remove.
8323                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8324                    }
8325                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8326                    // Must be a new task.
8327                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8328                }
8329                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8330                    mLastAddedTaskActivity = null;
8331                }
8332                ActivityInfo ainfo = mLastAddedTaskActivity;
8333                if (ainfo == null) {
8334                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8335                            comp, 0, UserHandle.getUserId(callingUid));
8336                    if (ainfo.applicationInfo.uid != callingUid) {
8337                        throw new SecurityException(
8338                                "Can't add task for another application: target uid="
8339                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8340                    }
8341                }
8342
8343                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8344                        intent, description);
8345
8346                int trimIdx = trimRecentsForTask(task, false);
8347                if (trimIdx >= 0) {
8348                    // If this would have caused a trim, then we'll abort because that
8349                    // means it would be added at the end of the list but then just removed.
8350                    return -1;
8351                }
8352
8353                final int N = mRecentTasks.size();
8354                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8355                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8356                    tr.removedFromRecents(mTaskPersister);
8357                }
8358
8359                task.inRecents = true;
8360                mRecentTasks.add(task);
8361                r.task.stack.addTask(task, false, false);
8362
8363                task.setLastThumbnail(thumbnail);
8364                task.freeLastThumbnail();
8365
8366                return task.taskId;
8367            }
8368        } finally {
8369            Binder.restoreCallingIdentity(callingIdent);
8370        }
8371    }
8372
8373    @Override
8374    public Point getAppTaskThumbnailSize() {
8375        synchronized (this) {
8376            return new Point(mThumbnailWidth,  mThumbnailHeight);
8377        }
8378    }
8379
8380    @Override
8381    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8382        synchronized (this) {
8383            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8384            if (r != null) {
8385                r.setTaskDescription(td);
8386                r.task.updateTaskDescription();
8387            }
8388        }
8389    }
8390
8391    @Override
8392    public Bitmap getTaskDescriptionIcon(String filename) {
8393        return mTaskPersister.getTaskDescriptionIcon(filename);
8394    }
8395
8396    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8397        mRecentTasks.remove(tr);
8398        tr.removedFromRecents(mTaskPersister);
8399        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8400        Intent baseIntent = new Intent(
8401                tr.intent != null ? tr.intent : tr.affinityIntent);
8402        ComponentName component = baseIntent.getComponent();
8403        if (component == null) {
8404            Slog.w(TAG, "Now component for base intent of task: " + tr);
8405            return;
8406        }
8407
8408        // Find any running services associated with this app.
8409        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8410
8411        if (killProcesses) {
8412            // Find any running processes associated with this app.
8413            final String pkg = component.getPackageName();
8414            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8415            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8416            for (int i=0; i<pmap.size(); i++) {
8417                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8418                for (int j=0; j<uids.size(); j++) {
8419                    ProcessRecord proc = uids.valueAt(j);
8420                    if (proc.userId != tr.userId) {
8421                        continue;
8422                    }
8423                    if (!proc.pkgList.containsKey(pkg)) {
8424                        continue;
8425                    }
8426                    procs.add(proc);
8427                }
8428            }
8429
8430            // Kill the running processes.
8431            for (int i=0; i<procs.size(); i++) {
8432                ProcessRecord pr = procs.get(i);
8433                if (pr == mHomeProcess) {
8434                    // Don't kill the home process along with tasks from the same package.
8435                    continue;
8436                }
8437                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8438                    pr.kill("remove task", true);
8439                } else {
8440                    pr.waitingToKill = "remove task";
8441                }
8442            }
8443        }
8444    }
8445
8446    /**
8447     * Removes the task with the specified task id.
8448     *
8449     * @param taskId Identifier of the task to be removed.
8450     * @param flags Additional operational flags.  May be 0 or
8451     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8452     * @return Returns true if the given task was found and removed.
8453     */
8454    private boolean removeTaskByIdLocked(int taskId, int flags) {
8455        TaskRecord tr = recentTaskForIdLocked(taskId);
8456        if (tr != null) {
8457            tr.removeTaskActivitiesLocked();
8458            cleanUpRemovedTaskLocked(tr, flags);
8459            if (tr.isPersistable) {
8460                notifyTaskPersisterLocked(null, true);
8461            }
8462            return true;
8463        }
8464        return false;
8465    }
8466
8467    @Override
8468    public boolean removeTask(int taskId, int flags) {
8469        synchronized (this) {
8470            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8471                    "removeTask()");
8472            long ident = Binder.clearCallingIdentity();
8473            try {
8474                return removeTaskByIdLocked(taskId, flags);
8475            } finally {
8476                Binder.restoreCallingIdentity(ident);
8477            }
8478        }
8479    }
8480
8481    /**
8482     * TODO: Add mController hook
8483     */
8484    @Override
8485    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8486        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8487                "moveTaskToFront()");
8488
8489        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8490        synchronized(this) {
8491            moveTaskToFrontLocked(taskId, flags, options);
8492        }
8493    }
8494
8495    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8496        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8497                Binder.getCallingUid(), -1, -1, "Task to front")) {
8498            ActivityOptions.abort(options);
8499            return;
8500        }
8501        final long origId = Binder.clearCallingIdentity();
8502        try {
8503            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8504            if (task == null) {
8505                return;
8506            }
8507            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8508                mStackSupervisor.showLockTaskToast();
8509                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8510                return;
8511            }
8512            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8513            if (prev != null && prev.isRecentsActivity()) {
8514                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8515            }
8516            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8517        } finally {
8518            Binder.restoreCallingIdentity(origId);
8519        }
8520        ActivityOptions.abort(options);
8521    }
8522
8523    @Override
8524    public void moveTaskToBack(int taskId) {
8525        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8526                "moveTaskToBack()");
8527
8528        synchronized(this) {
8529            TaskRecord tr = recentTaskForIdLocked(taskId);
8530            if (tr != null) {
8531                if (tr == mStackSupervisor.mLockTaskModeTask) {
8532                    mStackSupervisor.showLockTaskToast();
8533                    return;
8534                }
8535                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8536                ActivityStack stack = tr.stack;
8537                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8538                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8539                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8540                        return;
8541                    }
8542                }
8543                final long origId = Binder.clearCallingIdentity();
8544                try {
8545                    stack.moveTaskToBackLocked(taskId, null);
8546                } finally {
8547                    Binder.restoreCallingIdentity(origId);
8548                }
8549            }
8550        }
8551    }
8552
8553    /**
8554     * Moves an activity, and all of the other activities within the same task, to the bottom
8555     * of the history stack.  The activity's order within the task is unchanged.
8556     *
8557     * @param token A reference to the activity we wish to move
8558     * @param nonRoot If false then this only works if the activity is the root
8559     *                of a task; if true it will work for any activity in a task.
8560     * @return Returns true if the move completed, false if not.
8561     */
8562    @Override
8563    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8564        enforceNotIsolatedCaller("moveActivityTaskToBack");
8565        synchronized(this) {
8566            final long origId = Binder.clearCallingIdentity();
8567            try {
8568                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8569                if (taskId >= 0) {
8570                    if ((mStackSupervisor.mLockTaskModeTask != null)
8571                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8572                        mStackSupervisor.showLockTaskToast();
8573                        return false;
8574                    }
8575                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8576                }
8577            } finally {
8578                Binder.restoreCallingIdentity(origId);
8579            }
8580        }
8581        return false;
8582    }
8583
8584    @Override
8585    public void moveTaskBackwards(int task) {
8586        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8587                "moveTaskBackwards()");
8588
8589        synchronized(this) {
8590            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8591                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8592                return;
8593            }
8594            final long origId = Binder.clearCallingIdentity();
8595            moveTaskBackwardsLocked(task);
8596            Binder.restoreCallingIdentity(origId);
8597        }
8598    }
8599
8600    private final void moveTaskBackwardsLocked(int task) {
8601        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8602    }
8603
8604    @Override
8605    public IBinder getHomeActivityToken() throws RemoteException {
8606        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8607                "getHomeActivityToken()");
8608        synchronized (this) {
8609            return mStackSupervisor.getHomeActivityToken();
8610        }
8611    }
8612
8613    @Override
8614    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8615            IActivityContainerCallback callback) throws RemoteException {
8616        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8617                "createActivityContainer()");
8618        synchronized (this) {
8619            if (parentActivityToken == null) {
8620                throw new IllegalArgumentException("parent token must not be null");
8621            }
8622            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8623            if (r == null) {
8624                return null;
8625            }
8626            if (callback == null) {
8627                throw new IllegalArgumentException("callback must not be null");
8628            }
8629            return mStackSupervisor.createActivityContainer(r, callback);
8630        }
8631    }
8632
8633    @Override
8634    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8635        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8636                "deleteActivityContainer()");
8637        synchronized (this) {
8638            mStackSupervisor.deleteActivityContainer(container);
8639        }
8640    }
8641
8642    @Override
8643    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8644            throws RemoteException {
8645        synchronized (this) {
8646            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8647            if (stack != null) {
8648                return stack.mActivityContainer;
8649            }
8650            return null;
8651        }
8652    }
8653
8654    @Override
8655    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8656        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8657                "moveTaskToStack()");
8658        if (stackId == HOME_STACK_ID) {
8659            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8660                    new RuntimeException("here").fillInStackTrace());
8661        }
8662        synchronized (this) {
8663            long ident = Binder.clearCallingIdentity();
8664            try {
8665                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8666                        + stackId + " toTop=" + toTop);
8667                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8668            } finally {
8669                Binder.restoreCallingIdentity(ident);
8670            }
8671        }
8672    }
8673
8674    @Override
8675    public void resizeStack(int stackBoxId, Rect bounds) {
8676        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8677                "resizeStackBox()");
8678        long ident = Binder.clearCallingIdentity();
8679        try {
8680            mWindowManager.resizeStack(stackBoxId, bounds);
8681        } finally {
8682            Binder.restoreCallingIdentity(ident);
8683        }
8684    }
8685
8686    @Override
8687    public List<StackInfo> getAllStackInfos() {
8688        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8689                "getAllStackInfos()");
8690        long ident = Binder.clearCallingIdentity();
8691        try {
8692            synchronized (this) {
8693                return mStackSupervisor.getAllStackInfosLocked();
8694            }
8695        } finally {
8696            Binder.restoreCallingIdentity(ident);
8697        }
8698    }
8699
8700    @Override
8701    public StackInfo getStackInfo(int stackId) {
8702        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8703                "getStackInfo()");
8704        long ident = Binder.clearCallingIdentity();
8705        try {
8706            synchronized (this) {
8707                return mStackSupervisor.getStackInfoLocked(stackId);
8708            }
8709        } finally {
8710            Binder.restoreCallingIdentity(ident);
8711        }
8712    }
8713
8714    @Override
8715    public boolean isInHomeStack(int taskId) {
8716        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8717                "getStackInfo()");
8718        long ident = Binder.clearCallingIdentity();
8719        try {
8720            synchronized (this) {
8721                TaskRecord tr = recentTaskForIdLocked(taskId);
8722                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8723            }
8724        } finally {
8725            Binder.restoreCallingIdentity(ident);
8726        }
8727    }
8728
8729    @Override
8730    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8731        synchronized(this) {
8732            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8733        }
8734    }
8735
8736    private boolean isLockTaskAuthorized(String pkg) {
8737        final DevicePolicyManager dpm = (DevicePolicyManager)
8738                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8739        try {
8740            int uid = mContext.getPackageManager().getPackageUid(pkg,
8741                    Binder.getCallingUserHandle().getIdentifier());
8742            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8743        } catch (NameNotFoundException e) {
8744            return false;
8745        }
8746    }
8747
8748    void startLockTaskMode(TaskRecord task) {
8749        final String pkg;
8750        synchronized (this) {
8751            pkg = task.intent.getComponent().getPackageName();
8752        }
8753        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8754        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8755            final TaskRecord taskRecord = task;
8756            mHandler.post(new Runnable() {
8757                @Override
8758                public void run() {
8759                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8760                }
8761            });
8762            return;
8763        }
8764        long ident = Binder.clearCallingIdentity();
8765        try {
8766            synchronized (this) {
8767                // Since we lost lock on task, make sure it is still there.
8768                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8769                if (task != null) {
8770                    if (!isSystemInitiated
8771                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8772                        throw new IllegalArgumentException("Invalid task, not in foreground");
8773                    }
8774                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8775                }
8776            }
8777        } finally {
8778            Binder.restoreCallingIdentity(ident);
8779        }
8780    }
8781
8782    @Override
8783    public void startLockTaskMode(int taskId) {
8784        final TaskRecord task;
8785        long ident = Binder.clearCallingIdentity();
8786        try {
8787            synchronized (this) {
8788                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8789            }
8790        } finally {
8791            Binder.restoreCallingIdentity(ident);
8792        }
8793        if (task != null) {
8794            startLockTaskMode(task);
8795        }
8796    }
8797
8798    @Override
8799    public void startLockTaskMode(IBinder token) {
8800        final TaskRecord task;
8801        long ident = Binder.clearCallingIdentity();
8802        try {
8803            synchronized (this) {
8804                final ActivityRecord r = ActivityRecord.forToken(token);
8805                if (r == null) {
8806                    return;
8807                }
8808                task = r.task;
8809            }
8810        } finally {
8811            Binder.restoreCallingIdentity(ident);
8812        }
8813        if (task != null) {
8814            startLockTaskMode(task);
8815        }
8816    }
8817
8818    @Override
8819    public void startLockTaskModeOnCurrent() throws RemoteException {
8820        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8821                "startLockTaskModeOnCurrent");
8822        ActivityRecord r = null;
8823        synchronized (this) {
8824            r = mStackSupervisor.topRunningActivityLocked();
8825        }
8826        startLockTaskMode(r.task);
8827    }
8828
8829    @Override
8830    public void stopLockTaskMode() {
8831        // Verify that the user matches the package of the intent for the TaskRecord
8832        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8833        // and stopLockTaskMode.
8834        final int callingUid = Binder.getCallingUid();
8835        if (callingUid != Process.SYSTEM_UID) {
8836            try {
8837                String pkg =
8838                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8839                int uid = mContext.getPackageManager().getPackageUid(pkg,
8840                        Binder.getCallingUserHandle().getIdentifier());
8841                if (uid != callingUid) {
8842                    throw new SecurityException("Invalid uid, expected " + uid);
8843                }
8844            } catch (NameNotFoundException e) {
8845                Log.d(TAG, "stopLockTaskMode " + e);
8846                return;
8847            }
8848        }
8849        long ident = Binder.clearCallingIdentity();
8850        try {
8851            Log.d(TAG, "stopLockTaskMode");
8852            // Stop lock task
8853            synchronized (this) {
8854                mStackSupervisor.setLockTaskModeLocked(null, false);
8855            }
8856        } finally {
8857            Binder.restoreCallingIdentity(ident);
8858        }
8859    }
8860
8861    @Override
8862    public void stopLockTaskModeOnCurrent() throws RemoteException {
8863        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8864                "stopLockTaskModeOnCurrent");
8865        long ident = Binder.clearCallingIdentity();
8866        try {
8867            stopLockTaskMode();
8868        } finally {
8869            Binder.restoreCallingIdentity(ident);
8870        }
8871    }
8872
8873    @Override
8874    public boolean isInLockTaskMode() {
8875        synchronized (this) {
8876            return mStackSupervisor.isInLockTaskMode();
8877        }
8878    }
8879
8880    // =========================================================
8881    // CONTENT PROVIDERS
8882    // =========================================================
8883
8884    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8885        List<ProviderInfo> providers = null;
8886        try {
8887            providers = AppGlobals.getPackageManager().
8888                queryContentProviders(app.processName, app.uid,
8889                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8890        } catch (RemoteException ex) {
8891        }
8892        if (DEBUG_MU)
8893            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8894        int userId = app.userId;
8895        if (providers != null) {
8896            int N = providers.size();
8897            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8898            for (int i=0; i<N; i++) {
8899                ProviderInfo cpi =
8900                    (ProviderInfo)providers.get(i);
8901                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8902                        cpi.name, cpi.flags);
8903                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8904                    // This is a singleton provider, but a user besides the
8905                    // default user is asking to initialize a process it runs
8906                    // in...  well, no, it doesn't actually run in this process,
8907                    // it runs in the process of the default user.  Get rid of it.
8908                    providers.remove(i);
8909                    N--;
8910                    i--;
8911                    continue;
8912                }
8913
8914                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8915                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8916                if (cpr == null) {
8917                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8918                    mProviderMap.putProviderByClass(comp, cpr);
8919                }
8920                if (DEBUG_MU)
8921                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8922                app.pubProviders.put(cpi.name, cpr);
8923                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8924                    // Don't add this if it is a platform component that is marked
8925                    // to run in multiple processes, because this is actually
8926                    // part of the framework so doesn't make sense to track as a
8927                    // separate apk in the process.
8928                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8929                            mProcessStats);
8930                }
8931                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8932            }
8933        }
8934        return providers;
8935    }
8936
8937    /**
8938     * Check if {@link ProcessRecord} has a possible chance at accessing the
8939     * given {@link ProviderInfo}. Final permission checking is always done
8940     * in {@link ContentProvider}.
8941     */
8942    private final String checkContentProviderPermissionLocked(
8943            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8944        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8945        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8946        boolean checkedGrants = false;
8947        if (checkUser) {
8948            // Looking for cross-user grants before enforcing the typical cross-users permissions
8949            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8950            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8951                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8952                    return null;
8953                }
8954                checkedGrants = true;
8955            }
8956            userId = handleIncomingUser(callingPid, callingUid, userId,
8957                    false, ALLOW_NON_FULL,
8958                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8959            if (userId != tmpTargetUserId) {
8960                // When we actually went to determine the final targer user ID, this ended
8961                // up different than our initial check for the authority.  This is because
8962                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8963                // SELF.  So we need to re-check the grants again.
8964                checkedGrants = false;
8965            }
8966        }
8967        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8968                cpi.applicationInfo.uid, cpi.exported)
8969                == PackageManager.PERMISSION_GRANTED) {
8970            return null;
8971        }
8972        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8973                cpi.applicationInfo.uid, cpi.exported)
8974                == PackageManager.PERMISSION_GRANTED) {
8975            return null;
8976        }
8977
8978        PathPermission[] pps = cpi.pathPermissions;
8979        if (pps != null) {
8980            int i = pps.length;
8981            while (i > 0) {
8982                i--;
8983                PathPermission pp = pps[i];
8984                String pprperm = pp.getReadPermission();
8985                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8986                        cpi.applicationInfo.uid, cpi.exported)
8987                        == PackageManager.PERMISSION_GRANTED) {
8988                    return null;
8989                }
8990                String ppwperm = pp.getWritePermission();
8991                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8992                        cpi.applicationInfo.uid, cpi.exported)
8993                        == PackageManager.PERMISSION_GRANTED) {
8994                    return null;
8995                }
8996            }
8997        }
8998        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8999            return null;
9000        }
9001
9002        String msg;
9003        if (!cpi.exported) {
9004            msg = "Permission Denial: opening provider " + cpi.name
9005                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9006                    + ", uid=" + callingUid + ") that is not exported from uid "
9007                    + cpi.applicationInfo.uid;
9008        } else {
9009            msg = "Permission Denial: opening provider " + cpi.name
9010                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9011                    + ", uid=" + callingUid + ") requires "
9012                    + cpi.readPermission + " or " + cpi.writePermission;
9013        }
9014        Slog.w(TAG, msg);
9015        return msg;
9016    }
9017
9018    /**
9019     * Returns if the ContentProvider has granted a uri to callingUid
9020     */
9021    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9022        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9023        if (perms != null) {
9024            for (int i=perms.size()-1; i>=0; i--) {
9025                GrantUri grantUri = perms.keyAt(i);
9026                if (grantUri.sourceUserId == userId || !checkUser) {
9027                    if (matchesProvider(grantUri.uri, cpi)) {
9028                        return true;
9029                    }
9030                }
9031            }
9032        }
9033        return false;
9034    }
9035
9036    /**
9037     * Returns true if the uri authority is one of the authorities specified in the provider.
9038     */
9039    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9040        String uriAuth = uri.getAuthority();
9041        String cpiAuth = cpi.authority;
9042        if (cpiAuth.indexOf(';') == -1) {
9043            return cpiAuth.equals(uriAuth);
9044        }
9045        String[] cpiAuths = cpiAuth.split(";");
9046        int length = cpiAuths.length;
9047        for (int i = 0; i < length; i++) {
9048            if (cpiAuths[i].equals(uriAuth)) return true;
9049        }
9050        return false;
9051    }
9052
9053    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9054            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9055        if (r != null) {
9056            for (int i=0; i<r.conProviders.size(); i++) {
9057                ContentProviderConnection conn = r.conProviders.get(i);
9058                if (conn.provider == cpr) {
9059                    if (DEBUG_PROVIDER) Slog.v(TAG,
9060                            "Adding provider requested by "
9061                            + r.processName + " from process "
9062                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9063                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9064                    if (stable) {
9065                        conn.stableCount++;
9066                        conn.numStableIncs++;
9067                    } else {
9068                        conn.unstableCount++;
9069                        conn.numUnstableIncs++;
9070                    }
9071                    return conn;
9072                }
9073            }
9074            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9075            if (stable) {
9076                conn.stableCount = 1;
9077                conn.numStableIncs = 1;
9078            } else {
9079                conn.unstableCount = 1;
9080                conn.numUnstableIncs = 1;
9081            }
9082            cpr.connections.add(conn);
9083            r.conProviders.add(conn);
9084            return conn;
9085        }
9086        cpr.addExternalProcessHandleLocked(externalProcessToken);
9087        return null;
9088    }
9089
9090    boolean decProviderCountLocked(ContentProviderConnection conn,
9091            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9092        if (conn != null) {
9093            cpr = conn.provider;
9094            if (DEBUG_PROVIDER) Slog.v(TAG,
9095                    "Removing provider requested by "
9096                    + conn.client.processName + " from process "
9097                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9098                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9099            if (stable) {
9100                conn.stableCount--;
9101            } else {
9102                conn.unstableCount--;
9103            }
9104            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9105                cpr.connections.remove(conn);
9106                conn.client.conProviders.remove(conn);
9107                return true;
9108            }
9109            return false;
9110        }
9111        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9112        return false;
9113    }
9114
9115    private void checkTime(long startTime, String where) {
9116        long now = SystemClock.elapsedRealtime();
9117        if ((now-startTime) > 1000) {
9118            // If we are taking more than a second, log about it.
9119            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9120        }
9121    }
9122
9123    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9124            String name, IBinder token, boolean stable, int userId) {
9125        ContentProviderRecord cpr;
9126        ContentProviderConnection conn = null;
9127        ProviderInfo cpi = null;
9128
9129        synchronized(this) {
9130            long startTime = SystemClock.elapsedRealtime();
9131
9132            ProcessRecord r = null;
9133            if (caller != null) {
9134                r = getRecordForAppLocked(caller);
9135                if (r == null) {
9136                    throw new SecurityException(
9137                            "Unable to find app for caller " + caller
9138                          + " (pid=" + Binder.getCallingPid()
9139                          + ") when getting content provider " + name);
9140                }
9141            }
9142
9143            boolean checkCrossUser = true;
9144
9145            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9146
9147            // First check if this content provider has been published...
9148            cpr = mProviderMap.getProviderByName(name, userId);
9149            // If that didn't work, check if it exists for user 0 and then
9150            // verify that it's a singleton provider before using it.
9151            if (cpr == null && userId != UserHandle.USER_OWNER) {
9152                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9153                if (cpr != null) {
9154                    cpi = cpr.info;
9155                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9156                            cpi.name, cpi.flags)
9157                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9158                        userId = UserHandle.USER_OWNER;
9159                        checkCrossUser = false;
9160                    } else {
9161                        cpr = null;
9162                        cpi = null;
9163                    }
9164                }
9165            }
9166
9167            boolean providerRunning = cpr != null;
9168            if (providerRunning) {
9169                cpi = cpr.info;
9170                String msg;
9171                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9172                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9173                        != null) {
9174                    throw new SecurityException(msg);
9175                }
9176                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9177
9178                if (r != null && cpr.canRunHere(r)) {
9179                    // This provider has been published or is in the process
9180                    // of being published...  but it is also allowed to run
9181                    // in the caller's process, so don't make a connection
9182                    // and just let the caller instantiate its own instance.
9183                    ContentProviderHolder holder = cpr.newHolder(null);
9184                    // don't give caller the provider object, it needs
9185                    // to make its own.
9186                    holder.provider = null;
9187                    return holder;
9188                }
9189
9190                final long origId = Binder.clearCallingIdentity();
9191
9192                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9193
9194                // In this case the provider instance already exists, so we can
9195                // return it right away.
9196                conn = incProviderCountLocked(r, cpr, token, stable);
9197                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9198                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9199                        // If this is a perceptible app accessing the provider,
9200                        // make sure to count it as being accessed and thus
9201                        // back up on the LRU list.  This is good because
9202                        // content providers are often expensive to start.
9203                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9204                        updateLruProcessLocked(cpr.proc, false, null);
9205                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9206                    }
9207                }
9208
9209                if (cpr.proc != null) {
9210                    if (false) {
9211                        if (cpr.name.flattenToShortString().equals(
9212                                "com.android.providers.calendar/.CalendarProvider2")) {
9213                            Slog.v(TAG, "****************** KILLING "
9214                                + cpr.name.flattenToShortString());
9215                            Process.killProcess(cpr.proc.pid);
9216                        }
9217                    }
9218                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9219                    boolean success = updateOomAdjLocked(cpr.proc);
9220                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9221                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9222                    // NOTE: there is still a race here where a signal could be
9223                    // pending on the process even though we managed to update its
9224                    // adj level.  Not sure what to do about this, but at least
9225                    // the race is now smaller.
9226                    if (!success) {
9227                        // Uh oh...  it looks like the provider's process
9228                        // has been killed on us.  We need to wait for a new
9229                        // process to be started, and make sure its death
9230                        // doesn't kill our process.
9231                        Slog.i(TAG,
9232                                "Existing provider " + cpr.name.flattenToShortString()
9233                                + " is crashing; detaching " + r);
9234                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9235                        checkTime(startTime, "getContentProviderImpl: before appDied");
9236                        appDiedLocked(cpr.proc);
9237                        checkTime(startTime, "getContentProviderImpl: after appDied");
9238                        if (!lastRef) {
9239                            // This wasn't the last ref our process had on
9240                            // the provider...  we have now been killed, bail.
9241                            return null;
9242                        }
9243                        providerRunning = false;
9244                        conn = null;
9245                    }
9246                }
9247
9248                Binder.restoreCallingIdentity(origId);
9249            }
9250
9251            boolean singleton;
9252            if (!providerRunning) {
9253                try {
9254                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9255                    cpi = AppGlobals.getPackageManager().
9256                        resolveContentProvider(name,
9257                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9258                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9259                } catch (RemoteException ex) {
9260                }
9261                if (cpi == null) {
9262                    return null;
9263                }
9264                // If the provider is a singleton AND
9265                // (it's a call within the same user || the provider is a
9266                // privileged app)
9267                // Then allow connecting to the singleton provider
9268                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9269                        cpi.name, cpi.flags)
9270                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9271                if (singleton) {
9272                    userId = UserHandle.USER_OWNER;
9273                }
9274                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9275                checkTime(startTime, "getContentProviderImpl: got app info for user");
9276
9277                String msg;
9278                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9279                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9280                        != null) {
9281                    throw new SecurityException(msg);
9282                }
9283                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9284
9285                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9286                        && !cpi.processName.equals("system")) {
9287                    // If this content provider does not run in the system
9288                    // process, and the system is not yet ready to run other
9289                    // processes, then fail fast instead of hanging.
9290                    throw new IllegalArgumentException(
9291                            "Attempt to launch content provider before system ready");
9292                }
9293
9294                // Make sure that the user who owns this provider is started.  If not,
9295                // we don't want to allow it to run.
9296                if (mStartedUsers.get(userId) == null) {
9297                    Slog.w(TAG, "Unable to launch app "
9298                            + cpi.applicationInfo.packageName + "/"
9299                            + cpi.applicationInfo.uid + " for provider "
9300                            + name + ": user " + userId + " is stopped");
9301                    return null;
9302                }
9303
9304                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9305                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9306                cpr = mProviderMap.getProviderByClass(comp, userId);
9307                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9308                final boolean firstClass = cpr == null;
9309                if (firstClass) {
9310                    try {
9311                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9312                        ApplicationInfo ai =
9313                            AppGlobals.getPackageManager().
9314                                getApplicationInfo(
9315                                        cpi.applicationInfo.packageName,
9316                                        STOCK_PM_FLAGS, userId);
9317                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9318                        if (ai == null) {
9319                            Slog.w(TAG, "No package info for content provider "
9320                                    + cpi.name);
9321                            return null;
9322                        }
9323                        ai = getAppInfoForUser(ai, userId);
9324                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9325                    } catch (RemoteException ex) {
9326                        // pm is in same process, this will never happen.
9327                    }
9328                }
9329
9330                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9331
9332                if (r != null && cpr.canRunHere(r)) {
9333                    // If this is a multiprocess provider, then just return its
9334                    // info and allow the caller to instantiate it.  Only do
9335                    // this if the provider is the same user as the caller's
9336                    // process, or can run as root (so can be in any process).
9337                    return cpr.newHolder(null);
9338                }
9339
9340                if (DEBUG_PROVIDER) {
9341                    RuntimeException e = new RuntimeException("here");
9342                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9343                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9344                }
9345
9346                // This is single process, and our app is now connecting to it.
9347                // See if we are already in the process of launching this
9348                // provider.
9349                final int N = mLaunchingProviders.size();
9350                int i;
9351                for (i=0; i<N; i++) {
9352                    if (mLaunchingProviders.get(i) == cpr) {
9353                        break;
9354                    }
9355                }
9356
9357                // If the provider is not already being launched, then get it
9358                // started.
9359                if (i >= N) {
9360                    final long origId = Binder.clearCallingIdentity();
9361
9362                    try {
9363                        // Content provider is now in use, its package can't be stopped.
9364                        try {
9365                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9366                            AppGlobals.getPackageManager().setPackageStoppedState(
9367                                    cpr.appInfo.packageName, false, userId);
9368                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9369                        } catch (RemoteException e) {
9370                        } catch (IllegalArgumentException e) {
9371                            Slog.w(TAG, "Failed trying to unstop package "
9372                                    + cpr.appInfo.packageName + ": " + e);
9373                        }
9374
9375                        // Use existing process if already started
9376                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9377                        ProcessRecord proc = getProcessRecordLocked(
9378                                cpi.processName, cpr.appInfo.uid, false);
9379                        if (proc != null && proc.thread != null) {
9380                            if (DEBUG_PROVIDER) {
9381                                Slog.d(TAG, "Installing in existing process " + proc);
9382                            }
9383                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9384                            proc.pubProviders.put(cpi.name, cpr);
9385                            try {
9386                                proc.thread.scheduleInstallProvider(cpi);
9387                            } catch (RemoteException e) {
9388                            }
9389                        } else {
9390                            checkTime(startTime, "getContentProviderImpl: before start process");
9391                            proc = startProcessLocked(cpi.processName,
9392                                    cpr.appInfo, false, 0, "content provider",
9393                                    new ComponentName(cpi.applicationInfo.packageName,
9394                                            cpi.name), false, false, false);
9395                            checkTime(startTime, "getContentProviderImpl: after start process");
9396                            if (proc == null) {
9397                                Slog.w(TAG, "Unable to launch app "
9398                                        + cpi.applicationInfo.packageName + "/"
9399                                        + cpi.applicationInfo.uid + " for provider "
9400                                        + name + ": process is bad");
9401                                return null;
9402                            }
9403                        }
9404                        cpr.launchingApp = proc;
9405                        mLaunchingProviders.add(cpr);
9406                    } finally {
9407                        Binder.restoreCallingIdentity(origId);
9408                    }
9409                }
9410
9411                checkTime(startTime, "getContentProviderImpl: updating data structures");
9412
9413                // Make sure the provider is published (the same provider class
9414                // may be published under multiple names).
9415                if (firstClass) {
9416                    mProviderMap.putProviderByClass(comp, cpr);
9417                }
9418
9419                mProviderMap.putProviderByName(name, cpr);
9420                conn = incProviderCountLocked(r, cpr, token, stable);
9421                if (conn != null) {
9422                    conn.waiting = true;
9423                }
9424            }
9425            checkTime(startTime, "getContentProviderImpl: done!");
9426        }
9427
9428        // Wait for the provider to be published...
9429        synchronized (cpr) {
9430            while (cpr.provider == null) {
9431                if (cpr.launchingApp == null) {
9432                    Slog.w(TAG, "Unable to launch app "
9433                            + cpi.applicationInfo.packageName + "/"
9434                            + cpi.applicationInfo.uid + " for provider "
9435                            + name + ": launching app became null");
9436                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9437                            UserHandle.getUserId(cpi.applicationInfo.uid),
9438                            cpi.applicationInfo.packageName,
9439                            cpi.applicationInfo.uid, name);
9440                    return null;
9441                }
9442                try {
9443                    if (DEBUG_MU) {
9444                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9445                                + cpr.launchingApp);
9446                    }
9447                    if (conn != null) {
9448                        conn.waiting = true;
9449                    }
9450                    cpr.wait();
9451                } catch (InterruptedException ex) {
9452                } finally {
9453                    if (conn != null) {
9454                        conn.waiting = false;
9455                    }
9456                }
9457            }
9458        }
9459        return cpr != null ? cpr.newHolder(conn) : null;
9460    }
9461
9462    @Override
9463    public final ContentProviderHolder getContentProvider(
9464            IApplicationThread caller, String name, int userId, boolean stable) {
9465        enforceNotIsolatedCaller("getContentProvider");
9466        if (caller == null) {
9467            String msg = "null IApplicationThread when getting content provider "
9468                    + name;
9469            Slog.w(TAG, msg);
9470            throw new SecurityException(msg);
9471        }
9472        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9473        // with cross-user grant.
9474        return getContentProviderImpl(caller, name, null, stable, userId);
9475    }
9476
9477    public ContentProviderHolder getContentProviderExternal(
9478            String name, int userId, IBinder token) {
9479        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9480            "Do not have permission in call getContentProviderExternal()");
9481        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9482                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9483        return getContentProviderExternalUnchecked(name, token, userId);
9484    }
9485
9486    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9487            IBinder token, int userId) {
9488        return getContentProviderImpl(null, name, token, true, userId);
9489    }
9490
9491    /**
9492     * Drop a content provider from a ProcessRecord's bookkeeping
9493     */
9494    public void removeContentProvider(IBinder connection, boolean stable) {
9495        enforceNotIsolatedCaller("removeContentProvider");
9496        long ident = Binder.clearCallingIdentity();
9497        try {
9498            synchronized (this) {
9499                ContentProviderConnection conn;
9500                try {
9501                    conn = (ContentProviderConnection)connection;
9502                } catch (ClassCastException e) {
9503                    String msg ="removeContentProvider: " + connection
9504                            + " not a ContentProviderConnection";
9505                    Slog.w(TAG, msg);
9506                    throw new IllegalArgumentException(msg);
9507                }
9508                if (conn == null) {
9509                    throw new NullPointerException("connection is null");
9510                }
9511                if (decProviderCountLocked(conn, null, null, stable)) {
9512                    updateOomAdjLocked();
9513                }
9514            }
9515        } finally {
9516            Binder.restoreCallingIdentity(ident);
9517        }
9518    }
9519
9520    public void removeContentProviderExternal(String name, IBinder token) {
9521        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9522            "Do not have permission in call removeContentProviderExternal()");
9523        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9524    }
9525
9526    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9527        synchronized (this) {
9528            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9529            if(cpr == null) {
9530                //remove from mProvidersByClass
9531                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9532                return;
9533            }
9534
9535            //update content provider record entry info
9536            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9537            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9538            if (localCpr.hasExternalProcessHandles()) {
9539                if (localCpr.removeExternalProcessHandleLocked(token)) {
9540                    updateOomAdjLocked();
9541                } else {
9542                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9543                            + " with no external reference for token: "
9544                            + token + ".");
9545                }
9546            } else {
9547                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9548                        + " with no external references.");
9549            }
9550        }
9551    }
9552
9553    public final void publishContentProviders(IApplicationThread caller,
9554            List<ContentProviderHolder> providers) {
9555        if (providers == null) {
9556            return;
9557        }
9558
9559        enforceNotIsolatedCaller("publishContentProviders");
9560        synchronized (this) {
9561            final ProcessRecord r = getRecordForAppLocked(caller);
9562            if (DEBUG_MU)
9563                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9564            if (r == null) {
9565                throw new SecurityException(
9566                        "Unable to find app for caller " + caller
9567                      + " (pid=" + Binder.getCallingPid()
9568                      + ") when publishing content providers");
9569            }
9570
9571            final long origId = Binder.clearCallingIdentity();
9572
9573            final int N = providers.size();
9574            for (int i=0; i<N; i++) {
9575                ContentProviderHolder src = providers.get(i);
9576                if (src == null || src.info == null || src.provider == null) {
9577                    continue;
9578                }
9579                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9580                if (DEBUG_MU)
9581                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9582                if (dst != null) {
9583                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9584                    mProviderMap.putProviderByClass(comp, dst);
9585                    String names[] = dst.info.authority.split(";");
9586                    for (int j = 0; j < names.length; j++) {
9587                        mProviderMap.putProviderByName(names[j], dst);
9588                    }
9589
9590                    int NL = mLaunchingProviders.size();
9591                    int j;
9592                    for (j=0; j<NL; j++) {
9593                        if (mLaunchingProviders.get(j) == dst) {
9594                            mLaunchingProviders.remove(j);
9595                            j--;
9596                            NL--;
9597                        }
9598                    }
9599                    synchronized (dst) {
9600                        dst.provider = src.provider;
9601                        dst.proc = r;
9602                        dst.notifyAll();
9603                    }
9604                    updateOomAdjLocked(r);
9605                }
9606            }
9607
9608            Binder.restoreCallingIdentity(origId);
9609        }
9610    }
9611
9612    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9613        ContentProviderConnection conn;
9614        try {
9615            conn = (ContentProviderConnection)connection;
9616        } catch (ClassCastException e) {
9617            String msg ="refContentProvider: " + connection
9618                    + " not a ContentProviderConnection";
9619            Slog.w(TAG, msg);
9620            throw new IllegalArgumentException(msg);
9621        }
9622        if (conn == null) {
9623            throw new NullPointerException("connection is null");
9624        }
9625
9626        synchronized (this) {
9627            if (stable > 0) {
9628                conn.numStableIncs += stable;
9629            }
9630            stable = conn.stableCount + stable;
9631            if (stable < 0) {
9632                throw new IllegalStateException("stableCount < 0: " + stable);
9633            }
9634
9635            if (unstable > 0) {
9636                conn.numUnstableIncs += unstable;
9637            }
9638            unstable = conn.unstableCount + unstable;
9639            if (unstable < 0) {
9640                throw new IllegalStateException("unstableCount < 0: " + unstable);
9641            }
9642
9643            if ((stable+unstable) <= 0) {
9644                throw new IllegalStateException("ref counts can't go to zero here: stable="
9645                        + stable + " unstable=" + unstable);
9646            }
9647            conn.stableCount = stable;
9648            conn.unstableCount = unstable;
9649            return !conn.dead;
9650        }
9651    }
9652
9653    public void unstableProviderDied(IBinder connection) {
9654        ContentProviderConnection conn;
9655        try {
9656            conn = (ContentProviderConnection)connection;
9657        } catch (ClassCastException e) {
9658            String msg ="refContentProvider: " + connection
9659                    + " not a ContentProviderConnection";
9660            Slog.w(TAG, msg);
9661            throw new IllegalArgumentException(msg);
9662        }
9663        if (conn == null) {
9664            throw new NullPointerException("connection is null");
9665        }
9666
9667        // Safely retrieve the content provider associated with the connection.
9668        IContentProvider provider;
9669        synchronized (this) {
9670            provider = conn.provider.provider;
9671        }
9672
9673        if (provider == null) {
9674            // Um, yeah, we're way ahead of you.
9675            return;
9676        }
9677
9678        // Make sure the caller is being honest with us.
9679        if (provider.asBinder().pingBinder()) {
9680            // Er, no, still looks good to us.
9681            synchronized (this) {
9682                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9683                        + " says " + conn + " died, but we don't agree");
9684                return;
9685            }
9686        }
9687
9688        // Well look at that!  It's dead!
9689        synchronized (this) {
9690            if (conn.provider.provider != provider) {
9691                // But something changed...  good enough.
9692                return;
9693            }
9694
9695            ProcessRecord proc = conn.provider.proc;
9696            if (proc == null || proc.thread == null) {
9697                // Seems like the process is already cleaned up.
9698                return;
9699            }
9700
9701            // As far as we're concerned, this is just like receiving a
9702            // death notification...  just a bit prematurely.
9703            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9704                    + ") early provider death");
9705            final long ident = Binder.clearCallingIdentity();
9706            try {
9707                appDiedLocked(proc);
9708            } finally {
9709                Binder.restoreCallingIdentity(ident);
9710            }
9711        }
9712    }
9713
9714    @Override
9715    public void appNotRespondingViaProvider(IBinder connection) {
9716        enforceCallingPermission(
9717                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9718
9719        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9720        if (conn == null) {
9721            Slog.w(TAG, "ContentProviderConnection is null");
9722            return;
9723        }
9724
9725        final ProcessRecord host = conn.provider.proc;
9726        if (host == null) {
9727            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9728            return;
9729        }
9730
9731        final long token = Binder.clearCallingIdentity();
9732        try {
9733            appNotResponding(host, null, null, false, "ContentProvider not responding");
9734        } finally {
9735            Binder.restoreCallingIdentity(token);
9736        }
9737    }
9738
9739    public final void installSystemProviders() {
9740        List<ProviderInfo> providers;
9741        synchronized (this) {
9742            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9743            providers = generateApplicationProvidersLocked(app);
9744            if (providers != null) {
9745                for (int i=providers.size()-1; i>=0; i--) {
9746                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9747                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9748                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9749                                + ": not system .apk");
9750                        providers.remove(i);
9751                    }
9752                }
9753            }
9754        }
9755        if (providers != null) {
9756            mSystemThread.installSystemProviders(providers);
9757        }
9758
9759        mCoreSettingsObserver = new CoreSettingsObserver(this);
9760
9761        //mUsageStatsService.monitorPackages();
9762    }
9763
9764    /**
9765     * Allows apps to retrieve the MIME type of a URI.
9766     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9767     * users, then it does not need permission to access the ContentProvider.
9768     * Either, it needs cross-user uri grants.
9769     *
9770     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9771     *
9772     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9773     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9774     */
9775    public String getProviderMimeType(Uri uri, int userId) {
9776        enforceNotIsolatedCaller("getProviderMimeType");
9777        final String name = uri.getAuthority();
9778        int callingUid = Binder.getCallingUid();
9779        int callingPid = Binder.getCallingPid();
9780        long ident = 0;
9781        boolean clearedIdentity = false;
9782        userId = unsafeConvertIncomingUser(userId);
9783        if (canClearIdentity(callingPid, callingUid, userId)) {
9784            clearedIdentity = true;
9785            ident = Binder.clearCallingIdentity();
9786        }
9787        ContentProviderHolder holder = null;
9788        try {
9789            holder = getContentProviderExternalUnchecked(name, null, userId);
9790            if (holder != null) {
9791                return holder.provider.getType(uri);
9792            }
9793        } catch (RemoteException e) {
9794            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9795            return null;
9796        } finally {
9797            // We need to clear the identity to call removeContentProviderExternalUnchecked
9798            if (!clearedIdentity) {
9799                ident = Binder.clearCallingIdentity();
9800            }
9801            try {
9802                if (holder != null) {
9803                    removeContentProviderExternalUnchecked(name, null, userId);
9804                }
9805            } finally {
9806                Binder.restoreCallingIdentity(ident);
9807            }
9808        }
9809
9810        return null;
9811    }
9812
9813    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9814        if (UserHandle.getUserId(callingUid) == userId) {
9815            return true;
9816        }
9817        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9818                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9819                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9820                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9821                return true;
9822        }
9823        return false;
9824    }
9825
9826    // =========================================================
9827    // GLOBAL MANAGEMENT
9828    // =========================================================
9829
9830    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9831            boolean isolated, int isolatedUid) {
9832        String proc = customProcess != null ? customProcess : info.processName;
9833        BatteryStatsImpl.Uid.Proc ps = null;
9834        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9835        int uid = info.uid;
9836        if (isolated) {
9837            if (isolatedUid == 0) {
9838                int userId = UserHandle.getUserId(uid);
9839                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9840                while (true) {
9841                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9842                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9843                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9844                    }
9845                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9846                    mNextIsolatedProcessUid++;
9847                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9848                        // No process for this uid, use it.
9849                        break;
9850                    }
9851                    stepsLeft--;
9852                    if (stepsLeft <= 0) {
9853                        return null;
9854                    }
9855                }
9856            } else {
9857                // Special case for startIsolatedProcess (internal only), where
9858                // the uid of the isolated process is specified by the caller.
9859                uid = isolatedUid;
9860            }
9861        }
9862        return new ProcessRecord(stats, info, proc, uid);
9863    }
9864
9865    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9866            String abiOverride) {
9867        ProcessRecord app;
9868        if (!isolated) {
9869            app = getProcessRecordLocked(info.processName, info.uid, true);
9870        } else {
9871            app = null;
9872        }
9873
9874        if (app == null) {
9875            app = newProcessRecordLocked(info, null, isolated, 0);
9876            mProcessNames.put(info.processName, app.uid, app);
9877            if (isolated) {
9878                mIsolatedProcesses.put(app.uid, app);
9879            }
9880            updateLruProcessLocked(app, false, null);
9881            updateOomAdjLocked();
9882        }
9883
9884        // This package really, really can not be stopped.
9885        try {
9886            AppGlobals.getPackageManager().setPackageStoppedState(
9887                    info.packageName, false, UserHandle.getUserId(app.uid));
9888        } catch (RemoteException e) {
9889        } catch (IllegalArgumentException e) {
9890            Slog.w(TAG, "Failed trying to unstop package "
9891                    + info.packageName + ": " + e);
9892        }
9893
9894        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9895                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9896            app.persistent = true;
9897            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9898        }
9899        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9900            mPersistentStartingProcesses.add(app);
9901            startProcessLocked(app, "added application", app.processName, abiOverride,
9902                    null /* entryPoint */, null /* entryPointArgs */);
9903        }
9904
9905        return app;
9906    }
9907
9908    public void unhandledBack() {
9909        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9910                "unhandledBack()");
9911
9912        synchronized(this) {
9913            final long origId = Binder.clearCallingIdentity();
9914            try {
9915                getFocusedStack().unhandledBackLocked();
9916            } finally {
9917                Binder.restoreCallingIdentity(origId);
9918            }
9919        }
9920    }
9921
9922    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9923        enforceNotIsolatedCaller("openContentUri");
9924        final int userId = UserHandle.getCallingUserId();
9925        String name = uri.getAuthority();
9926        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9927        ParcelFileDescriptor pfd = null;
9928        if (cph != null) {
9929            // We record the binder invoker's uid in thread-local storage before
9930            // going to the content provider to open the file.  Later, in the code
9931            // that handles all permissions checks, we look for this uid and use
9932            // that rather than the Activity Manager's own uid.  The effect is that
9933            // we do the check against the caller's permissions even though it looks
9934            // to the content provider like the Activity Manager itself is making
9935            // the request.
9936            sCallerIdentity.set(new Identity(
9937                    Binder.getCallingPid(), Binder.getCallingUid()));
9938            try {
9939                pfd = cph.provider.openFile(null, uri, "r", null);
9940            } catch (FileNotFoundException e) {
9941                // do nothing; pfd will be returned null
9942            } finally {
9943                // Ensure that whatever happens, we clean up the identity state
9944                sCallerIdentity.remove();
9945            }
9946
9947            // We've got the fd now, so we're done with the provider.
9948            removeContentProviderExternalUnchecked(name, null, userId);
9949        } else {
9950            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9951        }
9952        return pfd;
9953    }
9954
9955    // Actually is sleeping or shutting down or whatever else in the future
9956    // is an inactive state.
9957    public boolean isSleepingOrShuttingDown() {
9958        return isSleeping() || mShuttingDown;
9959    }
9960
9961    public boolean isSleeping() {
9962        return mSleeping && !mKeyguardWaitingForDraw;
9963    }
9964
9965    void goingToSleep() {
9966        synchronized(this) {
9967            mWentToSleep = true;
9968            updateEventDispatchingLocked();
9969            goToSleepIfNeededLocked();
9970        }
9971    }
9972
9973    void finishRunningVoiceLocked() {
9974        if (mRunningVoice) {
9975            mRunningVoice = false;
9976            goToSleepIfNeededLocked();
9977        }
9978    }
9979
9980    void goToSleepIfNeededLocked() {
9981        if (mWentToSleep && !mRunningVoice) {
9982            if (!mSleeping) {
9983                mSleeping = true;
9984                mKeyguardWaitingForDraw = false;
9985                mStackSupervisor.goingToSleepLocked();
9986
9987                // Initialize the wake times of all processes.
9988                checkExcessivePowerUsageLocked(false);
9989                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9990                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9991                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9992            }
9993        }
9994    }
9995
9996    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9997        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9998            // Never persist the home stack.
9999            return;
10000        }
10001        mTaskPersister.wakeup(task, flush);
10002    }
10003
10004    @Override
10005    public boolean shutdown(int timeout) {
10006        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10007                != PackageManager.PERMISSION_GRANTED) {
10008            throw new SecurityException("Requires permission "
10009                    + android.Manifest.permission.SHUTDOWN);
10010        }
10011
10012        boolean timedout = false;
10013
10014        synchronized(this) {
10015            mShuttingDown = true;
10016            updateEventDispatchingLocked();
10017            timedout = mStackSupervisor.shutdownLocked(timeout);
10018        }
10019
10020        mAppOpsService.shutdown();
10021        if (mUsageStatsService != null) {
10022            mUsageStatsService.prepareShutdown();
10023        }
10024        mBatteryStatsService.shutdown();
10025        synchronized (this) {
10026            mProcessStats.shutdownLocked();
10027        }
10028        notifyTaskPersisterLocked(null, true);
10029
10030        return timedout;
10031    }
10032
10033    public final void activitySlept(IBinder token) {
10034        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10035
10036        final long origId = Binder.clearCallingIdentity();
10037
10038        synchronized (this) {
10039            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10040            if (r != null) {
10041                mStackSupervisor.activitySleptLocked(r);
10042            }
10043        }
10044
10045        Binder.restoreCallingIdentity(origId);
10046    }
10047
10048    void logLockScreen(String msg) {
10049        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10050                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
10051                mWentToSleep + " mSleeping=" + mSleeping);
10052    }
10053
10054    private void comeOutOfSleepIfNeededLocked() {
10055        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
10056            if (mSleeping) {
10057                mSleeping = false;
10058                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10059            }
10060        }
10061    }
10062
10063    void wakingUp() {
10064        synchronized(this) {
10065            mWentToSleep = false;
10066            updateEventDispatchingLocked();
10067            comeOutOfSleepIfNeededLocked();
10068        }
10069    }
10070
10071    void startRunningVoiceLocked() {
10072        if (!mRunningVoice) {
10073            mRunningVoice = true;
10074            comeOutOfSleepIfNeededLocked();
10075        }
10076    }
10077
10078    private void updateEventDispatchingLocked() {
10079        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10080    }
10081
10082    public void setLockScreenShown(boolean shown) {
10083        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10084                != PackageManager.PERMISSION_GRANTED) {
10085            throw new SecurityException("Requires permission "
10086                    + android.Manifest.permission.DEVICE_POWER);
10087        }
10088
10089        synchronized(this) {
10090            long ident = Binder.clearCallingIdentity();
10091            try {
10092                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10093                mLockScreenShown = shown;
10094                mKeyguardWaitingForDraw = false;
10095                comeOutOfSleepIfNeededLocked();
10096            } finally {
10097                Binder.restoreCallingIdentity(ident);
10098            }
10099        }
10100    }
10101
10102    @Override
10103    public void stopAppSwitches() {
10104        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10105                != PackageManager.PERMISSION_GRANTED) {
10106            throw new SecurityException("Requires permission "
10107                    + android.Manifest.permission.STOP_APP_SWITCHES);
10108        }
10109
10110        synchronized(this) {
10111            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10112                    + APP_SWITCH_DELAY_TIME;
10113            mDidAppSwitch = false;
10114            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10115            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10116            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10117        }
10118    }
10119
10120    public void resumeAppSwitches() {
10121        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10122                != PackageManager.PERMISSION_GRANTED) {
10123            throw new SecurityException("Requires permission "
10124                    + android.Manifest.permission.STOP_APP_SWITCHES);
10125        }
10126
10127        synchronized(this) {
10128            // Note that we don't execute any pending app switches... we will
10129            // let those wait until either the timeout, or the next start
10130            // activity request.
10131            mAppSwitchesAllowedTime = 0;
10132        }
10133    }
10134
10135    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10136            int callingPid, int callingUid, String name) {
10137        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10138            return true;
10139        }
10140
10141        int perm = checkComponentPermission(
10142                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10143                sourceUid, -1, true);
10144        if (perm == PackageManager.PERMISSION_GRANTED) {
10145            return true;
10146        }
10147
10148        // If the actual IPC caller is different from the logical source, then
10149        // also see if they are allowed to control app switches.
10150        if (callingUid != -1 && callingUid != sourceUid) {
10151            perm = checkComponentPermission(
10152                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10153                    callingUid, -1, true);
10154            if (perm == PackageManager.PERMISSION_GRANTED) {
10155                return true;
10156            }
10157        }
10158
10159        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10160        return false;
10161    }
10162
10163    public void setDebugApp(String packageName, boolean waitForDebugger,
10164            boolean persistent) {
10165        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10166                "setDebugApp()");
10167
10168        long ident = Binder.clearCallingIdentity();
10169        try {
10170            // Note that this is not really thread safe if there are multiple
10171            // callers into it at the same time, but that's not a situation we
10172            // care about.
10173            if (persistent) {
10174                final ContentResolver resolver = mContext.getContentResolver();
10175                Settings.Global.putString(
10176                    resolver, Settings.Global.DEBUG_APP,
10177                    packageName);
10178                Settings.Global.putInt(
10179                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10180                    waitForDebugger ? 1 : 0);
10181            }
10182
10183            synchronized (this) {
10184                if (!persistent) {
10185                    mOrigDebugApp = mDebugApp;
10186                    mOrigWaitForDebugger = mWaitForDebugger;
10187                }
10188                mDebugApp = packageName;
10189                mWaitForDebugger = waitForDebugger;
10190                mDebugTransient = !persistent;
10191                if (packageName != null) {
10192                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10193                            false, UserHandle.USER_ALL, "set debug app");
10194                }
10195            }
10196        } finally {
10197            Binder.restoreCallingIdentity(ident);
10198        }
10199    }
10200
10201    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10202        synchronized (this) {
10203            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10204            if (!isDebuggable) {
10205                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10206                    throw new SecurityException("Process not debuggable: " + app.packageName);
10207                }
10208            }
10209
10210            mOpenGlTraceApp = processName;
10211        }
10212    }
10213
10214    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10215        synchronized (this) {
10216            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10217            if (!isDebuggable) {
10218                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10219                    throw new SecurityException("Process not debuggable: " + app.packageName);
10220                }
10221            }
10222            mProfileApp = processName;
10223            mProfileFile = profilerInfo.profileFile;
10224            if (mProfileFd != null) {
10225                try {
10226                    mProfileFd.close();
10227                } catch (IOException e) {
10228                }
10229                mProfileFd = null;
10230            }
10231            mProfileFd = profilerInfo.profileFd;
10232            mSamplingInterval = profilerInfo.samplingInterval;
10233            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10234            mProfileType = 0;
10235        }
10236    }
10237
10238    @Override
10239    public void setAlwaysFinish(boolean enabled) {
10240        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10241                "setAlwaysFinish()");
10242
10243        Settings.Global.putInt(
10244                mContext.getContentResolver(),
10245                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10246
10247        synchronized (this) {
10248            mAlwaysFinishActivities = enabled;
10249        }
10250    }
10251
10252    @Override
10253    public void setActivityController(IActivityController controller) {
10254        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10255                "setActivityController()");
10256        synchronized (this) {
10257            mController = controller;
10258            Watchdog.getInstance().setActivityController(controller);
10259        }
10260    }
10261
10262    @Override
10263    public void setUserIsMonkey(boolean userIsMonkey) {
10264        synchronized (this) {
10265            synchronized (mPidsSelfLocked) {
10266                final int callingPid = Binder.getCallingPid();
10267                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10268                if (precessRecord == null) {
10269                    throw new SecurityException("Unknown process: " + callingPid);
10270                }
10271                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10272                    throw new SecurityException("Only an instrumentation process "
10273                            + "with a UiAutomation can call setUserIsMonkey");
10274                }
10275            }
10276            mUserIsMonkey = userIsMonkey;
10277        }
10278    }
10279
10280    @Override
10281    public boolean isUserAMonkey() {
10282        synchronized (this) {
10283            // If there is a controller also implies the user is a monkey.
10284            return (mUserIsMonkey || mController != null);
10285        }
10286    }
10287
10288    public void requestBugReport() {
10289        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10290        SystemProperties.set("ctl.start", "bugreport");
10291    }
10292
10293    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10294        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10295    }
10296
10297    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10298        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10299            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10300        }
10301        return KEY_DISPATCHING_TIMEOUT;
10302    }
10303
10304    @Override
10305    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10306        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10307                != PackageManager.PERMISSION_GRANTED) {
10308            throw new SecurityException("Requires permission "
10309                    + android.Manifest.permission.FILTER_EVENTS);
10310        }
10311        ProcessRecord proc;
10312        long timeout;
10313        synchronized (this) {
10314            synchronized (mPidsSelfLocked) {
10315                proc = mPidsSelfLocked.get(pid);
10316            }
10317            timeout = getInputDispatchingTimeoutLocked(proc);
10318        }
10319
10320        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10321            return -1;
10322        }
10323
10324        return timeout;
10325    }
10326
10327    /**
10328     * Handle input dispatching timeouts.
10329     * Returns whether input dispatching should be aborted or not.
10330     */
10331    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10332            final ActivityRecord activity, final ActivityRecord parent,
10333            final boolean aboveSystem, String reason) {
10334        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10335                != PackageManager.PERMISSION_GRANTED) {
10336            throw new SecurityException("Requires permission "
10337                    + android.Manifest.permission.FILTER_EVENTS);
10338        }
10339
10340        final String annotation;
10341        if (reason == null) {
10342            annotation = "Input dispatching timed out";
10343        } else {
10344            annotation = "Input dispatching timed out (" + reason + ")";
10345        }
10346
10347        if (proc != null) {
10348            synchronized (this) {
10349                if (proc.debugging) {
10350                    return false;
10351                }
10352
10353                if (mDidDexOpt) {
10354                    // Give more time since we were dexopting.
10355                    mDidDexOpt = false;
10356                    return false;
10357                }
10358
10359                if (proc.instrumentationClass != null) {
10360                    Bundle info = new Bundle();
10361                    info.putString("shortMsg", "keyDispatchingTimedOut");
10362                    info.putString("longMsg", annotation);
10363                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10364                    return true;
10365                }
10366            }
10367            mHandler.post(new Runnable() {
10368                @Override
10369                public void run() {
10370                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10371                }
10372            });
10373        }
10374
10375        return true;
10376    }
10377
10378    public Bundle getAssistContextExtras(int requestType) {
10379        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10380                "getAssistContextExtras()");
10381        PendingAssistExtras pae;
10382        Bundle extras = new Bundle();
10383        synchronized (this) {
10384            ActivityRecord activity = getFocusedStack().mResumedActivity;
10385            if (activity == null) {
10386                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10387                return null;
10388            }
10389            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10390            if (activity.app == null || activity.app.thread == null) {
10391                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10392                return extras;
10393            }
10394            if (activity.app.pid == Binder.getCallingPid()) {
10395                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10396                return extras;
10397            }
10398            pae = new PendingAssistExtras(activity);
10399            try {
10400                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10401                        requestType);
10402                mPendingAssistExtras.add(pae);
10403                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10404            } catch (RemoteException e) {
10405                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10406                return extras;
10407            }
10408        }
10409        synchronized (pae) {
10410            while (!pae.haveResult) {
10411                try {
10412                    pae.wait();
10413                } catch (InterruptedException e) {
10414                }
10415            }
10416            if (pae.result != null) {
10417                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10418            }
10419        }
10420        synchronized (this) {
10421            mPendingAssistExtras.remove(pae);
10422            mHandler.removeCallbacks(pae);
10423        }
10424        return extras;
10425    }
10426
10427    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10428        PendingAssistExtras pae = (PendingAssistExtras)token;
10429        synchronized (pae) {
10430            pae.result = extras;
10431            pae.haveResult = true;
10432            pae.notifyAll();
10433        }
10434    }
10435
10436    public void registerProcessObserver(IProcessObserver observer) {
10437        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10438                "registerProcessObserver()");
10439        synchronized (this) {
10440            mProcessObservers.register(observer);
10441        }
10442    }
10443
10444    @Override
10445    public void unregisterProcessObserver(IProcessObserver observer) {
10446        synchronized (this) {
10447            mProcessObservers.unregister(observer);
10448        }
10449    }
10450
10451    @Override
10452    public boolean convertFromTranslucent(IBinder token) {
10453        final long origId = Binder.clearCallingIdentity();
10454        try {
10455            synchronized (this) {
10456                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10457                if (r == null) {
10458                    return false;
10459                }
10460                final boolean translucentChanged = r.changeWindowTranslucency(true);
10461                if (translucentChanged) {
10462                    r.task.stack.releaseBackgroundResources();
10463                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10464                }
10465                mWindowManager.setAppFullscreen(token, true);
10466                return translucentChanged;
10467            }
10468        } finally {
10469            Binder.restoreCallingIdentity(origId);
10470        }
10471    }
10472
10473    @Override
10474    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10475        final long origId = Binder.clearCallingIdentity();
10476        try {
10477            synchronized (this) {
10478                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10479                if (r == null) {
10480                    return false;
10481                }
10482                int index = r.task.mActivities.lastIndexOf(r);
10483                if (index > 0) {
10484                    ActivityRecord under = r.task.mActivities.get(index - 1);
10485                    under.returningOptions = options;
10486                }
10487                final boolean translucentChanged = r.changeWindowTranslucency(false);
10488                if (translucentChanged) {
10489                    r.task.stack.convertToTranslucent(r);
10490                }
10491                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10492                mWindowManager.setAppFullscreen(token, false);
10493                return translucentChanged;
10494            }
10495        } finally {
10496            Binder.restoreCallingIdentity(origId);
10497        }
10498    }
10499
10500    @Override
10501    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10502        final long origId = Binder.clearCallingIdentity();
10503        try {
10504            synchronized (this) {
10505                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10506                if (r != null) {
10507                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10508                }
10509            }
10510            return false;
10511        } finally {
10512            Binder.restoreCallingIdentity(origId);
10513        }
10514    }
10515
10516    @Override
10517    public boolean isBackgroundVisibleBehind(IBinder token) {
10518        final long origId = Binder.clearCallingIdentity();
10519        try {
10520            synchronized (this) {
10521                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10522                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10523                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10524                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10525                return visible;
10526            }
10527        } finally {
10528            Binder.restoreCallingIdentity(origId);
10529        }
10530    }
10531
10532    @Override
10533    public ActivityOptions getActivityOptions(IBinder token) {
10534        final long origId = Binder.clearCallingIdentity();
10535        try {
10536            synchronized (this) {
10537                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10538                if (r != null) {
10539                    final ActivityOptions activityOptions = r.pendingOptions;
10540                    r.pendingOptions = null;
10541                    return activityOptions;
10542                }
10543                return null;
10544            }
10545        } finally {
10546            Binder.restoreCallingIdentity(origId);
10547        }
10548    }
10549
10550    @Override
10551    public void setImmersive(IBinder token, boolean immersive) {
10552        synchronized(this) {
10553            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10554            if (r == null) {
10555                throw new IllegalArgumentException();
10556            }
10557            r.immersive = immersive;
10558
10559            // update associated state if we're frontmost
10560            if (r == mFocusedActivity) {
10561                if (DEBUG_IMMERSIVE) {
10562                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10563                }
10564                applyUpdateLockStateLocked(r);
10565            }
10566        }
10567    }
10568
10569    @Override
10570    public boolean isImmersive(IBinder token) {
10571        synchronized (this) {
10572            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10573            if (r == null) {
10574                throw new IllegalArgumentException();
10575            }
10576            return r.immersive;
10577        }
10578    }
10579
10580    public boolean isTopActivityImmersive() {
10581        enforceNotIsolatedCaller("startActivity");
10582        synchronized (this) {
10583            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10584            return (r != null) ? r.immersive : false;
10585        }
10586    }
10587
10588    @Override
10589    public boolean isTopOfTask(IBinder token) {
10590        synchronized (this) {
10591            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10592            if (r == null) {
10593                throw new IllegalArgumentException();
10594            }
10595            return r.task.getTopActivity() == r;
10596        }
10597    }
10598
10599    public final void enterSafeMode() {
10600        synchronized(this) {
10601            // It only makes sense to do this before the system is ready
10602            // and started launching other packages.
10603            if (!mSystemReady) {
10604                try {
10605                    AppGlobals.getPackageManager().enterSafeMode();
10606                } catch (RemoteException e) {
10607                }
10608            }
10609
10610            mSafeMode = true;
10611        }
10612    }
10613
10614    public final void showSafeModeOverlay() {
10615        View v = LayoutInflater.from(mContext).inflate(
10616                com.android.internal.R.layout.safe_mode, null);
10617        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10618        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10619        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10620        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10621        lp.gravity = Gravity.BOTTOM | Gravity.START;
10622        lp.format = v.getBackground().getOpacity();
10623        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10624                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10625        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10626        ((WindowManager)mContext.getSystemService(
10627                Context.WINDOW_SERVICE)).addView(v, lp);
10628    }
10629
10630    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10631        if (!(sender instanceof PendingIntentRecord)) {
10632            return;
10633        }
10634        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10635        synchronized (stats) {
10636            if (mBatteryStatsService.isOnBattery()) {
10637                mBatteryStatsService.enforceCallingPermission();
10638                PendingIntentRecord rec = (PendingIntentRecord)sender;
10639                int MY_UID = Binder.getCallingUid();
10640                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10641                BatteryStatsImpl.Uid.Pkg pkg =
10642                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10643                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10644                pkg.incWakeupsLocked();
10645            }
10646        }
10647    }
10648
10649    public boolean killPids(int[] pids, String pReason, boolean secure) {
10650        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10651            throw new SecurityException("killPids only available to the system");
10652        }
10653        String reason = (pReason == null) ? "Unknown" : pReason;
10654        // XXX Note: don't acquire main activity lock here, because the window
10655        // manager calls in with its locks held.
10656
10657        boolean killed = false;
10658        synchronized (mPidsSelfLocked) {
10659            int[] types = new int[pids.length];
10660            int worstType = 0;
10661            for (int i=0; i<pids.length; i++) {
10662                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10663                if (proc != null) {
10664                    int type = proc.setAdj;
10665                    types[i] = type;
10666                    if (type > worstType) {
10667                        worstType = type;
10668                    }
10669                }
10670            }
10671
10672            // If the worst oom_adj is somewhere in the cached proc LRU range,
10673            // then constrain it so we will kill all cached procs.
10674            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10675                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10676                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10677            }
10678
10679            // If this is not a secure call, don't let it kill processes that
10680            // are important.
10681            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10682                worstType = ProcessList.SERVICE_ADJ;
10683            }
10684
10685            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10686            for (int i=0; i<pids.length; i++) {
10687                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10688                if (proc == null) {
10689                    continue;
10690                }
10691                int adj = proc.setAdj;
10692                if (adj >= worstType && !proc.killedByAm) {
10693                    proc.kill(reason, true);
10694                    killed = true;
10695                }
10696            }
10697        }
10698        return killed;
10699    }
10700
10701    @Override
10702    public void killUid(int uid, String reason) {
10703        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10704            throw new SecurityException("killUid only available to the system");
10705        }
10706        synchronized (this) {
10707            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10708                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10709                    reason != null ? reason : "kill uid");
10710        }
10711    }
10712
10713    @Override
10714    public boolean killProcessesBelowForeground(String reason) {
10715        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10716            throw new SecurityException("killProcessesBelowForeground() only available to system");
10717        }
10718
10719        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10720    }
10721
10722    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10723        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10724            throw new SecurityException("killProcessesBelowAdj() only available to system");
10725        }
10726
10727        boolean killed = false;
10728        synchronized (mPidsSelfLocked) {
10729            final int size = mPidsSelfLocked.size();
10730            for (int i = 0; i < size; i++) {
10731                final int pid = mPidsSelfLocked.keyAt(i);
10732                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10733                if (proc == null) continue;
10734
10735                final int adj = proc.setAdj;
10736                if (adj > belowAdj && !proc.killedByAm) {
10737                    proc.kill(reason, true);
10738                    killed = true;
10739                }
10740            }
10741        }
10742        return killed;
10743    }
10744
10745    @Override
10746    public void hang(final IBinder who, boolean allowRestart) {
10747        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10748                != PackageManager.PERMISSION_GRANTED) {
10749            throw new SecurityException("Requires permission "
10750                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10751        }
10752
10753        final IBinder.DeathRecipient death = new DeathRecipient() {
10754            @Override
10755            public void binderDied() {
10756                synchronized (this) {
10757                    notifyAll();
10758                }
10759            }
10760        };
10761
10762        try {
10763            who.linkToDeath(death, 0);
10764        } catch (RemoteException e) {
10765            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10766            return;
10767        }
10768
10769        synchronized (this) {
10770            Watchdog.getInstance().setAllowRestart(allowRestart);
10771            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10772            synchronized (death) {
10773                while (who.isBinderAlive()) {
10774                    try {
10775                        death.wait();
10776                    } catch (InterruptedException e) {
10777                    }
10778                }
10779            }
10780            Watchdog.getInstance().setAllowRestart(true);
10781        }
10782    }
10783
10784    @Override
10785    public void restart() {
10786        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10787                != PackageManager.PERMISSION_GRANTED) {
10788            throw new SecurityException("Requires permission "
10789                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10790        }
10791
10792        Log.i(TAG, "Sending shutdown broadcast...");
10793
10794        BroadcastReceiver br = new BroadcastReceiver() {
10795            @Override public void onReceive(Context context, Intent intent) {
10796                // Now the broadcast is done, finish up the low-level shutdown.
10797                Log.i(TAG, "Shutting down activity manager...");
10798                shutdown(10000);
10799                Log.i(TAG, "Shutdown complete, restarting!");
10800                Process.killProcess(Process.myPid());
10801                System.exit(10);
10802            }
10803        };
10804
10805        // First send the high-level shut down broadcast.
10806        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10807        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10808        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10809        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10810        mContext.sendOrderedBroadcastAsUser(intent,
10811                UserHandle.ALL, null, br, mHandler, 0, null, null);
10812        */
10813        br.onReceive(mContext, intent);
10814    }
10815
10816    private long getLowRamTimeSinceIdle(long now) {
10817        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10818    }
10819
10820    @Override
10821    public void performIdleMaintenance() {
10822        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10823                != PackageManager.PERMISSION_GRANTED) {
10824            throw new SecurityException("Requires permission "
10825                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10826        }
10827
10828        synchronized (this) {
10829            final long now = SystemClock.uptimeMillis();
10830            final long timeSinceLastIdle = now - mLastIdleTime;
10831            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10832            mLastIdleTime = now;
10833            mLowRamTimeSinceLastIdle = 0;
10834            if (mLowRamStartTime != 0) {
10835                mLowRamStartTime = now;
10836            }
10837
10838            StringBuilder sb = new StringBuilder(128);
10839            sb.append("Idle maintenance over ");
10840            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10841            sb.append(" low RAM for ");
10842            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10843            Slog.i(TAG, sb.toString());
10844
10845            // If at least 1/3 of our time since the last idle period has been spent
10846            // with RAM low, then we want to kill processes.
10847            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10848
10849            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10850                ProcessRecord proc = mLruProcesses.get(i);
10851                if (proc.notCachedSinceIdle) {
10852                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10853                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10854                        if (doKilling && proc.initialIdlePss != 0
10855                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10856                            proc.kill("idle maint (pss " + proc.lastPss
10857                                    + " from " + proc.initialIdlePss + ")", true);
10858                        }
10859                    }
10860                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10861                    proc.notCachedSinceIdle = true;
10862                    proc.initialIdlePss = 0;
10863                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10864                            isSleeping(), now);
10865                }
10866            }
10867
10868            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10869            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10870        }
10871    }
10872
10873    private void retrieveSettings() {
10874        final ContentResolver resolver = mContext.getContentResolver();
10875        String debugApp = Settings.Global.getString(
10876            resolver, Settings.Global.DEBUG_APP);
10877        boolean waitForDebugger = Settings.Global.getInt(
10878            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10879        boolean alwaysFinishActivities = Settings.Global.getInt(
10880            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10881        boolean forceRtl = Settings.Global.getInt(
10882                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10883        // Transfer any global setting for forcing RTL layout, into a System Property
10884        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10885
10886        Configuration configuration = new Configuration();
10887        Settings.System.getConfiguration(resolver, configuration);
10888        if (forceRtl) {
10889            // This will take care of setting the correct layout direction flags
10890            configuration.setLayoutDirection(configuration.locale);
10891        }
10892
10893        synchronized (this) {
10894            mDebugApp = mOrigDebugApp = debugApp;
10895            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10896            mAlwaysFinishActivities = alwaysFinishActivities;
10897            // This happens before any activities are started, so we can
10898            // change mConfiguration in-place.
10899            updateConfigurationLocked(configuration, null, false, true);
10900            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10901        }
10902    }
10903
10904    /** Loads resources after the current configuration has been set. */
10905    private void loadResourcesOnSystemReady() {
10906        final Resources res = mContext.getResources();
10907        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10908        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10909        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10910    }
10911
10912    public boolean testIsSystemReady() {
10913        // no need to synchronize(this) just to read & return the value
10914        return mSystemReady;
10915    }
10916
10917    private static File getCalledPreBootReceiversFile() {
10918        File dataDir = Environment.getDataDirectory();
10919        File systemDir = new File(dataDir, "system");
10920        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10921        return fname;
10922    }
10923
10924    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10925        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10926        File file = getCalledPreBootReceiversFile();
10927        FileInputStream fis = null;
10928        try {
10929            fis = new FileInputStream(file);
10930            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10931            int fvers = dis.readInt();
10932            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10933                String vers = dis.readUTF();
10934                String codename = dis.readUTF();
10935                String build = dis.readUTF();
10936                if (android.os.Build.VERSION.RELEASE.equals(vers)
10937                        && android.os.Build.VERSION.CODENAME.equals(codename)
10938                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10939                    int num = dis.readInt();
10940                    while (num > 0) {
10941                        num--;
10942                        String pkg = dis.readUTF();
10943                        String cls = dis.readUTF();
10944                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10945                    }
10946                }
10947            }
10948        } catch (FileNotFoundException e) {
10949        } catch (IOException e) {
10950            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10951        } finally {
10952            if (fis != null) {
10953                try {
10954                    fis.close();
10955                } catch (IOException e) {
10956                }
10957            }
10958        }
10959        return lastDoneReceivers;
10960    }
10961
10962    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10963        File file = getCalledPreBootReceiversFile();
10964        FileOutputStream fos = null;
10965        DataOutputStream dos = null;
10966        try {
10967            fos = new FileOutputStream(file);
10968            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10969            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10970            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10971            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10972            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10973            dos.writeInt(list.size());
10974            for (int i=0; i<list.size(); i++) {
10975                dos.writeUTF(list.get(i).getPackageName());
10976                dos.writeUTF(list.get(i).getClassName());
10977            }
10978        } catch (IOException e) {
10979            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10980            file.delete();
10981        } finally {
10982            FileUtils.sync(fos);
10983            if (dos != null) {
10984                try {
10985                    dos.close();
10986                } catch (IOException e) {
10987                    // TODO Auto-generated catch block
10988                    e.printStackTrace();
10989                }
10990            }
10991        }
10992    }
10993
10994    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10995            ArrayList<ComponentName> doneReceivers, int userId) {
10996        boolean waitingUpdate = false;
10997        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10998        List<ResolveInfo> ris = null;
10999        try {
11000            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11001                    intent, null, 0, userId);
11002        } catch (RemoteException e) {
11003        }
11004        if (ris != null) {
11005            for (int i=ris.size()-1; i>=0; i--) {
11006                if ((ris.get(i).activityInfo.applicationInfo.flags
11007                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11008                    ris.remove(i);
11009                }
11010            }
11011            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11012
11013            // For User 0, load the version number. When delivering to a new user, deliver
11014            // to all receivers.
11015            if (userId == UserHandle.USER_OWNER) {
11016                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11017                for (int i=0; i<ris.size(); i++) {
11018                    ActivityInfo ai = ris.get(i).activityInfo;
11019                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11020                    if (lastDoneReceivers.contains(comp)) {
11021                        // We already did the pre boot receiver for this app with the current
11022                        // platform version, so don't do it again...
11023                        ris.remove(i);
11024                        i--;
11025                        // ...however, do keep it as one that has been done, so we don't
11026                        // forget about it when rewriting the file of last done receivers.
11027                        doneReceivers.add(comp);
11028                    }
11029                }
11030            }
11031
11032            // If primary user, send broadcast to all available users, else just to userId
11033            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11034                    : new int[] { userId };
11035            for (int i = 0; i < ris.size(); i++) {
11036                ActivityInfo ai = ris.get(i).activityInfo;
11037                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11038                doneReceivers.add(comp);
11039                intent.setComponent(comp);
11040                for (int j=0; j<users.length; j++) {
11041                    IIntentReceiver finisher = null;
11042                    // On last receiver and user, set up a completion callback
11043                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11044                        finisher = new IIntentReceiver.Stub() {
11045                            public void performReceive(Intent intent, int resultCode,
11046                                    String data, Bundle extras, boolean ordered,
11047                                    boolean sticky, int sendingUser) {
11048                                // The raw IIntentReceiver interface is called
11049                                // with the AM lock held, so redispatch to
11050                                // execute our code without the lock.
11051                                mHandler.post(onFinishCallback);
11052                            }
11053                        };
11054                    }
11055                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11056                            + " for user " + users[j]);
11057                    broadcastIntentLocked(null, null, intent, null, finisher,
11058                            0, null, null, null, AppOpsManager.OP_NONE,
11059                            true, false, MY_PID, Process.SYSTEM_UID,
11060                            users[j]);
11061                    if (finisher != null) {
11062                        waitingUpdate = true;
11063                    }
11064                }
11065            }
11066        }
11067
11068        return waitingUpdate;
11069    }
11070
11071    public void systemReady(final Runnable goingCallback) {
11072        synchronized(this) {
11073            if (mSystemReady) {
11074                // If we're done calling all the receivers, run the next "boot phase" passed in
11075                // by the SystemServer
11076                if (goingCallback != null) {
11077                    goingCallback.run();
11078                }
11079                return;
11080            }
11081
11082            // Make sure we have the current profile info, since it is needed for
11083            // security checks.
11084            updateCurrentProfileIdsLocked();
11085
11086            if (mRecentTasks == null) {
11087                mRecentTasks = mTaskPersister.restoreTasksLocked();
11088                if (!mRecentTasks.isEmpty()) {
11089                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11090                }
11091                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11092                mTaskPersister.startPersisting();
11093            }
11094
11095            // Check to see if there are any update receivers to run.
11096            if (!mDidUpdate) {
11097                if (mWaitingUpdate) {
11098                    return;
11099                }
11100                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11101                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11102                    public void run() {
11103                        synchronized (ActivityManagerService.this) {
11104                            mDidUpdate = true;
11105                        }
11106                        writeLastDonePreBootReceivers(doneReceivers);
11107                        showBootMessage(mContext.getText(
11108                                R.string.android_upgrading_complete),
11109                                false);
11110                        systemReady(goingCallback);
11111                    }
11112                }, doneReceivers, UserHandle.USER_OWNER);
11113
11114                if (mWaitingUpdate) {
11115                    return;
11116                }
11117                mDidUpdate = true;
11118            }
11119
11120            mAppOpsService.systemReady();
11121            mSystemReady = true;
11122        }
11123
11124        ArrayList<ProcessRecord> procsToKill = null;
11125        synchronized(mPidsSelfLocked) {
11126            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11127                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11128                if (!isAllowedWhileBooting(proc.info)){
11129                    if (procsToKill == null) {
11130                        procsToKill = new ArrayList<ProcessRecord>();
11131                    }
11132                    procsToKill.add(proc);
11133                }
11134            }
11135        }
11136
11137        synchronized(this) {
11138            if (procsToKill != null) {
11139                for (int i=procsToKill.size()-1; i>=0; i--) {
11140                    ProcessRecord proc = procsToKill.get(i);
11141                    Slog.i(TAG, "Removing system update proc: " + proc);
11142                    removeProcessLocked(proc, true, false, "system update done");
11143                }
11144            }
11145
11146            // Now that we have cleaned up any update processes, we
11147            // are ready to start launching real processes and know that
11148            // we won't trample on them any more.
11149            mProcessesReady = true;
11150        }
11151
11152        Slog.i(TAG, "System now ready");
11153        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11154            SystemClock.uptimeMillis());
11155
11156        synchronized(this) {
11157            // Make sure we have no pre-ready processes sitting around.
11158
11159            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11160                ResolveInfo ri = mContext.getPackageManager()
11161                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11162                                STOCK_PM_FLAGS);
11163                CharSequence errorMsg = null;
11164                if (ri != null) {
11165                    ActivityInfo ai = ri.activityInfo;
11166                    ApplicationInfo app = ai.applicationInfo;
11167                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11168                        mTopAction = Intent.ACTION_FACTORY_TEST;
11169                        mTopData = null;
11170                        mTopComponent = new ComponentName(app.packageName,
11171                                ai.name);
11172                    } else {
11173                        errorMsg = mContext.getResources().getText(
11174                                com.android.internal.R.string.factorytest_not_system);
11175                    }
11176                } else {
11177                    errorMsg = mContext.getResources().getText(
11178                            com.android.internal.R.string.factorytest_no_action);
11179                }
11180                if (errorMsg != null) {
11181                    mTopAction = null;
11182                    mTopData = null;
11183                    mTopComponent = null;
11184                    Message msg = Message.obtain();
11185                    msg.what = SHOW_FACTORY_ERROR_MSG;
11186                    msg.getData().putCharSequence("msg", errorMsg);
11187                    mHandler.sendMessage(msg);
11188                }
11189            }
11190        }
11191
11192        retrieveSettings();
11193        loadResourcesOnSystemReady();
11194
11195        synchronized (this) {
11196            readGrantedUriPermissionsLocked();
11197        }
11198
11199        if (goingCallback != null) goingCallback.run();
11200
11201        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11202                Integer.toString(mCurrentUserId), mCurrentUserId);
11203        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11204                Integer.toString(mCurrentUserId), mCurrentUserId);
11205        mSystemServiceManager.startUser(mCurrentUserId);
11206
11207        synchronized (this) {
11208            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11209                try {
11210                    List apps = AppGlobals.getPackageManager().
11211                        getPersistentApplications(STOCK_PM_FLAGS);
11212                    if (apps != null) {
11213                        int N = apps.size();
11214                        int i;
11215                        for (i=0; i<N; i++) {
11216                            ApplicationInfo info
11217                                = (ApplicationInfo)apps.get(i);
11218                            if (info != null &&
11219                                    !info.packageName.equals("android")) {
11220                                addAppLocked(info, false, null /* ABI override */);
11221                            }
11222                        }
11223                    }
11224                } catch (RemoteException ex) {
11225                    // pm is in same process, this will never happen.
11226                }
11227            }
11228
11229            // Start up initial activity.
11230            mBooting = true;
11231
11232            try {
11233                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11234                    Message msg = Message.obtain();
11235                    msg.what = SHOW_UID_ERROR_MSG;
11236                    mHandler.sendMessage(msg);
11237                }
11238            } catch (RemoteException e) {
11239            }
11240
11241            long ident = Binder.clearCallingIdentity();
11242            try {
11243                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11244                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11245                        | Intent.FLAG_RECEIVER_FOREGROUND);
11246                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11247                broadcastIntentLocked(null, null, intent,
11248                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11249                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11250                intent = new Intent(Intent.ACTION_USER_STARTING);
11251                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11252                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11253                broadcastIntentLocked(null, null, intent,
11254                        null, new IIntentReceiver.Stub() {
11255                            @Override
11256                            public void performReceive(Intent intent, int resultCode, String data,
11257                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11258                                    throws RemoteException {
11259                            }
11260                        }, 0, null, null,
11261                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11262                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11263            } catch (Throwable t) {
11264                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11265            } finally {
11266                Binder.restoreCallingIdentity(ident);
11267            }
11268            mStackSupervisor.resumeTopActivitiesLocked();
11269            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11270        }
11271    }
11272
11273    private boolean makeAppCrashingLocked(ProcessRecord app,
11274            String shortMsg, String longMsg, String stackTrace) {
11275        app.crashing = true;
11276        app.crashingReport = generateProcessError(app,
11277                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11278        startAppProblemLocked(app);
11279        app.stopFreezingAllLocked();
11280        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11281    }
11282
11283    private void makeAppNotRespondingLocked(ProcessRecord app,
11284            String activity, String shortMsg, String longMsg) {
11285        app.notResponding = true;
11286        app.notRespondingReport = generateProcessError(app,
11287                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11288                activity, shortMsg, longMsg, null);
11289        startAppProblemLocked(app);
11290        app.stopFreezingAllLocked();
11291    }
11292
11293    /**
11294     * Generate a process error record, suitable for attachment to a ProcessRecord.
11295     *
11296     * @param app The ProcessRecord in which the error occurred.
11297     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11298     *                      ActivityManager.AppErrorStateInfo
11299     * @param activity The activity associated with the crash, if known.
11300     * @param shortMsg Short message describing the crash.
11301     * @param longMsg Long message describing the crash.
11302     * @param stackTrace Full crash stack trace, may be null.
11303     *
11304     * @return Returns a fully-formed AppErrorStateInfo record.
11305     */
11306    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11307            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11308        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11309
11310        report.condition = condition;
11311        report.processName = app.processName;
11312        report.pid = app.pid;
11313        report.uid = app.info.uid;
11314        report.tag = activity;
11315        report.shortMsg = shortMsg;
11316        report.longMsg = longMsg;
11317        report.stackTrace = stackTrace;
11318
11319        return report;
11320    }
11321
11322    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11323        synchronized (this) {
11324            app.crashing = false;
11325            app.crashingReport = null;
11326            app.notResponding = false;
11327            app.notRespondingReport = null;
11328            if (app.anrDialog == fromDialog) {
11329                app.anrDialog = null;
11330            }
11331            if (app.waitDialog == fromDialog) {
11332                app.waitDialog = null;
11333            }
11334            if (app.pid > 0 && app.pid != MY_PID) {
11335                handleAppCrashLocked(app, null, null, null);
11336                app.kill("user request after error", true);
11337            }
11338        }
11339    }
11340
11341    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11342            String stackTrace) {
11343        long now = SystemClock.uptimeMillis();
11344
11345        Long crashTime;
11346        if (!app.isolated) {
11347            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11348        } else {
11349            crashTime = null;
11350        }
11351        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11352            // This process loses!
11353            Slog.w(TAG, "Process " + app.info.processName
11354                    + " has crashed too many times: killing!");
11355            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11356                    app.userId, app.info.processName, app.uid);
11357            mStackSupervisor.handleAppCrashLocked(app);
11358            if (!app.persistent) {
11359                // We don't want to start this process again until the user
11360                // explicitly does so...  but for persistent process, we really
11361                // need to keep it running.  If a persistent process is actually
11362                // repeatedly crashing, then badness for everyone.
11363                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11364                        app.info.processName);
11365                if (!app.isolated) {
11366                    // XXX We don't have a way to mark isolated processes
11367                    // as bad, since they don't have a peristent identity.
11368                    mBadProcesses.put(app.info.processName, app.uid,
11369                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11370                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11371                }
11372                app.bad = true;
11373                app.removed = true;
11374                // Don't let services in this process be restarted and potentially
11375                // annoy the user repeatedly.  Unless it is persistent, since those
11376                // processes run critical code.
11377                removeProcessLocked(app, false, false, "crash");
11378                mStackSupervisor.resumeTopActivitiesLocked();
11379                return false;
11380            }
11381            mStackSupervisor.resumeTopActivitiesLocked();
11382        } else {
11383            mStackSupervisor.finishTopRunningActivityLocked(app);
11384        }
11385
11386        // Bump up the crash count of any services currently running in the proc.
11387        for (int i=app.services.size()-1; i>=0; i--) {
11388            // Any services running in the application need to be placed
11389            // back in the pending list.
11390            ServiceRecord sr = app.services.valueAt(i);
11391            sr.crashCount++;
11392        }
11393
11394        // If the crashing process is what we consider to be the "home process" and it has been
11395        // replaced by a third-party app, clear the package preferred activities from packages
11396        // with a home activity running in the process to prevent a repeatedly crashing app
11397        // from blocking the user to manually clear the list.
11398        final ArrayList<ActivityRecord> activities = app.activities;
11399        if (app == mHomeProcess && activities.size() > 0
11400                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11401            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11402                final ActivityRecord r = activities.get(activityNdx);
11403                if (r.isHomeActivity()) {
11404                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11405                    try {
11406                        ActivityThread.getPackageManager()
11407                                .clearPackagePreferredActivities(r.packageName);
11408                    } catch (RemoteException c) {
11409                        // pm is in same process, this will never happen.
11410                    }
11411                }
11412            }
11413        }
11414
11415        if (!app.isolated) {
11416            // XXX Can't keep track of crash times for isolated processes,
11417            // because they don't have a perisistent identity.
11418            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11419        }
11420
11421        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11422        return true;
11423    }
11424
11425    void startAppProblemLocked(ProcessRecord app) {
11426        // If this app is not running under the current user, then we
11427        // can't give it a report button because that would require
11428        // launching the report UI under a different user.
11429        app.errorReportReceiver = null;
11430
11431        for (int userId : mCurrentProfileIds) {
11432            if (app.userId == userId) {
11433                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11434                        mContext, app.info.packageName, app.info.flags);
11435            }
11436        }
11437        skipCurrentReceiverLocked(app);
11438    }
11439
11440    void skipCurrentReceiverLocked(ProcessRecord app) {
11441        for (BroadcastQueue queue : mBroadcastQueues) {
11442            queue.skipCurrentReceiverLocked(app);
11443        }
11444    }
11445
11446    /**
11447     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11448     * The application process will exit immediately after this call returns.
11449     * @param app object of the crashing app, null for the system server
11450     * @param crashInfo describing the exception
11451     */
11452    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11453        ProcessRecord r = findAppProcess(app, "Crash");
11454        final String processName = app == null ? "system_server"
11455                : (r == null ? "unknown" : r.processName);
11456
11457        handleApplicationCrashInner("crash", r, processName, crashInfo);
11458    }
11459
11460    /* Native crash reporting uses this inner version because it needs to be somewhat
11461     * decoupled from the AM-managed cleanup lifecycle
11462     */
11463    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11464            ApplicationErrorReport.CrashInfo crashInfo) {
11465        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11466                UserHandle.getUserId(Binder.getCallingUid()), processName,
11467                r == null ? -1 : r.info.flags,
11468                crashInfo.exceptionClassName,
11469                crashInfo.exceptionMessage,
11470                crashInfo.throwFileName,
11471                crashInfo.throwLineNumber);
11472
11473        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11474
11475        crashApplication(r, crashInfo);
11476    }
11477
11478    public void handleApplicationStrictModeViolation(
11479            IBinder app,
11480            int violationMask,
11481            StrictMode.ViolationInfo info) {
11482        ProcessRecord r = findAppProcess(app, "StrictMode");
11483        if (r == null) {
11484            return;
11485        }
11486
11487        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11488            Integer stackFingerprint = info.hashCode();
11489            boolean logIt = true;
11490            synchronized (mAlreadyLoggedViolatedStacks) {
11491                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11492                    logIt = false;
11493                    // TODO: sub-sample into EventLog for these, with
11494                    // the info.durationMillis?  Then we'd get
11495                    // the relative pain numbers, without logging all
11496                    // the stack traces repeatedly.  We'd want to do
11497                    // likewise in the client code, which also does
11498                    // dup suppression, before the Binder call.
11499                } else {
11500                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11501                        mAlreadyLoggedViolatedStacks.clear();
11502                    }
11503                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11504                }
11505            }
11506            if (logIt) {
11507                logStrictModeViolationToDropBox(r, info);
11508            }
11509        }
11510
11511        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11512            AppErrorResult result = new AppErrorResult();
11513            synchronized (this) {
11514                final long origId = Binder.clearCallingIdentity();
11515
11516                Message msg = Message.obtain();
11517                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11518                HashMap<String, Object> data = new HashMap<String, Object>();
11519                data.put("result", result);
11520                data.put("app", r);
11521                data.put("violationMask", violationMask);
11522                data.put("info", info);
11523                msg.obj = data;
11524                mHandler.sendMessage(msg);
11525
11526                Binder.restoreCallingIdentity(origId);
11527            }
11528            int res = result.get();
11529            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11530        }
11531    }
11532
11533    // Depending on the policy in effect, there could be a bunch of
11534    // these in quick succession so we try to batch these together to
11535    // minimize disk writes, number of dropbox entries, and maximize
11536    // compression, by having more fewer, larger records.
11537    private void logStrictModeViolationToDropBox(
11538            ProcessRecord process,
11539            StrictMode.ViolationInfo info) {
11540        if (info == null) {
11541            return;
11542        }
11543        final boolean isSystemApp = process == null ||
11544                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11545                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11546        final String processName = process == null ? "unknown" : process.processName;
11547        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11548        final DropBoxManager dbox = (DropBoxManager)
11549                mContext.getSystemService(Context.DROPBOX_SERVICE);
11550
11551        // Exit early if the dropbox isn't configured to accept this report type.
11552        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11553
11554        boolean bufferWasEmpty;
11555        boolean needsFlush;
11556        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11557        synchronized (sb) {
11558            bufferWasEmpty = sb.length() == 0;
11559            appendDropBoxProcessHeaders(process, processName, sb);
11560            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11561            sb.append("System-App: ").append(isSystemApp).append("\n");
11562            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11563            if (info.violationNumThisLoop != 0) {
11564                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11565            }
11566            if (info.numAnimationsRunning != 0) {
11567                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11568            }
11569            if (info.broadcastIntentAction != null) {
11570                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11571            }
11572            if (info.durationMillis != -1) {
11573                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11574            }
11575            if (info.numInstances != -1) {
11576                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11577            }
11578            if (info.tags != null) {
11579                for (String tag : info.tags) {
11580                    sb.append("Span-Tag: ").append(tag).append("\n");
11581                }
11582            }
11583            sb.append("\n");
11584            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11585                sb.append(info.crashInfo.stackTrace);
11586            }
11587            sb.append("\n");
11588
11589            // Only buffer up to ~64k.  Various logging bits truncate
11590            // things at 128k.
11591            needsFlush = (sb.length() > 64 * 1024);
11592        }
11593
11594        // Flush immediately if the buffer's grown too large, or this
11595        // is a non-system app.  Non-system apps are isolated with a
11596        // different tag & policy and not batched.
11597        //
11598        // Batching is useful during internal testing with
11599        // StrictMode settings turned up high.  Without batching,
11600        // thousands of separate files could be created on boot.
11601        if (!isSystemApp || needsFlush) {
11602            new Thread("Error dump: " + dropboxTag) {
11603                @Override
11604                public void run() {
11605                    String report;
11606                    synchronized (sb) {
11607                        report = sb.toString();
11608                        sb.delete(0, sb.length());
11609                        sb.trimToSize();
11610                    }
11611                    if (report.length() != 0) {
11612                        dbox.addText(dropboxTag, report);
11613                    }
11614                }
11615            }.start();
11616            return;
11617        }
11618
11619        // System app batching:
11620        if (!bufferWasEmpty) {
11621            // An existing dropbox-writing thread is outstanding, so
11622            // we don't need to start it up.  The existing thread will
11623            // catch the buffer appends we just did.
11624            return;
11625        }
11626
11627        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11628        // (After this point, we shouldn't access AMS internal data structures.)
11629        new Thread("Error dump: " + dropboxTag) {
11630            @Override
11631            public void run() {
11632                // 5 second sleep to let stacks arrive and be batched together
11633                try {
11634                    Thread.sleep(5000);  // 5 seconds
11635                } catch (InterruptedException e) {}
11636
11637                String errorReport;
11638                synchronized (mStrictModeBuffer) {
11639                    errorReport = mStrictModeBuffer.toString();
11640                    if (errorReport.length() == 0) {
11641                        return;
11642                    }
11643                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11644                    mStrictModeBuffer.trimToSize();
11645                }
11646                dbox.addText(dropboxTag, errorReport);
11647            }
11648        }.start();
11649    }
11650
11651    /**
11652     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11653     * @param app object of the crashing app, null for the system server
11654     * @param tag reported by the caller
11655     * @param system whether this wtf is coming from the system
11656     * @param crashInfo describing the context of the error
11657     * @return true if the process should exit immediately (WTF is fatal)
11658     */
11659    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11660            final ApplicationErrorReport.CrashInfo crashInfo) {
11661        final ProcessRecord r = findAppProcess(app, "WTF");
11662        final String processName = app == null ? "system_server"
11663                : (r == null ? "unknown" : r.processName);
11664
11665        EventLog.writeEvent(EventLogTags.AM_WTF,
11666                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11667                processName,
11668                r == null ? -1 : r.info.flags,
11669                tag, crashInfo.exceptionMessage);
11670
11671        if (system) {
11672            // If this is coming from the system, we could very well have low-level
11673            // system locks held, so we want to do this all asynchronously.  And we
11674            // never want this to become fatal, so there is that too.
11675            mHandler.post(new Runnable() {
11676                @Override public void run() {
11677                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11678                            crashInfo);
11679                }
11680            });
11681            return false;
11682        }
11683
11684        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11685
11686        if (r != null && r.pid != Process.myPid() &&
11687                Settings.Global.getInt(mContext.getContentResolver(),
11688                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11689            crashApplication(r, crashInfo);
11690            return true;
11691        } else {
11692            return false;
11693        }
11694    }
11695
11696    /**
11697     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11698     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11699     */
11700    private ProcessRecord findAppProcess(IBinder app, String reason) {
11701        if (app == null) {
11702            return null;
11703        }
11704
11705        synchronized (this) {
11706            final int NP = mProcessNames.getMap().size();
11707            for (int ip=0; ip<NP; ip++) {
11708                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11709                final int NA = apps.size();
11710                for (int ia=0; ia<NA; ia++) {
11711                    ProcessRecord p = apps.valueAt(ia);
11712                    if (p.thread != null && p.thread.asBinder() == app) {
11713                        return p;
11714                    }
11715                }
11716            }
11717
11718            Slog.w(TAG, "Can't find mystery application for " + reason
11719                    + " from pid=" + Binder.getCallingPid()
11720                    + " uid=" + Binder.getCallingUid() + ": " + app);
11721            return null;
11722        }
11723    }
11724
11725    /**
11726     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11727     * to append various headers to the dropbox log text.
11728     */
11729    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11730            StringBuilder sb) {
11731        // Watchdog thread ends up invoking this function (with
11732        // a null ProcessRecord) to add the stack file to dropbox.
11733        // Do not acquire a lock on this (am) in such cases, as it
11734        // could cause a potential deadlock, if and when watchdog
11735        // is invoked due to unavailability of lock on am and it
11736        // would prevent watchdog from killing system_server.
11737        if (process == null) {
11738            sb.append("Process: ").append(processName).append("\n");
11739            return;
11740        }
11741        // Note: ProcessRecord 'process' is guarded by the service
11742        // instance.  (notably process.pkgList, which could otherwise change
11743        // concurrently during execution of this method)
11744        synchronized (this) {
11745            sb.append("Process: ").append(processName).append("\n");
11746            int flags = process.info.flags;
11747            IPackageManager pm = AppGlobals.getPackageManager();
11748            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11749            for (int ip=0; ip<process.pkgList.size(); ip++) {
11750                String pkg = process.pkgList.keyAt(ip);
11751                sb.append("Package: ").append(pkg);
11752                try {
11753                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11754                    if (pi != null) {
11755                        sb.append(" v").append(pi.versionCode);
11756                        if (pi.versionName != null) {
11757                            sb.append(" (").append(pi.versionName).append(")");
11758                        }
11759                    }
11760                } catch (RemoteException e) {
11761                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11762                }
11763                sb.append("\n");
11764            }
11765        }
11766    }
11767
11768    private static String processClass(ProcessRecord process) {
11769        if (process == null || process.pid == MY_PID) {
11770            return "system_server";
11771        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11772            return "system_app";
11773        } else {
11774            return "data_app";
11775        }
11776    }
11777
11778    /**
11779     * Write a description of an error (crash, WTF, ANR) to the drop box.
11780     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11781     * @param process which caused the error, null means the system server
11782     * @param activity which triggered the error, null if unknown
11783     * @param parent activity related to the error, null if unknown
11784     * @param subject line related to the error, null if absent
11785     * @param report in long form describing the error, null if absent
11786     * @param logFile to include in the report, null if none
11787     * @param crashInfo giving an application stack trace, null if absent
11788     */
11789    public void addErrorToDropBox(String eventType,
11790            ProcessRecord process, String processName, ActivityRecord activity,
11791            ActivityRecord parent, String subject,
11792            final String report, final File logFile,
11793            final ApplicationErrorReport.CrashInfo crashInfo) {
11794        // NOTE -- this must never acquire the ActivityManagerService lock,
11795        // otherwise the watchdog may be prevented from resetting the system.
11796
11797        final String dropboxTag = processClass(process) + "_" + eventType;
11798        final DropBoxManager dbox = (DropBoxManager)
11799                mContext.getSystemService(Context.DROPBOX_SERVICE);
11800
11801        // Exit early if the dropbox isn't configured to accept this report type.
11802        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11803
11804        final StringBuilder sb = new StringBuilder(1024);
11805        appendDropBoxProcessHeaders(process, processName, sb);
11806        if (activity != null) {
11807            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11808        }
11809        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11810            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11811        }
11812        if (parent != null && parent != activity) {
11813            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11814        }
11815        if (subject != null) {
11816            sb.append("Subject: ").append(subject).append("\n");
11817        }
11818        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11819        if (Debug.isDebuggerConnected()) {
11820            sb.append("Debugger: Connected\n");
11821        }
11822        sb.append("\n");
11823
11824        // Do the rest in a worker thread to avoid blocking the caller on I/O
11825        // (After this point, we shouldn't access AMS internal data structures.)
11826        Thread worker = new Thread("Error dump: " + dropboxTag) {
11827            @Override
11828            public void run() {
11829                if (report != null) {
11830                    sb.append(report);
11831                }
11832                if (logFile != null) {
11833                    try {
11834                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11835                                    "\n\n[[TRUNCATED]]"));
11836                    } catch (IOException e) {
11837                        Slog.e(TAG, "Error reading " + logFile, e);
11838                    }
11839                }
11840                if (crashInfo != null && crashInfo.stackTrace != null) {
11841                    sb.append(crashInfo.stackTrace);
11842                }
11843
11844                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11845                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11846                if (lines > 0) {
11847                    sb.append("\n");
11848
11849                    // Merge several logcat streams, and take the last N lines
11850                    InputStreamReader input = null;
11851                    try {
11852                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11853                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11854                                "-b", "crash",
11855                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11856
11857                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11858                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11859                        input = new InputStreamReader(logcat.getInputStream());
11860
11861                        int num;
11862                        char[] buf = new char[8192];
11863                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11864                    } catch (IOException e) {
11865                        Slog.e(TAG, "Error running logcat", e);
11866                    } finally {
11867                        if (input != null) try { input.close(); } catch (IOException e) {}
11868                    }
11869                }
11870
11871                dbox.addText(dropboxTag, sb.toString());
11872            }
11873        };
11874
11875        if (process == null) {
11876            // If process is null, we are being called from some internal code
11877            // and may be about to die -- run this synchronously.
11878            worker.run();
11879        } else {
11880            worker.start();
11881        }
11882    }
11883
11884    /**
11885     * Bring up the "unexpected error" dialog box for a crashing app.
11886     * Deal with edge cases (intercepts from instrumented applications,
11887     * ActivityController, error intent receivers, that sort of thing).
11888     * @param r the application crashing
11889     * @param crashInfo describing the failure
11890     */
11891    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11892        long timeMillis = System.currentTimeMillis();
11893        String shortMsg = crashInfo.exceptionClassName;
11894        String longMsg = crashInfo.exceptionMessage;
11895        String stackTrace = crashInfo.stackTrace;
11896        if (shortMsg != null && longMsg != null) {
11897            longMsg = shortMsg + ": " + longMsg;
11898        } else if (shortMsg != null) {
11899            longMsg = shortMsg;
11900        }
11901
11902        AppErrorResult result = new AppErrorResult();
11903        synchronized (this) {
11904            if (mController != null) {
11905                try {
11906                    String name = r != null ? r.processName : null;
11907                    int pid = r != null ? r.pid : Binder.getCallingPid();
11908                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11909                    if (!mController.appCrashed(name, pid,
11910                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11911                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11912                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11913                            Slog.w(TAG, "Skip killing native crashed app " + name
11914                                    + "(" + pid + ") during testing");
11915                        } else {
11916                            Slog.w(TAG, "Force-killing crashed app " + name
11917                                    + " at watcher's request");
11918                            if (r != null) {
11919                                r.kill("crash", true);
11920                            } else {
11921                                // Huh.
11922                                Process.killProcess(pid);
11923                                Process.killProcessGroup(uid, pid);
11924                            }
11925                        }
11926                        return;
11927                    }
11928                } catch (RemoteException e) {
11929                    mController = null;
11930                    Watchdog.getInstance().setActivityController(null);
11931                }
11932            }
11933
11934            final long origId = Binder.clearCallingIdentity();
11935
11936            // If this process is running instrumentation, finish it.
11937            if (r != null && r.instrumentationClass != null) {
11938                Slog.w(TAG, "Error in app " + r.processName
11939                      + " running instrumentation " + r.instrumentationClass + ":");
11940                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11941                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11942                Bundle info = new Bundle();
11943                info.putString("shortMsg", shortMsg);
11944                info.putString("longMsg", longMsg);
11945                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11946                Binder.restoreCallingIdentity(origId);
11947                return;
11948            }
11949
11950            // If we can't identify the process or it's already exceeded its crash quota,
11951            // quit right away without showing a crash dialog.
11952            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11953                Binder.restoreCallingIdentity(origId);
11954                return;
11955            }
11956
11957            Message msg = Message.obtain();
11958            msg.what = SHOW_ERROR_MSG;
11959            HashMap data = new HashMap();
11960            data.put("result", result);
11961            data.put("app", r);
11962            msg.obj = data;
11963            mHandler.sendMessage(msg);
11964
11965            Binder.restoreCallingIdentity(origId);
11966        }
11967
11968        int res = result.get();
11969
11970        Intent appErrorIntent = null;
11971        synchronized (this) {
11972            if (r != null && !r.isolated) {
11973                // XXX Can't keep track of crash time for isolated processes,
11974                // since they don't have a persistent identity.
11975                mProcessCrashTimes.put(r.info.processName, r.uid,
11976                        SystemClock.uptimeMillis());
11977            }
11978            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11979                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11980            }
11981        }
11982
11983        if (appErrorIntent != null) {
11984            try {
11985                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11986            } catch (ActivityNotFoundException e) {
11987                Slog.w(TAG, "bug report receiver dissappeared", e);
11988            }
11989        }
11990    }
11991
11992    Intent createAppErrorIntentLocked(ProcessRecord r,
11993            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11994        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11995        if (report == null) {
11996            return null;
11997        }
11998        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11999        result.setComponent(r.errorReportReceiver);
12000        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12001        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12002        return result;
12003    }
12004
12005    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12006            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12007        if (r.errorReportReceiver == null) {
12008            return null;
12009        }
12010
12011        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12012            return null;
12013        }
12014
12015        ApplicationErrorReport report = new ApplicationErrorReport();
12016        report.packageName = r.info.packageName;
12017        report.installerPackageName = r.errorReportReceiver.getPackageName();
12018        report.processName = r.processName;
12019        report.time = timeMillis;
12020        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12021
12022        if (r.crashing || r.forceCrashReport) {
12023            report.type = ApplicationErrorReport.TYPE_CRASH;
12024            report.crashInfo = crashInfo;
12025        } else if (r.notResponding) {
12026            report.type = ApplicationErrorReport.TYPE_ANR;
12027            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12028
12029            report.anrInfo.activity = r.notRespondingReport.tag;
12030            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12031            report.anrInfo.info = r.notRespondingReport.longMsg;
12032        }
12033
12034        return report;
12035    }
12036
12037    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12038        enforceNotIsolatedCaller("getProcessesInErrorState");
12039        // assume our apps are happy - lazy create the list
12040        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12041
12042        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12043                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12044        int userId = UserHandle.getUserId(Binder.getCallingUid());
12045
12046        synchronized (this) {
12047
12048            // iterate across all processes
12049            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12050                ProcessRecord app = mLruProcesses.get(i);
12051                if (!allUsers && app.userId != userId) {
12052                    continue;
12053                }
12054                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12055                    // This one's in trouble, so we'll generate a report for it
12056                    // crashes are higher priority (in case there's a crash *and* an anr)
12057                    ActivityManager.ProcessErrorStateInfo report = null;
12058                    if (app.crashing) {
12059                        report = app.crashingReport;
12060                    } else if (app.notResponding) {
12061                        report = app.notRespondingReport;
12062                    }
12063
12064                    if (report != null) {
12065                        if (errList == null) {
12066                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12067                        }
12068                        errList.add(report);
12069                    } else {
12070                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12071                                " crashing = " + app.crashing +
12072                                " notResponding = " + app.notResponding);
12073                    }
12074                }
12075            }
12076        }
12077
12078        return errList;
12079    }
12080
12081    static int procStateToImportance(int procState, int memAdj,
12082            ActivityManager.RunningAppProcessInfo currApp) {
12083        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12084        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12085            currApp.lru = memAdj;
12086        } else {
12087            currApp.lru = 0;
12088        }
12089        return imp;
12090    }
12091
12092    private void fillInProcMemInfo(ProcessRecord app,
12093            ActivityManager.RunningAppProcessInfo outInfo) {
12094        outInfo.pid = app.pid;
12095        outInfo.uid = app.info.uid;
12096        if (mHeavyWeightProcess == app) {
12097            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12098        }
12099        if (app.persistent) {
12100            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12101        }
12102        if (app.activities.size() > 0) {
12103            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12104        }
12105        outInfo.lastTrimLevel = app.trimMemoryLevel;
12106        int adj = app.curAdj;
12107        int procState = app.curProcState;
12108        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12109        outInfo.importanceReasonCode = app.adjTypeCode;
12110        outInfo.processState = app.curProcState;
12111    }
12112
12113    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12114        enforceNotIsolatedCaller("getRunningAppProcesses");
12115        // Lazy instantiation of list
12116        List<ActivityManager.RunningAppProcessInfo> runList = null;
12117        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12118                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12119        int userId = UserHandle.getUserId(Binder.getCallingUid());
12120        synchronized (this) {
12121            // Iterate across all processes
12122            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12123                ProcessRecord app = mLruProcesses.get(i);
12124                if (!allUsers && app.userId != userId) {
12125                    continue;
12126                }
12127                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12128                    // Generate process state info for running application
12129                    ActivityManager.RunningAppProcessInfo currApp =
12130                        new ActivityManager.RunningAppProcessInfo(app.processName,
12131                                app.pid, app.getPackageList());
12132                    fillInProcMemInfo(app, currApp);
12133                    if (app.adjSource instanceof ProcessRecord) {
12134                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12135                        currApp.importanceReasonImportance =
12136                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12137                                        app.adjSourceProcState);
12138                    } else if (app.adjSource instanceof ActivityRecord) {
12139                        ActivityRecord r = (ActivityRecord)app.adjSource;
12140                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12141                    }
12142                    if (app.adjTarget instanceof ComponentName) {
12143                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12144                    }
12145                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12146                    //        + " lru=" + currApp.lru);
12147                    if (runList == null) {
12148                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12149                    }
12150                    runList.add(currApp);
12151                }
12152            }
12153        }
12154        return runList;
12155    }
12156
12157    public List<ApplicationInfo> getRunningExternalApplications() {
12158        enforceNotIsolatedCaller("getRunningExternalApplications");
12159        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12160        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12161        if (runningApps != null && runningApps.size() > 0) {
12162            Set<String> extList = new HashSet<String>();
12163            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12164                if (app.pkgList != null) {
12165                    for (String pkg : app.pkgList) {
12166                        extList.add(pkg);
12167                    }
12168                }
12169            }
12170            IPackageManager pm = AppGlobals.getPackageManager();
12171            for (String pkg : extList) {
12172                try {
12173                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12174                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12175                        retList.add(info);
12176                    }
12177                } catch (RemoteException e) {
12178                }
12179            }
12180        }
12181        return retList;
12182    }
12183
12184    @Override
12185    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12186        enforceNotIsolatedCaller("getMyMemoryState");
12187        synchronized (this) {
12188            ProcessRecord proc;
12189            synchronized (mPidsSelfLocked) {
12190                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12191            }
12192            fillInProcMemInfo(proc, outInfo);
12193        }
12194    }
12195
12196    @Override
12197    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12198        if (checkCallingPermission(android.Manifest.permission.DUMP)
12199                != PackageManager.PERMISSION_GRANTED) {
12200            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12201                    + Binder.getCallingPid()
12202                    + ", uid=" + Binder.getCallingUid()
12203                    + " without permission "
12204                    + android.Manifest.permission.DUMP);
12205            return;
12206        }
12207
12208        boolean dumpAll = false;
12209        boolean dumpClient = false;
12210        String dumpPackage = null;
12211
12212        int opti = 0;
12213        while (opti < args.length) {
12214            String opt = args[opti];
12215            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12216                break;
12217            }
12218            opti++;
12219            if ("-a".equals(opt)) {
12220                dumpAll = true;
12221            } else if ("-c".equals(opt)) {
12222                dumpClient = true;
12223            } else if ("-h".equals(opt)) {
12224                pw.println("Activity manager dump options:");
12225                pw.println("  [-a] [-c] [-h] [cmd] ...");
12226                pw.println("  cmd may be one of:");
12227                pw.println("    a[ctivities]: activity stack state");
12228                pw.println("    r[recents]: recent activities state");
12229                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12230                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12231                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12232                pw.println("    o[om]: out of memory management");
12233                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12234                pw.println("    provider [COMP_SPEC]: provider client-side state");
12235                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12236                pw.println("    service [COMP_SPEC]: service client-side state");
12237                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12238                pw.println("    all: dump all activities");
12239                pw.println("    top: dump the top activity");
12240                pw.println("    write: write all pending state to storage");
12241                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12242                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12243                pw.println("    a partial substring in a component name, a");
12244                pw.println("    hex object identifier.");
12245                pw.println("  -a: include all available server state.");
12246                pw.println("  -c: include client state.");
12247                return;
12248            } else {
12249                pw.println("Unknown argument: " + opt + "; use -h for help");
12250            }
12251        }
12252
12253        long origId = Binder.clearCallingIdentity();
12254        boolean more = false;
12255        // Is the caller requesting to dump a particular piece of data?
12256        if (opti < args.length) {
12257            String cmd = args[opti];
12258            opti++;
12259            if ("activities".equals(cmd) || "a".equals(cmd)) {
12260                synchronized (this) {
12261                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12262                }
12263            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12264                synchronized (this) {
12265                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12266                }
12267            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12268                String[] newArgs;
12269                String name;
12270                if (opti >= args.length) {
12271                    name = null;
12272                    newArgs = EMPTY_STRING_ARRAY;
12273                } else {
12274                    name = args[opti];
12275                    opti++;
12276                    newArgs = new String[args.length - opti];
12277                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12278                            args.length - opti);
12279                }
12280                synchronized (this) {
12281                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12282                }
12283            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12284                String[] newArgs;
12285                String name;
12286                if (opti >= args.length) {
12287                    name = null;
12288                    newArgs = EMPTY_STRING_ARRAY;
12289                } else {
12290                    name = args[opti];
12291                    opti++;
12292                    newArgs = new String[args.length - opti];
12293                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12294                            args.length - opti);
12295                }
12296                synchronized (this) {
12297                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12298                }
12299            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12300                String[] newArgs;
12301                String name;
12302                if (opti >= args.length) {
12303                    name = null;
12304                    newArgs = EMPTY_STRING_ARRAY;
12305                } else {
12306                    name = args[opti];
12307                    opti++;
12308                    newArgs = new String[args.length - opti];
12309                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12310                            args.length - opti);
12311                }
12312                synchronized (this) {
12313                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12314                }
12315            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12316                synchronized (this) {
12317                    dumpOomLocked(fd, pw, args, opti, true);
12318                }
12319            } else if ("provider".equals(cmd)) {
12320                String[] newArgs;
12321                String name;
12322                if (opti >= args.length) {
12323                    name = null;
12324                    newArgs = EMPTY_STRING_ARRAY;
12325                } else {
12326                    name = args[opti];
12327                    opti++;
12328                    newArgs = new String[args.length - opti];
12329                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12330                }
12331                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12332                    pw.println("No providers match: " + name);
12333                    pw.println("Use -h for help.");
12334                }
12335            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12336                synchronized (this) {
12337                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12338                }
12339            } else if ("service".equals(cmd)) {
12340                String[] newArgs;
12341                String name;
12342                if (opti >= args.length) {
12343                    name = null;
12344                    newArgs = EMPTY_STRING_ARRAY;
12345                } else {
12346                    name = args[opti];
12347                    opti++;
12348                    newArgs = new String[args.length - opti];
12349                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12350                            args.length - opti);
12351                }
12352                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12353                    pw.println("No services match: " + name);
12354                    pw.println("Use -h for help.");
12355                }
12356            } else if ("package".equals(cmd)) {
12357                String[] newArgs;
12358                if (opti >= args.length) {
12359                    pw.println("package: no package name specified");
12360                    pw.println("Use -h for help.");
12361                } else {
12362                    dumpPackage = args[opti];
12363                    opti++;
12364                    newArgs = new String[args.length - opti];
12365                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12366                            args.length - opti);
12367                    args = newArgs;
12368                    opti = 0;
12369                    more = true;
12370                }
12371            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12372                synchronized (this) {
12373                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12374                }
12375            } else if ("write".equals(cmd)) {
12376                mTaskPersister.flush();
12377                pw.println("All tasks persisted.");
12378                return;
12379            } else {
12380                // Dumping a single activity?
12381                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12382                    pw.println("Bad activity command, or no activities match: " + cmd);
12383                    pw.println("Use -h for help.");
12384                }
12385            }
12386            if (!more) {
12387                Binder.restoreCallingIdentity(origId);
12388                return;
12389            }
12390        }
12391
12392        // No piece of data specified, dump everything.
12393        synchronized (this) {
12394            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12395            pw.println();
12396            if (dumpAll) {
12397                pw.println("-------------------------------------------------------------------------------");
12398            }
12399            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12400            pw.println();
12401            if (dumpAll) {
12402                pw.println("-------------------------------------------------------------------------------");
12403            }
12404            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12405            pw.println();
12406            if (dumpAll) {
12407                pw.println("-------------------------------------------------------------------------------");
12408            }
12409            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12410            pw.println();
12411            if (dumpAll) {
12412                pw.println("-------------------------------------------------------------------------------");
12413            }
12414            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12415            pw.println();
12416            if (dumpAll) {
12417                pw.println("-------------------------------------------------------------------------------");
12418            }
12419            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12420            pw.println();
12421            if (dumpAll) {
12422                pw.println("-------------------------------------------------------------------------------");
12423            }
12424            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12425        }
12426        Binder.restoreCallingIdentity(origId);
12427    }
12428
12429    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12430            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12431        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12432
12433        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12434                dumpPackage);
12435        boolean needSep = printedAnything;
12436
12437        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12438                dumpPackage, needSep, "  mFocusedActivity: ");
12439        if (printed) {
12440            printedAnything = true;
12441            needSep = false;
12442        }
12443
12444        if (dumpPackage == null) {
12445            if (needSep) {
12446                pw.println();
12447            }
12448            needSep = true;
12449            printedAnything = true;
12450            mStackSupervisor.dump(pw, "  ");
12451        }
12452
12453        if (!printedAnything) {
12454            pw.println("  (nothing)");
12455        }
12456    }
12457
12458    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12459            int opti, boolean dumpAll, String dumpPackage) {
12460        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12461
12462        boolean printedAnything = false;
12463
12464        if (mRecentTasks.size() > 0) {
12465            boolean printedHeader = false;
12466
12467            final int N = mRecentTasks.size();
12468            for (int i=0; i<N; i++) {
12469                TaskRecord tr = mRecentTasks.get(i);
12470                if (dumpPackage != null) {
12471                    if (tr.realActivity == null ||
12472                            !dumpPackage.equals(tr.realActivity)) {
12473                        continue;
12474                    }
12475                }
12476                if (!printedHeader) {
12477                    pw.println("  Recent tasks:");
12478                    printedHeader = true;
12479                    printedAnything = true;
12480                }
12481                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12482                        pw.println(tr);
12483                if (dumpAll) {
12484                    mRecentTasks.get(i).dump(pw, "    ");
12485                }
12486            }
12487        }
12488
12489        if (!printedAnything) {
12490            pw.println("  (nothing)");
12491        }
12492    }
12493
12494    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12495            int opti, boolean dumpAll, String dumpPackage) {
12496        boolean needSep = false;
12497        boolean printedAnything = false;
12498        int numPers = 0;
12499
12500        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12501
12502        if (dumpAll) {
12503            final int NP = mProcessNames.getMap().size();
12504            for (int ip=0; ip<NP; ip++) {
12505                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12506                final int NA = procs.size();
12507                for (int ia=0; ia<NA; ia++) {
12508                    ProcessRecord r = procs.valueAt(ia);
12509                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12510                        continue;
12511                    }
12512                    if (!needSep) {
12513                        pw.println("  All known processes:");
12514                        needSep = true;
12515                        printedAnything = true;
12516                    }
12517                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12518                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12519                        pw.print(" "); pw.println(r);
12520                    r.dump(pw, "    ");
12521                    if (r.persistent) {
12522                        numPers++;
12523                    }
12524                }
12525            }
12526        }
12527
12528        if (mIsolatedProcesses.size() > 0) {
12529            boolean printed = false;
12530            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12531                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12532                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12533                    continue;
12534                }
12535                if (!printed) {
12536                    if (needSep) {
12537                        pw.println();
12538                    }
12539                    pw.println("  Isolated process list (sorted by uid):");
12540                    printedAnything = true;
12541                    printed = true;
12542                    needSep = true;
12543                }
12544                pw.println(String.format("%sIsolated #%2d: %s",
12545                        "    ", i, r.toString()));
12546            }
12547        }
12548
12549        if (mLruProcesses.size() > 0) {
12550            if (needSep) {
12551                pw.println();
12552            }
12553            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12554                    pw.print(" total, non-act at ");
12555                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12556                    pw.print(", non-svc at ");
12557                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12558                    pw.println("):");
12559            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12560            needSep = true;
12561            printedAnything = true;
12562        }
12563
12564        if (dumpAll || dumpPackage != null) {
12565            synchronized (mPidsSelfLocked) {
12566                boolean printed = false;
12567                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12568                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12569                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12570                        continue;
12571                    }
12572                    if (!printed) {
12573                        if (needSep) pw.println();
12574                        needSep = true;
12575                        pw.println("  PID mappings:");
12576                        printed = true;
12577                        printedAnything = true;
12578                    }
12579                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12580                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12581                }
12582            }
12583        }
12584
12585        if (mForegroundProcesses.size() > 0) {
12586            synchronized (mPidsSelfLocked) {
12587                boolean printed = false;
12588                for (int i=0; i<mForegroundProcesses.size(); i++) {
12589                    ProcessRecord r = mPidsSelfLocked.get(
12590                            mForegroundProcesses.valueAt(i).pid);
12591                    if (dumpPackage != null && (r == null
12592                            || !r.pkgList.containsKey(dumpPackage))) {
12593                        continue;
12594                    }
12595                    if (!printed) {
12596                        if (needSep) pw.println();
12597                        needSep = true;
12598                        pw.println("  Foreground Processes:");
12599                        printed = true;
12600                        printedAnything = true;
12601                    }
12602                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12603                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12604                }
12605            }
12606        }
12607
12608        if (mPersistentStartingProcesses.size() > 0) {
12609            if (needSep) pw.println();
12610            needSep = true;
12611            printedAnything = true;
12612            pw.println("  Persisent processes that are starting:");
12613            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12614                    "Starting Norm", "Restarting PERS", dumpPackage);
12615        }
12616
12617        if (mRemovedProcesses.size() > 0) {
12618            if (needSep) pw.println();
12619            needSep = true;
12620            printedAnything = true;
12621            pw.println("  Processes that are being removed:");
12622            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12623                    "Removed Norm", "Removed PERS", dumpPackage);
12624        }
12625
12626        if (mProcessesOnHold.size() > 0) {
12627            if (needSep) pw.println();
12628            needSep = true;
12629            printedAnything = true;
12630            pw.println("  Processes that are on old until the system is ready:");
12631            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12632                    "OnHold Norm", "OnHold PERS", dumpPackage);
12633        }
12634
12635        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12636
12637        if (mProcessCrashTimes.getMap().size() > 0) {
12638            boolean printed = false;
12639            long now = SystemClock.uptimeMillis();
12640            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12641            final int NP = pmap.size();
12642            for (int ip=0; ip<NP; ip++) {
12643                String pname = pmap.keyAt(ip);
12644                SparseArray<Long> uids = pmap.valueAt(ip);
12645                final int N = uids.size();
12646                for (int i=0; i<N; i++) {
12647                    int puid = uids.keyAt(i);
12648                    ProcessRecord r = mProcessNames.get(pname, puid);
12649                    if (dumpPackage != null && (r == null
12650                            || !r.pkgList.containsKey(dumpPackage))) {
12651                        continue;
12652                    }
12653                    if (!printed) {
12654                        if (needSep) pw.println();
12655                        needSep = true;
12656                        pw.println("  Time since processes crashed:");
12657                        printed = true;
12658                        printedAnything = true;
12659                    }
12660                    pw.print("    Process "); pw.print(pname);
12661                            pw.print(" uid "); pw.print(puid);
12662                            pw.print(": last crashed ");
12663                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12664                            pw.println(" ago");
12665                }
12666            }
12667        }
12668
12669        if (mBadProcesses.getMap().size() > 0) {
12670            boolean printed = false;
12671            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12672            final int NP = pmap.size();
12673            for (int ip=0; ip<NP; ip++) {
12674                String pname = pmap.keyAt(ip);
12675                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12676                final int N = uids.size();
12677                for (int i=0; i<N; i++) {
12678                    int puid = uids.keyAt(i);
12679                    ProcessRecord r = mProcessNames.get(pname, puid);
12680                    if (dumpPackage != null && (r == null
12681                            || !r.pkgList.containsKey(dumpPackage))) {
12682                        continue;
12683                    }
12684                    if (!printed) {
12685                        if (needSep) pw.println();
12686                        needSep = true;
12687                        pw.println("  Bad processes:");
12688                        printedAnything = true;
12689                    }
12690                    BadProcessInfo info = uids.valueAt(i);
12691                    pw.print("    Bad process "); pw.print(pname);
12692                            pw.print(" uid "); pw.print(puid);
12693                            pw.print(": crashed at time "); pw.println(info.time);
12694                    if (info.shortMsg != null) {
12695                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12696                    }
12697                    if (info.longMsg != null) {
12698                        pw.print("      Long msg: "); pw.println(info.longMsg);
12699                    }
12700                    if (info.stack != null) {
12701                        pw.println("      Stack:");
12702                        int lastPos = 0;
12703                        for (int pos=0; pos<info.stack.length(); pos++) {
12704                            if (info.stack.charAt(pos) == '\n') {
12705                                pw.print("        ");
12706                                pw.write(info.stack, lastPos, pos-lastPos);
12707                                pw.println();
12708                                lastPos = pos+1;
12709                            }
12710                        }
12711                        if (lastPos < info.stack.length()) {
12712                            pw.print("        ");
12713                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12714                            pw.println();
12715                        }
12716                    }
12717                }
12718            }
12719        }
12720
12721        if (dumpPackage == null) {
12722            pw.println();
12723            needSep = false;
12724            pw.println("  mStartedUsers:");
12725            for (int i=0; i<mStartedUsers.size(); i++) {
12726                UserStartedState uss = mStartedUsers.valueAt(i);
12727                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12728                        pw.print(": "); uss.dump("", pw);
12729            }
12730            pw.print("  mStartedUserArray: [");
12731            for (int i=0; i<mStartedUserArray.length; i++) {
12732                if (i > 0) pw.print(", ");
12733                pw.print(mStartedUserArray[i]);
12734            }
12735            pw.println("]");
12736            pw.print("  mUserLru: [");
12737            for (int i=0; i<mUserLru.size(); i++) {
12738                if (i > 0) pw.print(", ");
12739                pw.print(mUserLru.get(i));
12740            }
12741            pw.println("]");
12742            if (dumpAll) {
12743                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12744            }
12745            synchronized (mUserProfileGroupIdsSelfLocked) {
12746                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12747                    pw.println("  mUserProfileGroupIds:");
12748                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12749                        pw.print("    User #");
12750                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12751                        pw.print(" -> profile #");
12752                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12753                    }
12754                }
12755            }
12756        }
12757        if (mHomeProcess != null && (dumpPackage == null
12758                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12759            if (needSep) {
12760                pw.println();
12761                needSep = false;
12762            }
12763            pw.println("  mHomeProcess: " + mHomeProcess);
12764        }
12765        if (mPreviousProcess != null && (dumpPackage == null
12766                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12767            if (needSep) {
12768                pw.println();
12769                needSep = false;
12770            }
12771            pw.println("  mPreviousProcess: " + mPreviousProcess);
12772        }
12773        if (dumpAll) {
12774            StringBuilder sb = new StringBuilder(128);
12775            sb.append("  mPreviousProcessVisibleTime: ");
12776            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12777            pw.println(sb);
12778        }
12779        if (mHeavyWeightProcess != null && (dumpPackage == null
12780                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12781            if (needSep) {
12782                pw.println();
12783                needSep = false;
12784            }
12785            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12786        }
12787        if (dumpPackage == null) {
12788            pw.println("  mConfiguration: " + mConfiguration);
12789        }
12790        if (dumpAll) {
12791            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12792            if (mCompatModePackages.getPackages().size() > 0) {
12793                boolean printed = false;
12794                for (Map.Entry<String, Integer> entry
12795                        : mCompatModePackages.getPackages().entrySet()) {
12796                    String pkg = entry.getKey();
12797                    int mode = entry.getValue();
12798                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12799                        continue;
12800                    }
12801                    if (!printed) {
12802                        pw.println("  mScreenCompatPackages:");
12803                        printed = true;
12804                    }
12805                    pw.print("    "); pw.print(pkg); pw.print(": ");
12806                            pw.print(mode); pw.println();
12807                }
12808            }
12809        }
12810        if (dumpPackage == null) {
12811            if (mSleeping || mWentToSleep || mLockScreenShown) {
12812                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12813                        + " mLockScreenShown " + mLockScreenShown);
12814            }
12815            if (mShuttingDown || mRunningVoice) {
12816                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12817            }
12818        }
12819        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12820                || mOrigWaitForDebugger) {
12821            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12822                    || dumpPackage.equals(mOrigDebugApp)) {
12823                if (needSep) {
12824                    pw.println();
12825                    needSep = false;
12826                }
12827                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12828                        + " mDebugTransient=" + mDebugTransient
12829                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12830            }
12831        }
12832        if (mOpenGlTraceApp != null) {
12833            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12834                if (needSep) {
12835                    pw.println();
12836                    needSep = false;
12837                }
12838                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12839            }
12840        }
12841        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12842                || mProfileFd != null) {
12843            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12844                if (needSep) {
12845                    pw.println();
12846                    needSep = false;
12847                }
12848                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12849                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12850                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12851                        + mAutoStopProfiler);
12852                pw.println("  mProfileType=" + mProfileType);
12853            }
12854        }
12855        if (dumpPackage == null) {
12856            if (mAlwaysFinishActivities || mController != null) {
12857                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12858                        + " mController=" + mController);
12859            }
12860            if (dumpAll) {
12861                pw.println("  Total persistent processes: " + numPers);
12862                pw.println("  mProcessesReady=" + mProcessesReady
12863                        + " mSystemReady=" + mSystemReady);
12864                pw.println("  mBooting=" + mBooting
12865                        + " mBooted=" + mBooted
12866                        + " mFactoryTest=" + mFactoryTest);
12867                pw.print("  mLastPowerCheckRealtime=");
12868                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12869                        pw.println("");
12870                pw.print("  mLastPowerCheckUptime=");
12871                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12872                        pw.println("");
12873                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12874                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12875                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12876                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12877                        + " (" + mLruProcesses.size() + " total)"
12878                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12879                        + " mNumServiceProcs=" + mNumServiceProcs
12880                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12881                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12882                        + " mLastMemoryLevel" + mLastMemoryLevel
12883                        + " mLastNumProcesses" + mLastNumProcesses);
12884                long now = SystemClock.uptimeMillis();
12885                pw.print("  mLastIdleTime=");
12886                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12887                        pw.print(" mLowRamSinceLastIdle=");
12888                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12889                        pw.println();
12890            }
12891        }
12892
12893        if (!printedAnything) {
12894            pw.println("  (nothing)");
12895        }
12896    }
12897
12898    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12899            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12900        if (mProcessesToGc.size() > 0) {
12901            boolean printed = false;
12902            long now = SystemClock.uptimeMillis();
12903            for (int i=0; i<mProcessesToGc.size(); i++) {
12904                ProcessRecord proc = mProcessesToGc.get(i);
12905                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12906                    continue;
12907                }
12908                if (!printed) {
12909                    if (needSep) pw.println();
12910                    needSep = true;
12911                    pw.println("  Processes that are waiting to GC:");
12912                    printed = true;
12913                }
12914                pw.print("    Process "); pw.println(proc);
12915                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12916                        pw.print(", last gced=");
12917                        pw.print(now-proc.lastRequestedGc);
12918                        pw.print(" ms ago, last lowMem=");
12919                        pw.print(now-proc.lastLowMemory);
12920                        pw.println(" ms ago");
12921
12922            }
12923        }
12924        return needSep;
12925    }
12926
12927    void printOomLevel(PrintWriter pw, String name, int adj) {
12928        pw.print("    ");
12929        if (adj >= 0) {
12930            pw.print(' ');
12931            if (adj < 10) pw.print(' ');
12932        } else {
12933            if (adj > -10) pw.print(' ');
12934        }
12935        pw.print(adj);
12936        pw.print(": ");
12937        pw.print(name);
12938        pw.print(" (");
12939        pw.print(mProcessList.getMemLevel(adj)/1024);
12940        pw.println(" kB)");
12941    }
12942
12943    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12944            int opti, boolean dumpAll) {
12945        boolean needSep = false;
12946
12947        if (mLruProcesses.size() > 0) {
12948            if (needSep) pw.println();
12949            needSep = true;
12950            pw.println("  OOM levels:");
12951            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12952            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12953            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12954            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12955            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12956            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12957            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12958            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12959            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12960            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12961            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12962            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12963            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12964
12965            if (needSep) pw.println();
12966            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12967                    pw.print(" total, non-act at ");
12968                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12969                    pw.print(", non-svc at ");
12970                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12971                    pw.println("):");
12972            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12973            needSep = true;
12974        }
12975
12976        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12977
12978        pw.println();
12979        pw.println("  mHomeProcess: " + mHomeProcess);
12980        pw.println("  mPreviousProcess: " + mPreviousProcess);
12981        if (mHeavyWeightProcess != null) {
12982            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12983        }
12984
12985        return true;
12986    }
12987
12988    /**
12989     * There are three ways to call this:
12990     *  - no provider specified: dump all the providers
12991     *  - a flattened component name that matched an existing provider was specified as the
12992     *    first arg: dump that one provider
12993     *  - the first arg isn't the flattened component name of an existing provider:
12994     *    dump all providers whose component contains the first arg as a substring
12995     */
12996    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12997            int opti, boolean dumpAll) {
12998        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12999    }
13000
13001    static class ItemMatcher {
13002        ArrayList<ComponentName> components;
13003        ArrayList<String> strings;
13004        ArrayList<Integer> objects;
13005        boolean all;
13006
13007        ItemMatcher() {
13008            all = true;
13009        }
13010
13011        void build(String name) {
13012            ComponentName componentName = ComponentName.unflattenFromString(name);
13013            if (componentName != null) {
13014                if (components == null) {
13015                    components = new ArrayList<ComponentName>();
13016                }
13017                components.add(componentName);
13018                all = false;
13019            } else {
13020                int objectId = 0;
13021                // Not a '/' separated full component name; maybe an object ID?
13022                try {
13023                    objectId = Integer.parseInt(name, 16);
13024                    if (objects == null) {
13025                        objects = new ArrayList<Integer>();
13026                    }
13027                    objects.add(objectId);
13028                    all = false;
13029                } catch (RuntimeException e) {
13030                    // Not an integer; just do string match.
13031                    if (strings == null) {
13032                        strings = new ArrayList<String>();
13033                    }
13034                    strings.add(name);
13035                    all = false;
13036                }
13037            }
13038        }
13039
13040        int build(String[] args, int opti) {
13041            for (; opti<args.length; opti++) {
13042                String name = args[opti];
13043                if ("--".equals(name)) {
13044                    return opti+1;
13045                }
13046                build(name);
13047            }
13048            return opti;
13049        }
13050
13051        boolean match(Object object, ComponentName comp) {
13052            if (all) {
13053                return true;
13054            }
13055            if (components != null) {
13056                for (int i=0; i<components.size(); i++) {
13057                    if (components.get(i).equals(comp)) {
13058                        return true;
13059                    }
13060                }
13061            }
13062            if (objects != null) {
13063                for (int i=0; i<objects.size(); i++) {
13064                    if (System.identityHashCode(object) == objects.get(i)) {
13065                        return true;
13066                    }
13067                }
13068            }
13069            if (strings != null) {
13070                String flat = comp.flattenToString();
13071                for (int i=0; i<strings.size(); i++) {
13072                    if (flat.contains(strings.get(i))) {
13073                        return true;
13074                    }
13075                }
13076            }
13077            return false;
13078        }
13079    }
13080
13081    /**
13082     * There are three things that cmd can be:
13083     *  - a flattened component name that matches an existing activity
13084     *  - the cmd arg isn't the flattened component name of an existing activity:
13085     *    dump all activity whose component contains the cmd as a substring
13086     *  - A hex number of the ActivityRecord object instance.
13087     */
13088    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13089            int opti, boolean dumpAll) {
13090        ArrayList<ActivityRecord> activities;
13091
13092        synchronized (this) {
13093            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13094        }
13095
13096        if (activities.size() <= 0) {
13097            return false;
13098        }
13099
13100        String[] newArgs = new String[args.length - opti];
13101        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13102
13103        TaskRecord lastTask = null;
13104        boolean needSep = false;
13105        for (int i=activities.size()-1; i>=0; i--) {
13106            ActivityRecord r = activities.get(i);
13107            if (needSep) {
13108                pw.println();
13109            }
13110            needSep = true;
13111            synchronized (this) {
13112                if (lastTask != r.task) {
13113                    lastTask = r.task;
13114                    pw.print("TASK "); pw.print(lastTask.affinity);
13115                            pw.print(" id="); pw.println(lastTask.taskId);
13116                    if (dumpAll) {
13117                        lastTask.dump(pw, "  ");
13118                    }
13119                }
13120            }
13121            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13122        }
13123        return true;
13124    }
13125
13126    /**
13127     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13128     * there is a thread associated with the activity.
13129     */
13130    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13131            final ActivityRecord r, String[] args, boolean dumpAll) {
13132        String innerPrefix = prefix + "  ";
13133        synchronized (this) {
13134            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13135                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13136                    pw.print(" pid=");
13137                    if (r.app != null) pw.println(r.app.pid);
13138                    else pw.println("(not running)");
13139            if (dumpAll) {
13140                r.dump(pw, innerPrefix);
13141            }
13142        }
13143        if (r.app != null && r.app.thread != null) {
13144            // flush anything that is already in the PrintWriter since the thread is going
13145            // to write to the file descriptor directly
13146            pw.flush();
13147            try {
13148                TransferPipe tp = new TransferPipe();
13149                try {
13150                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13151                            r.appToken, innerPrefix, args);
13152                    tp.go(fd);
13153                } finally {
13154                    tp.kill();
13155                }
13156            } catch (IOException e) {
13157                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13158            } catch (RemoteException e) {
13159                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13160            }
13161        }
13162    }
13163
13164    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13165            int opti, boolean dumpAll, String dumpPackage) {
13166        boolean needSep = false;
13167        boolean onlyHistory = false;
13168        boolean printedAnything = false;
13169
13170        if ("history".equals(dumpPackage)) {
13171            if (opti < args.length && "-s".equals(args[opti])) {
13172                dumpAll = false;
13173            }
13174            onlyHistory = true;
13175            dumpPackage = null;
13176        }
13177
13178        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13179        if (!onlyHistory && dumpAll) {
13180            if (mRegisteredReceivers.size() > 0) {
13181                boolean printed = false;
13182                Iterator it = mRegisteredReceivers.values().iterator();
13183                while (it.hasNext()) {
13184                    ReceiverList r = (ReceiverList)it.next();
13185                    if (dumpPackage != null && (r.app == null ||
13186                            !dumpPackage.equals(r.app.info.packageName))) {
13187                        continue;
13188                    }
13189                    if (!printed) {
13190                        pw.println("  Registered Receivers:");
13191                        needSep = true;
13192                        printed = true;
13193                        printedAnything = true;
13194                    }
13195                    pw.print("  * "); pw.println(r);
13196                    r.dump(pw, "    ");
13197                }
13198            }
13199
13200            if (mReceiverResolver.dump(pw, needSep ?
13201                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13202                    "    ", dumpPackage, false)) {
13203                needSep = true;
13204                printedAnything = true;
13205            }
13206        }
13207
13208        for (BroadcastQueue q : mBroadcastQueues) {
13209            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13210            printedAnything |= needSep;
13211        }
13212
13213        needSep = true;
13214
13215        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13216            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13217                if (needSep) {
13218                    pw.println();
13219                }
13220                needSep = true;
13221                printedAnything = true;
13222                pw.print("  Sticky broadcasts for user ");
13223                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13224                StringBuilder sb = new StringBuilder(128);
13225                for (Map.Entry<String, ArrayList<Intent>> ent
13226                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13227                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13228                    if (dumpAll) {
13229                        pw.println(":");
13230                        ArrayList<Intent> intents = ent.getValue();
13231                        final int N = intents.size();
13232                        for (int i=0; i<N; i++) {
13233                            sb.setLength(0);
13234                            sb.append("    Intent: ");
13235                            intents.get(i).toShortString(sb, false, true, false, false);
13236                            pw.println(sb.toString());
13237                            Bundle bundle = intents.get(i).getExtras();
13238                            if (bundle != null) {
13239                                pw.print("      ");
13240                                pw.println(bundle.toString());
13241                            }
13242                        }
13243                    } else {
13244                        pw.println("");
13245                    }
13246                }
13247            }
13248        }
13249
13250        if (!onlyHistory && dumpAll) {
13251            pw.println();
13252            for (BroadcastQueue queue : mBroadcastQueues) {
13253                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13254                        + queue.mBroadcastsScheduled);
13255            }
13256            pw.println("  mHandler:");
13257            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13258            needSep = true;
13259            printedAnything = true;
13260        }
13261
13262        if (!printedAnything) {
13263            pw.println("  (nothing)");
13264        }
13265    }
13266
13267    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13268            int opti, boolean dumpAll, String dumpPackage) {
13269        boolean needSep;
13270        boolean printedAnything = false;
13271
13272        ItemMatcher matcher = new ItemMatcher();
13273        matcher.build(args, opti);
13274
13275        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13276
13277        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13278        printedAnything |= needSep;
13279
13280        if (mLaunchingProviders.size() > 0) {
13281            boolean printed = false;
13282            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13283                ContentProviderRecord r = mLaunchingProviders.get(i);
13284                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13285                    continue;
13286                }
13287                if (!printed) {
13288                    if (needSep) pw.println();
13289                    needSep = true;
13290                    pw.println("  Launching content providers:");
13291                    printed = true;
13292                    printedAnything = true;
13293                }
13294                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13295                        pw.println(r);
13296            }
13297        }
13298
13299        if (mGrantedUriPermissions.size() > 0) {
13300            boolean printed = false;
13301            int dumpUid = -2;
13302            if (dumpPackage != null) {
13303                try {
13304                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13305                } catch (NameNotFoundException e) {
13306                    dumpUid = -1;
13307                }
13308            }
13309            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13310                int uid = mGrantedUriPermissions.keyAt(i);
13311                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13312                    continue;
13313                }
13314                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13315                if (!printed) {
13316                    if (needSep) pw.println();
13317                    needSep = true;
13318                    pw.println("  Granted Uri Permissions:");
13319                    printed = true;
13320                    printedAnything = true;
13321                }
13322                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13323                for (UriPermission perm : perms.values()) {
13324                    pw.print("    "); pw.println(perm);
13325                    if (dumpAll) {
13326                        perm.dump(pw, "      ");
13327                    }
13328                }
13329            }
13330        }
13331
13332        if (!printedAnything) {
13333            pw.println("  (nothing)");
13334        }
13335    }
13336
13337    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13338            int opti, boolean dumpAll, String dumpPackage) {
13339        boolean printed = false;
13340
13341        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13342
13343        if (mIntentSenderRecords.size() > 0) {
13344            Iterator<WeakReference<PendingIntentRecord>> it
13345                    = mIntentSenderRecords.values().iterator();
13346            while (it.hasNext()) {
13347                WeakReference<PendingIntentRecord> ref = it.next();
13348                PendingIntentRecord rec = ref != null ? ref.get(): null;
13349                if (dumpPackage != null && (rec == null
13350                        || !dumpPackage.equals(rec.key.packageName))) {
13351                    continue;
13352                }
13353                printed = true;
13354                if (rec != null) {
13355                    pw.print("  * "); pw.println(rec);
13356                    if (dumpAll) {
13357                        rec.dump(pw, "    ");
13358                    }
13359                } else {
13360                    pw.print("  * "); pw.println(ref);
13361                }
13362            }
13363        }
13364
13365        if (!printed) {
13366            pw.println("  (nothing)");
13367        }
13368    }
13369
13370    private static final int dumpProcessList(PrintWriter pw,
13371            ActivityManagerService service, List list,
13372            String prefix, String normalLabel, String persistentLabel,
13373            String dumpPackage) {
13374        int numPers = 0;
13375        final int N = list.size()-1;
13376        for (int i=N; i>=0; i--) {
13377            ProcessRecord r = (ProcessRecord)list.get(i);
13378            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13379                continue;
13380            }
13381            pw.println(String.format("%s%s #%2d: %s",
13382                    prefix, (r.persistent ? persistentLabel : normalLabel),
13383                    i, r.toString()));
13384            if (r.persistent) {
13385                numPers++;
13386            }
13387        }
13388        return numPers;
13389    }
13390
13391    private static final boolean dumpProcessOomList(PrintWriter pw,
13392            ActivityManagerService service, List<ProcessRecord> origList,
13393            String prefix, String normalLabel, String persistentLabel,
13394            boolean inclDetails, String dumpPackage) {
13395
13396        ArrayList<Pair<ProcessRecord, Integer>> list
13397                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13398        for (int i=0; i<origList.size(); i++) {
13399            ProcessRecord r = origList.get(i);
13400            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13401                continue;
13402            }
13403            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13404        }
13405
13406        if (list.size() <= 0) {
13407            return false;
13408        }
13409
13410        Comparator<Pair<ProcessRecord, Integer>> comparator
13411                = new Comparator<Pair<ProcessRecord, Integer>>() {
13412            @Override
13413            public int compare(Pair<ProcessRecord, Integer> object1,
13414                    Pair<ProcessRecord, Integer> object2) {
13415                if (object1.first.setAdj != object2.first.setAdj) {
13416                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13417                }
13418                if (object1.second.intValue() != object2.second.intValue()) {
13419                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13420                }
13421                return 0;
13422            }
13423        };
13424
13425        Collections.sort(list, comparator);
13426
13427        final long curRealtime = SystemClock.elapsedRealtime();
13428        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13429        final long curUptime = SystemClock.uptimeMillis();
13430        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13431
13432        for (int i=list.size()-1; i>=0; i--) {
13433            ProcessRecord r = list.get(i).first;
13434            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13435            char schedGroup;
13436            switch (r.setSchedGroup) {
13437                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13438                    schedGroup = 'B';
13439                    break;
13440                case Process.THREAD_GROUP_DEFAULT:
13441                    schedGroup = 'F';
13442                    break;
13443                default:
13444                    schedGroup = '?';
13445                    break;
13446            }
13447            char foreground;
13448            if (r.foregroundActivities) {
13449                foreground = 'A';
13450            } else if (r.foregroundServices) {
13451                foreground = 'S';
13452            } else {
13453                foreground = ' ';
13454            }
13455            String procState = ProcessList.makeProcStateString(r.curProcState);
13456            pw.print(prefix);
13457            pw.print(r.persistent ? persistentLabel : normalLabel);
13458            pw.print(" #");
13459            int num = (origList.size()-1)-list.get(i).second;
13460            if (num < 10) pw.print(' ');
13461            pw.print(num);
13462            pw.print(": ");
13463            pw.print(oomAdj);
13464            pw.print(' ');
13465            pw.print(schedGroup);
13466            pw.print('/');
13467            pw.print(foreground);
13468            pw.print('/');
13469            pw.print(procState);
13470            pw.print(" trm:");
13471            if (r.trimMemoryLevel < 10) pw.print(' ');
13472            pw.print(r.trimMemoryLevel);
13473            pw.print(' ');
13474            pw.print(r.toShortString());
13475            pw.print(" (");
13476            pw.print(r.adjType);
13477            pw.println(')');
13478            if (r.adjSource != null || r.adjTarget != null) {
13479                pw.print(prefix);
13480                pw.print("    ");
13481                if (r.adjTarget instanceof ComponentName) {
13482                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13483                } else if (r.adjTarget != null) {
13484                    pw.print(r.adjTarget.toString());
13485                } else {
13486                    pw.print("{null}");
13487                }
13488                pw.print("<=");
13489                if (r.adjSource instanceof ProcessRecord) {
13490                    pw.print("Proc{");
13491                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13492                    pw.println("}");
13493                } else if (r.adjSource != null) {
13494                    pw.println(r.adjSource.toString());
13495                } else {
13496                    pw.println("{null}");
13497                }
13498            }
13499            if (inclDetails) {
13500                pw.print(prefix);
13501                pw.print("    ");
13502                pw.print("oom: max="); pw.print(r.maxAdj);
13503                pw.print(" curRaw="); pw.print(r.curRawAdj);
13504                pw.print(" setRaw="); pw.print(r.setRawAdj);
13505                pw.print(" cur="); pw.print(r.curAdj);
13506                pw.print(" set="); pw.println(r.setAdj);
13507                pw.print(prefix);
13508                pw.print("    ");
13509                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13510                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13511                pw.print(" lastPss="); pw.print(r.lastPss);
13512                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13513                pw.print(prefix);
13514                pw.print("    ");
13515                pw.print("cached="); pw.print(r.cached);
13516                pw.print(" empty="); pw.print(r.empty);
13517                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13518
13519                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13520                    if (r.lastWakeTime != 0) {
13521                        long wtime;
13522                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13523                        synchronized (stats) {
13524                            wtime = stats.getProcessWakeTime(r.info.uid,
13525                                    r.pid, curRealtime);
13526                        }
13527                        long timeUsed = wtime - r.lastWakeTime;
13528                        pw.print(prefix);
13529                        pw.print("    ");
13530                        pw.print("keep awake over ");
13531                        TimeUtils.formatDuration(realtimeSince, pw);
13532                        pw.print(" used ");
13533                        TimeUtils.formatDuration(timeUsed, pw);
13534                        pw.print(" (");
13535                        pw.print((timeUsed*100)/realtimeSince);
13536                        pw.println("%)");
13537                    }
13538                    if (r.lastCpuTime != 0) {
13539                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13540                        pw.print(prefix);
13541                        pw.print("    ");
13542                        pw.print("run cpu over ");
13543                        TimeUtils.formatDuration(uptimeSince, pw);
13544                        pw.print(" used ");
13545                        TimeUtils.formatDuration(timeUsed, pw);
13546                        pw.print(" (");
13547                        pw.print((timeUsed*100)/uptimeSince);
13548                        pw.println("%)");
13549                    }
13550                }
13551            }
13552        }
13553        return true;
13554    }
13555
13556    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13557        ArrayList<ProcessRecord> procs;
13558        synchronized (this) {
13559            if (args != null && args.length > start
13560                    && args[start].charAt(0) != '-') {
13561                procs = new ArrayList<ProcessRecord>();
13562                int pid = -1;
13563                try {
13564                    pid = Integer.parseInt(args[start]);
13565                } catch (NumberFormatException e) {
13566                }
13567                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13568                    ProcessRecord proc = mLruProcesses.get(i);
13569                    if (proc.pid == pid) {
13570                        procs.add(proc);
13571                    } else if (proc.processName.equals(args[start])) {
13572                        procs.add(proc);
13573                    }
13574                }
13575                if (procs.size() <= 0) {
13576                    return null;
13577                }
13578            } else {
13579                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13580            }
13581        }
13582        return procs;
13583    }
13584
13585    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13586            PrintWriter pw, String[] args) {
13587        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13588        if (procs == null) {
13589            pw.println("No process found for: " + args[0]);
13590            return;
13591        }
13592
13593        long uptime = SystemClock.uptimeMillis();
13594        long realtime = SystemClock.elapsedRealtime();
13595        pw.println("Applications Graphics Acceleration Info:");
13596        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13597
13598        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13599            ProcessRecord r = procs.get(i);
13600            if (r.thread != null) {
13601                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13602                pw.flush();
13603                try {
13604                    TransferPipe tp = new TransferPipe();
13605                    try {
13606                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13607                        tp.go(fd);
13608                    } finally {
13609                        tp.kill();
13610                    }
13611                } catch (IOException e) {
13612                    pw.println("Failure while dumping the app: " + r);
13613                    pw.flush();
13614                } catch (RemoteException e) {
13615                    pw.println("Got a RemoteException while dumping the app " + r);
13616                    pw.flush();
13617                }
13618            }
13619        }
13620    }
13621
13622    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13623        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13624        if (procs == null) {
13625            pw.println("No process found for: " + args[0]);
13626            return;
13627        }
13628
13629        pw.println("Applications Database Info:");
13630
13631        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13632            ProcessRecord r = procs.get(i);
13633            if (r.thread != null) {
13634                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13635                pw.flush();
13636                try {
13637                    TransferPipe tp = new TransferPipe();
13638                    try {
13639                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13640                        tp.go(fd);
13641                    } finally {
13642                        tp.kill();
13643                    }
13644                } catch (IOException e) {
13645                    pw.println("Failure while dumping the app: " + r);
13646                    pw.flush();
13647                } catch (RemoteException e) {
13648                    pw.println("Got a RemoteException while dumping the app " + r);
13649                    pw.flush();
13650                }
13651            }
13652        }
13653    }
13654
13655    final static class MemItem {
13656        final boolean isProc;
13657        final String label;
13658        final String shortLabel;
13659        final long pss;
13660        final int id;
13661        final boolean hasActivities;
13662        ArrayList<MemItem> subitems;
13663
13664        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13665                boolean _hasActivities) {
13666            isProc = true;
13667            label = _label;
13668            shortLabel = _shortLabel;
13669            pss = _pss;
13670            id = _id;
13671            hasActivities = _hasActivities;
13672        }
13673
13674        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13675            isProc = false;
13676            label = _label;
13677            shortLabel = _shortLabel;
13678            pss = _pss;
13679            id = _id;
13680            hasActivities = false;
13681        }
13682    }
13683
13684    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13685            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13686        if (sort && !isCompact) {
13687            Collections.sort(items, new Comparator<MemItem>() {
13688                @Override
13689                public int compare(MemItem lhs, MemItem rhs) {
13690                    if (lhs.pss < rhs.pss) {
13691                        return 1;
13692                    } else if (lhs.pss > rhs.pss) {
13693                        return -1;
13694                    }
13695                    return 0;
13696                }
13697            });
13698        }
13699
13700        for (int i=0; i<items.size(); i++) {
13701            MemItem mi = items.get(i);
13702            if (!isCompact) {
13703                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13704            } else if (mi.isProc) {
13705                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13706                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13707                pw.println(mi.hasActivities ? ",a" : ",e");
13708            } else {
13709                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13710                pw.println(mi.pss);
13711            }
13712            if (mi.subitems != null) {
13713                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13714                        true, isCompact);
13715            }
13716        }
13717    }
13718
13719    // These are in KB.
13720    static final long[] DUMP_MEM_BUCKETS = new long[] {
13721        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13722        120*1024, 160*1024, 200*1024,
13723        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13724        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13725    };
13726
13727    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13728            boolean stackLike) {
13729        int start = label.lastIndexOf('.');
13730        if (start >= 0) start++;
13731        else start = 0;
13732        int end = label.length();
13733        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13734            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13735                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13736                out.append(bucket);
13737                out.append(stackLike ? "MB." : "MB ");
13738                out.append(label, start, end);
13739                return;
13740            }
13741        }
13742        out.append(memKB/1024);
13743        out.append(stackLike ? "MB." : "MB ");
13744        out.append(label, start, end);
13745    }
13746
13747    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13748            ProcessList.NATIVE_ADJ,
13749            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13750            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13751            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13752            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13753            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13754    };
13755    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13756            "Native",
13757            "System", "Persistent", "Foreground",
13758            "Visible", "Perceptible",
13759            "Heavy Weight", "Backup",
13760            "A Services", "Home",
13761            "Previous", "B Services", "Cached"
13762    };
13763    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13764            "native",
13765            "sys", "pers", "fore",
13766            "vis", "percept",
13767            "heavy", "backup",
13768            "servicea", "home",
13769            "prev", "serviceb", "cached"
13770    };
13771
13772    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13773            long realtime, boolean isCheckinRequest, boolean isCompact) {
13774        if (isCheckinRequest || isCompact) {
13775            // short checkin version
13776            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13777        } else {
13778            pw.println("Applications Memory Usage (kB):");
13779            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13780        }
13781    }
13782
13783    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13784            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13785        boolean dumpDetails = false;
13786        boolean dumpFullDetails = false;
13787        boolean dumpDalvik = false;
13788        boolean oomOnly = false;
13789        boolean isCompact = false;
13790        boolean localOnly = false;
13791
13792        int opti = 0;
13793        while (opti < args.length) {
13794            String opt = args[opti];
13795            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13796                break;
13797            }
13798            opti++;
13799            if ("-a".equals(opt)) {
13800                dumpDetails = true;
13801                dumpFullDetails = true;
13802                dumpDalvik = true;
13803            } else if ("-d".equals(opt)) {
13804                dumpDalvik = true;
13805            } else if ("-c".equals(opt)) {
13806                isCompact = true;
13807            } else if ("--oom".equals(opt)) {
13808                oomOnly = true;
13809            } else if ("--local".equals(opt)) {
13810                localOnly = true;
13811            } else if ("-h".equals(opt)) {
13812                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13813                pw.println("  -a: include all available information for each process.");
13814                pw.println("  -d: include dalvik details when dumping process details.");
13815                pw.println("  -c: dump in a compact machine-parseable representation.");
13816                pw.println("  --oom: only show processes organized by oom adj.");
13817                pw.println("  --local: only collect details locally, don't call process.");
13818                pw.println("If [process] is specified it can be the name or ");
13819                pw.println("pid of a specific process to dump.");
13820                return;
13821            } else {
13822                pw.println("Unknown argument: " + opt + "; use -h for help");
13823            }
13824        }
13825
13826        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13827        long uptime = SystemClock.uptimeMillis();
13828        long realtime = SystemClock.elapsedRealtime();
13829        final long[] tmpLong = new long[1];
13830
13831        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13832        if (procs == null) {
13833            // No Java processes.  Maybe they want to print a native process.
13834            if (args != null && args.length > opti
13835                    && args[opti].charAt(0) != '-') {
13836                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13837                        = new ArrayList<ProcessCpuTracker.Stats>();
13838                updateCpuStatsNow();
13839                int findPid = -1;
13840                try {
13841                    findPid = Integer.parseInt(args[opti]);
13842                } catch (NumberFormatException e) {
13843                }
13844                synchronized (mProcessCpuTracker) {
13845                    final int N = mProcessCpuTracker.countStats();
13846                    for (int i=0; i<N; i++) {
13847                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13848                        if (st.pid == findPid || (st.baseName != null
13849                                && st.baseName.equals(args[opti]))) {
13850                            nativeProcs.add(st);
13851                        }
13852                    }
13853                }
13854                if (nativeProcs.size() > 0) {
13855                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13856                            isCompact);
13857                    Debug.MemoryInfo mi = null;
13858                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13859                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13860                        final int pid = r.pid;
13861                        if (!isCheckinRequest && dumpDetails) {
13862                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13863                        }
13864                        if (mi == null) {
13865                            mi = new Debug.MemoryInfo();
13866                        }
13867                        if (dumpDetails || (!brief && !oomOnly)) {
13868                            Debug.getMemoryInfo(pid, mi);
13869                        } else {
13870                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13871                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13872                        }
13873                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13874                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13875                        if (isCheckinRequest) {
13876                            pw.println();
13877                        }
13878                    }
13879                    return;
13880                }
13881            }
13882            pw.println("No process found for: " + args[opti]);
13883            return;
13884        }
13885
13886        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13887            dumpDetails = true;
13888        }
13889
13890        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13891
13892        String[] innerArgs = new String[args.length-opti];
13893        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13894
13895        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13896        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13897        long nativePss=0, dalvikPss=0, otherPss=0;
13898        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13899
13900        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13901        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13902                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13903
13904        long totalPss = 0;
13905        long cachedPss = 0;
13906
13907        Debug.MemoryInfo mi = null;
13908        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13909            final ProcessRecord r = procs.get(i);
13910            final IApplicationThread thread;
13911            final int pid;
13912            final int oomAdj;
13913            final boolean hasActivities;
13914            synchronized (this) {
13915                thread = r.thread;
13916                pid = r.pid;
13917                oomAdj = r.getSetAdjWithServices();
13918                hasActivities = r.activities.size() > 0;
13919            }
13920            if (thread != null) {
13921                if (!isCheckinRequest && dumpDetails) {
13922                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13923                }
13924                if (mi == null) {
13925                    mi = new Debug.MemoryInfo();
13926                }
13927                if (dumpDetails || (!brief && !oomOnly)) {
13928                    Debug.getMemoryInfo(pid, mi);
13929                } else {
13930                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13931                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13932                }
13933                if (dumpDetails) {
13934                    if (localOnly) {
13935                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13936                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13937                        if (isCheckinRequest) {
13938                            pw.println();
13939                        }
13940                    } else {
13941                        try {
13942                            pw.flush();
13943                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13944                                    dumpDalvik, innerArgs);
13945                        } catch (RemoteException e) {
13946                            if (!isCheckinRequest) {
13947                                pw.println("Got RemoteException!");
13948                                pw.flush();
13949                            }
13950                        }
13951                    }
13952                }
13953
13954                final long myTotalPss = mi.getTotalPss();
13955                final long myTotalUss = mi.getTotalUss();
13956
13957                synchronized (this) {
13958                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13959                        // Record this for posterity if the process has been stable.
13960                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13961                    }
13962                }
13963
13964                if (!isCheckinRequest && mi != null) {
13965                    totalPss += myTotalPss;
13966                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13967                            (hasActivities ? " / activities)" : ")"),
13968                            r.processName, myTotalPss, pid, hasActivities);
13969                    procMems.add(pssItem);
13970                    procMemsMap.put(pid, pssItem);
13971
13972                    nativePss += mi.nativePss;
13973                    dalvikPss += mi.dalvikPss;
13974                    otherPss += mi.otherPss;
13975                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13976                        long mem = mi.getOtherPss(j);
13977                        miscPss[j] += mem;
13978                        otherPss -= mem;
13979                    }
13980
13981                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13982                        cachedPss += myTotalPss;
13983                    }
13984
13985                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13986                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13987                                || oomIndex == (oomPss.length-1)) {
13988                            oomPss[oomIndex] += myTotalPss;
13989                            if (oomProcs[oomIndex] == null) {
13990                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13991                            }
13992                            oomProcs[oomIndex].add(pssItem);
13993                            break;
13994                        }
13995                    }
13996                }
13997            }
13998        }
13999
14000        long nativeProcTotalPss = 0;
14001
14002        if (!isCheckinRequest && procs.size() > 1) {
14003            // If we are showing aggregations, also look for native processes to
14004            // include so that our aggregations are more accurate.
14005            updateCpuStatsNow();
14006            synchronized (mProcessCpuTracker) {
14007                final int N = mProcessCpuTracker.countStats();
14008                for (int i=0; i<N; i++) {
14009                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14010                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14011                        if (mi == null) {
14012                            mi = new Debug.MemoryInfo();
14013                        }
14014                        if (!brief && !oomOnly) {
14015                            Debug.getMemoryInfo(st.pid, mi);
14016                        } else {
14017                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14018                            mi.nativePrivateDirty = (int)tmpLong[0];
14019                        }
14020
14021                        final long myTotalPss = mi.getTotalPss();
14022                        totalPss += myTotalPss;
14023                        nativeProcTotalPss += myTotalPss;
14024
14025                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14026                                st.name, myTotalPss, st.pid, false);
14027                        procMems.add(pssItem);
14028
14029                        nativePss += mi.nativePss;
14030                        dalvikPss += mi.dalvikPss;
14031                        otherPss += mi.otherPss;
14032                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14033                            long mem = mi.getOtherPss(j);
14034                            miscPss[j] += mem;
14035                            otherPss -= mem;
14036                        }
14037                        oomPss[0] += myTotalPss;
14038                        if (oomProcs[0] == null) {
14039                            oomProcs[0] = new ArrayList<MemItem>();
14040                        }
14041                        oomProcs[0].add(pssItem);
14042                    }
14043                }
14044            }
14045
14046            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14047
14048            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14049            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14050            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14051            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14052                String label = Debug.MemoryInfo.getOtherLabel(j);
14053                catMems.add(new MemItem(label, label, miscPss[j], j));
14054            }
14055
14056            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14057            for (int j=0; j<oomPss.length; j++) {
14058                if (oomPss[j] != 0) {
14059                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14060                            : DUMP_MEM_OOM_LABEL[j];
14061                    MemItem item = new MemItem(label, label, oomPss[j],
14062                            DUMP_MEM_OOM_ADJ[j]);
14063                    item.subitems = oomProcs[j];
14064                    oomMems.add(item);
14065                }
14066            }
14067
14068            if (!brief && !oomOnly && !isCompact) {
14069                pw.println();
14070                pw.println("Total PSS by process:");
14071                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14072                pw.println();
14073            }
14074            if (!isCompact) {
14075                pw.println("Total PSS by OOM adjustment:");
14076            }
14077            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14078            if (!brief && !oomOnly) {
14079                PrintWriter out = categoryPw != null ? categoryPw : pw;
14080                if (!isCompact) {
14081                    out.println();
14082                    out.println("Total PSS by category:");
14083                }
14084                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14085            }
14086            if (!isCompact) {
14087                pw.println();
14088            }
14089            MemInfoReader memInfo = new MemInfoReader();
14090            memInfo.readMemInfo();
14091            if (nativeProcTotalPss > 0) {
14092                synchronized (this) {
14093                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14094                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14095                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14096                            nativeProcTotalPss);
14097                }
14098            }
14099            if (!brief) {
14100                if (!isCompact) {
14101                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14102                    pw.print(" kB (status ");
14103                    switch (mLastMemoryLevel) {
14104                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14105                            pw.println("normal)");
14106                            break;
14107                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14108                            pw.println("moderate)");
14109                            break;
14110                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14111                            pw.println("low)");
14112                            break;
14113                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14114                            pw.println("critical)");
14115                            break;
14116                        default:
14117                            pw.print(mLastMemoryLevel);
14118                            pw.println(")");
14119                            break;
14120                    }
14121                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14122                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14123                            pw.print(cachedPss); pw.print(" cached pss + ");
14124                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14125                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14126                } else {
14127                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14128                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14129                            + memInfo.getFreeSizeKb()); pw.print(",");
14130                    pw.println(totalPss - cachedPss);
14131                }
14132            }
14133            if (!isCompact) {
14134                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14135                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14136                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14137                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14138                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14139                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14140                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14141                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14142                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14143                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14144                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14145            }
14146            if (!brief) {
14147                if (memInfo.getZramTotalSizeKb() != 0) {
14148                    if (!isCompact) {
14149                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14150                                pw.print(" kB physical used for ");
14151                                pw.print(memInfo.getSwapTotalSizeKb()
14152                                        - memInfo.getSwapFreeSizeKb());
14153                                pw.print(" kB in swap (");
14154                                pw.print(memInfo.getSwapTotalSizeKb());
14155                                pw.println(" kB total swap)");
14156                    } else {
14157                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14158                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14159                                pw.println(memInfo.getSwapFreeSizeKb());
14160                    }
14161                }
14162                final int[] SINGLE_LONG_FORMAT = new int[] {
14163                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14164                };
14165                long[] longOut = new long[1];
14166                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14167                        SINGLE_LONG_FORMAT, null, longOut, null);
14168                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14169                longOut[0] = 0;
14170                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14171                        SINGLE_LONG_FORMAT, null, longOut, null);
14172                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14173                longOut[0] = 0;
14174                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14175                        SINGLE_LONG_FORMAT, null, longOut, null);
14176                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14177                longOut[0] = 0;
14178                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14179                        SINGLE_LONG_FORMAT, null, longOut, null);
14180                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14181                if (!isCompact) {
14182                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14183                        pw.print("      KSM: "); pw.print(sharing);
14184                                pw.print(" kB saved from shared ");
14185                                pw.print(shared); pw.println(" kB");
14186                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14187                                pw.print(voltile); pw.println(" kB volatile");
14188                    }
14189                    pw.print("   Tuning: ");
14190                    pw.print(ActivityManager.staticGetMemoryClass());
14191                    pw.print(" (large ");
14192                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14193                    pw.print("), oom ");
14194                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14195                    pw.print(" kB");
14196                    pw.print(", restore limit ");
14197                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14198                    pw.print(" kB");
14199                    if (ActivityManager.isLowRamDeviceStatic()) {
14200                        pw.print(" (low-ram)");
14201                    }
14202                    if (ActivityManager.isHighEndGfx()) {
14203                        pw.print(" (high-end-gfx)");
14204                    }
14205                    pw.println();
14206                } else {
14207                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14208                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14209                    pw.println(voltile);
14210                    pw.print("tuning,");
14211                    pw.print(ActivityManager.staticGetMemoryClass());
14212                    pw.print(',');
14213                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14214                    pw.print(',');
14215                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14216                    if (ActivityManager.isLowRamDeviceStatic()) {
14217                        pw.print(",low-ram");
14218                    }
14219                    if (ActivityManager.isHighEndGfx()) {
14220                        pw.print(",high-end-gfx");
14221                    }
14222                    pw.println();
14223                }
14224            }
14225        }
14226    }
14227
14228    /**
14229     * Searches array of arguments for the specified string
14230     * @param args array of argument strings
14231     * @param value value to search for
14232     * @return true if the value is contained in the array
14233     */
14234    private static boolean scanArgs(String[] args, String value) {
14235        if (args != null) {
14236            for (String arg : args) {
14237                if (value.equals(arg)) {
14238                    return true;
14239                }
14240            }
14241        }
14242        return false;
14243    }
14244
14245    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14246            ContentProviderRecord cpr, boolean always) {
14247        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14248
14249        if (!inLaunching || always) {
14250            synchronized (cpr) {
14251                cpr.launchingApp = null;
14252                cpr.notifyAll();
14253            }
14254            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14255            String names[] = cpr.info.authority.split(";");
14256            for (int j = 0; j < names.length; j++) {
14257                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14258            }
14259        }
14260
14261        for (int i=0; i<cpr.connections.size(); i++) {
14262            ContentProviderConnection conn = cpr.connections.get(i);
14263            if (conn.waiting) {
14264                // If this connection is waiting for the provider, then we don't
14265                // need to mess with its process unless we are always removing
14266                // or for some reason the provider is not currently launching.
14267                if (inLaunching && !always) {
14268                    continue;
14269                }
14270            }
14271            ProcessRecord capp = conn.client;
14272            conn.dead = true;
14273            if (conn.stableCount > 0) {
14274                if (!capp.persistent && capp.thread != null
14275                        && capp.pid != 0
14276                        && capp.pid != MY_PID) {
14277                    capp.kill("depends on provider "
14278                            + cpr.name.flattenToShortString()
14279                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14280                }
14281            } else if (capp.thread != null && conn.provider.provider != null) {
14282                try {
14283                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14284                } catch (RemoteException e) {
14285                }
14286                // In the protocol here, we don't expect the client to correctly
14287                // clean up this connection, we'll just remove it.
14288                cpr.connections.remove(i);
14289                conn.client.conProviders.remove(conn);
14290            }
14291        }
14292
14293        if (inLaunching && always) {
14294            mLaunchingProviders.remove(cpr);
14295        }
14296        return inLaunching;
14297    }
14298
14299    /**
14300     * Main code for cleaning up a process when it has gone away.  This is
14301     * called both as a result of the process dying, or directly when stopping
14302     * a process when running in single process mode.
14303     */
14304    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14305            boolean restarting, boolean allowRestart, int index) {
14306        if (index >= 0) {
14307            removeLruProcessLocked(app);
14308            ProcessList.remove(app.pid);
14309        }
14310
14311        mProcessesToGc.remove(app);
14312        mPendingPssProcesses.remove(app);
14313
14314        // Dismiss any open dialogs.
14315        if (app.crashDialog != null && !app.forceCrashReport) {
14316            app.crashDialog.dismiss();
14317            app.crashDialog = null;
14318        }
14319        if (app.anrDialog != null) {
14320            app.anrDialog.dismiss();
14321            app.anrDialog = null;
14322        }
14323        if (app.waitDialog != null) {
14324            app.waitDialog.dismiss();
14325            app.waitDialog = null;
14326        }
14327
14328        app.crashing = false;
14329        app.notResponding = false;
14330
14331        app.resetPackageList(mProcessStats);
14332        app.unlinkDeathRecipient();
14333        app.makeInactive(mProcessStats);
14334        app.waitingToKill = null;
14335        app.forcingToForeground = null;
14336        updateProcessForegroundLocked(app, false, false);
14337        app.foregroundActivities = false;
14338        app.hasShownUi = false;
14339        app.treatLikeActivity = false;
14340        app.hasAboveClient = false;
14341        app.hasClientActivities = false;
14342
14343        mServices.killServicesLocked(app, allowRestart);
14344
14345        boolean restart = false;
14346
14347        // Remove published content providers.
14348        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14349            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14350            final boolean always = app.bad || !allowRestart;
14351            if (removeDyingProviderLocked(app, cpr, always) || always) {
14352                // We left the provider in the launching list, need to
14353                // restart it.
14354                restart = true;
14355            }
14356
14357            cpr.provider = null;
14358            cpr.proc = null;
14359        }
14360        app.pubProviders.clear();
14361
14362        // Take care of any launching providers waiting for this process.
14363        if (checkAppInLaunchingProvidersLocked(app, false)) {
14364            restart = true;
14365        }
14366
14367        // Unregister from connected content providers.
14368        if (!app.conProviders.isEmpty()) {
14369            for (int i=0; i<app.conProviders.size(); i++) {
14370                ContentProviderConnection conn = app.conProviders.get(i);
14371                conn.provider.connections.remove(conn);
14372            }
14373            app.conProviders.clear();
14374        }
14375
14376        // At this point there may be remaining entries in mLaunchingProviders
14377        // where we were the only one waiting, so they are no longer of use.
14378        // Look for these and clean up if found.
14379        // XXX Commented out for now.  Trying to figure out a way to reproduce
14380        // the actual situation to identify what is actually going on.
14381        if (false) {
14382            for (int i=0; i<mLaunchingProviders.size(); i++) {
14383                ContentProviderRecord cpr = (ContentProviderRecord)
14384                        mLaunchingProviders.get(i);
14385                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14386                    synchronized (cpr) {
14387                        cpr.launchingApp = null;
14388                        cpr.notifyAll();
14389                    }
14390                }
14391            }
14392        }
14393
14394        skipCurrentReceiverLocked(app);
14395
14396        // Unregister any receivers.
14397        for (int i=app.receivers.size()-1; i>=0; i--) {
14398            removeReceiverLocked(app.receivers.valueAt(i));
14399        }
14400        app.receivers.clear();
14401
14402        // If the app is undergoing backup, tell the backup manager about it
14403        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14404            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14405                    + mBackupTarget.appInfo + " died during backup");
14406            try {
14407                IBackupManager bm = IBackupManager.Stub.asInterface(
14408                        ServiceManager.getService(Context.BACKUP_SERVICE));
14409                bm.agentDisconnected(app.info.packageName);
14410            } catch (RemoteException e) {
14411                // can't happen; backup manager is local
14412            }
14413        }
14414
14415        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14416            ProcessChangeItem item = mPendingProcessChanges.get(i);
14417            if (item.pid == app.pid) {
14418                mPendingProcessChanges.remove(i);
14419                mAvailProcessChanges.add(item);
14420            }
14421        }
14422        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14423
14424        // If the caller is restarting this app, then leave it in its
14425        // current lists and let the caller take care of it.
14426        if (restarting) {
14427            return;
14428        }
14429
14430        if (!app.persistent || app.isolated) {
14431            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14432                    "Removing non-persistent process during cleanup: " + app);
14433            mProcessNames.remove(app.processName, app.uid);
14434            mIsolatedProcesses.remove(app.uid);
14435            if (mHeavyWeightProcess == app) {
14436                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14437                        mHeavyWeightProcess.userId, 0));
14438                mHeavyWeightProcess = null;
14439            }
14440        } else if (!app.removed) {
14441            // This app is persistent, so we need to keep its record around.
14442            // If it is not already on the pending app list, add it there
14443            // and start a new process for it.
14444            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14445                mPersistentStartingProcesses.add(app);
14446                restart = true;
14447            }
14448        }
14449        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14450                "Clean-up removing on hold: " + app);
14451        mProcessesOnHold.remove(app);
14452
14453        if (app == mHomeProcess) {
14454            mHomeProcess = null;
14455        }
14456        if (app == mPreviousProcess) {
14457            mPreviousProcess = null;
14458        }
14459
14460        if (restart && !app.isolated) {
14461            // We have components that still need to be running in the
14462            // process, so re-launch it.
14463            mProcessNames.put(app.processName, app.uid, app);
14464            startProcessLocked(app, "restart", app.processName);
14465        } else if (app.pid > 0 && app.pid != MY_PID) {
14466            // Goodbye!
14467            boolean removed;
14468            synchronized (mPidsSelfLocked) {
14469                mPidsSelfLocked.remove(app.pid);
14470                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14471            }
14472            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14473            if (app.isolated) {
14474                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14475            }
14476            app.setPid(0);
14477        }
14478    }
14479
14480    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14481        // Look through the content providers we are waiting to have launched,
14482        // and if any run in this process then either schedule a restart of
14483        // the process or kill the client waiting for it if this process has
14484        // gone bad.
14485        int NL = mLaunchingProviders.size();
14486        boolean restart = false;
14487        for (int i=0; i<NL; i++) {
14488            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14489            if (cpr.launchingApp == app) {
14490                if (!alwaysBad && !app.bad) {
14491                    restart = true;
14492                } else {
14493                    removeDyingProviderLocked(app, cpr, true);
14494                    // cpr should have been removed from mLaunchingProviders
14495                    NL = mLaunchingProviders.size();
14496                    i--;
14497                }
14498            }
14499        }
14500        return restart;
14501    }
14502
14503    // =========================================================
14504    // SERVICES
14505    // =========================================================
14506
14507    @Override
14508    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14509            int flags) {
14510        enforceNotIsolatedCaller("getServices");
14511        synchronized (this) {
14512            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14513        }
14514    }
14515
14516    @Override
14517    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14518        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14519        synchronized (this) {
14520            return mServices.getRunningServiceControlPanelLocked(name);
14521        }
14522    }
14523
14524    @Override
14525    public ComponentName startService(IApplicationThread caller, Intent service,
14526            String resolvedType, int userId) {
14527        enforceNotIsolatedCaller("startService");
14528        // Refuse possible leaked file descriptors
14529        if (service != null && service.hasFileDescriptors() == true) {
14530            throw new IllegalArgumentException("File descriptors passed in Intent");
14531        }
14532
14533        if (DEBUG_SERVICE)
14534            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14535        synchronized(this) {
14536            final int callingPid = Binder.getCallingPid();
14537            final int callingUid = Binder.getCallingUid();
14538            final long origId = Binder.clearCallingIdentity();
14539            ComponentName res = mServices.startServiceLocked(caller, service,
14540                    resolvedType, callingPid, callingUid, userId);
14541            Binder.restoreCallingIdentity(origId);
14542            return res;
14543        }
14544    }
14545
14546    ComponentName startServiceInPackage(int uid,
14547            Intent service, String resolvedType, int userId) {
14548        synchronized(this) {
14549            if (DEBUG_SERVICE)
14550                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14551            final long origId = Binder.clearCallingIdentity();
14552            ComponentName res = mServices.startServiceLocked(null, service,
14553                    resolvedType, -1, uid, userId);
14554            Binder.restoreCallingIdentity(origId);
14555            return res;
14556        }
14557    }
14558
14559    @Override
14560    public int stopService(IApplicationThread caller, Intent service,
14561            String resolvedType, int userId) {
14562        enforceNotIsolatedCaller("stopService");
14563        // Refuse possible leaked file descriptors
14564        if (service != null && service.hasFileDescriptors() == true) {
14565            throw new IllegalArgumentException("File descriptors passed in Intent");
14566        }
14567
14568        synchronized(this) {
14569            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14570        }
14571    }
14572
14573    @Override
14574    public IBinder peekService(Intent service, String resolvedType) {
14575        enforceNotIsolatedCaller("peekService");
14576        // Refuse possible leaked file descriptors
14577        if (service != null && service.hasFileDescriptors() == true) {
14578            throw new IllegalArgumentException("File descriptors passed in Intent");
14579        }
14580        synchronized(this) {
14581            return mServices.peekServiceLocked(service, resolvedType);
14582        }
14583    }
14584
14585    @Override
14586    public boolean stopServiceToken(ComponentName className, IBinder token,
14587            int startId) {
14588        synchronized(this) {
14589            return mServices.stopServiceTokenLocked(className, token, startId);
14590        }
14591    }
14592
14593    @Override
14594    public void setServiceForeground(ComponentName className, IBinder token,
14595            int id, Notification notification, boolean removeNotification) {
14596        synchronized(this) {
14597            mServices.setServiceForegroundLocked(className, token, id, notification,
14598                    removeNotification);
14599        }
14600    }
14601
14602    @Override
14603    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14604            boolean requireFull, String name, String callerPackage) {
14605        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14606                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14607    }
14608
14609    int unsafeConvertIncomingUser(int userId) {
14610        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14611                ? mCurrentUserId : userId;
14612    }
14613
14614    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14615            int allowMode, String name, String callerPackage) {
14616        final int callingUserId = UserHandle.getUserId(callingUid);
14617        if (callingUserId == userId) {
14618            return userId;
14619        }
14620
14621        // Note that we may be accessing mCurrentUserId outside of a lock...
14622        // shouldn't be a big deal, if this is being called outside
14623        // of a locked context there is intrinsically a race with
14624        // the value the caller will receive and someone else changing it.
14625        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14626        // we will switch to the calling user if access to the current user fails.
14627        int targetUserId = unsafeConvertIncomingUser(userId);
14628
14629        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14630            final boolean allow;
14631            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14632                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14633                // If the caller has this permission, they always pass go.  And collect $200.
14634                allow = true;
14635            } else if (allowMode == ALLOW_FULL_ONLY) {
14636                // We require full access, sucks to be you.
14637                allow = false;
14638            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14639                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14640                // If the caller does not have either permission, they are always doomed.
14641                allow = false;
14642            } else if (allowMode == ALLOW_NON_FULL) {
14643                // We are blanket allowing non-full access, you lucky caller!
14644                allow = true;
14645            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14646                // We may or may not allow this depending on whether the two users are
14647                // in the same profile.
14648                synchronized (mUserProfileGroupIdsSelfLocked) {
14649                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14650                            UserInfo.NO_PROFILE_GROUP_ID);
14651                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14652                            UserInfo.NO_PROFILE_GROUP_ID);
14653                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14654                            && callingProfile == targetProfile;
14655                }
14656            } else {
14657                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14658            }
14659            if (!allow) {
14660                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14661                    // In this case, they would like to just execute as their
14662                    // owner user instead of failing.
14663                    targetUserId = callingUserId;
14664                } else {
14665                    StringBuilder builder = new StringBuilder(128);
14666                    builder.append("Permission Denial: ");
14667                    builder.append(name);
14668                    if (callerPackage != null) {
14669                        builder.append(" from ");
14670                        builder.append(callerPackage);
14671                    }
14672                    builder.append(" asks to run as user ");
14673                    builder.append(userId);
14674                    builder.append(" but is calling from user ");
14675                    builder.append(UserHandle.getUserId(callingUid));
14676                    builder.append("; this requires ");
14677                    builder.append(INTERACT_ACROSS_USERS_FULL);
14678                    if (allowMode != ALLOW_FULL_ONLY) {
14679                        builder.append(" or ");
14680                        builder.append(INTERACT_ACROSS_USERS);
14681                    }
14682                    String msg = builder.toString();
14683                    Slog.w(TAG, msg);
14684                    throw new SecurityException(msg);
14685                }
14686            }
14687        }
14688        if (!allowAll && targetUserId < 0) {
14689            throw new IllegalArgumentException(
14690                    "Call does not support special user #" + targetUserId);
14691        }
14692        // Check shell permission
14693        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14694            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14695                    targetUserId)) {
14696                throw new SecurityException("Shell does not have permission to access user "
14697                        + targetUserId + "\n " + Debug.getCallers(3));
14698            }
14699        }
14700        return targetUserId;
14701    }
14702
14703    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14704            String className, int flags) {
14705        boolean result = false;
14706        // For apps that don't have pre-defined UIDs, check for permission
14707        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14708            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14709                if (ActivityManager.checkUidPermission(
14710                        INTERACT_ACROSS_USERS,
14711                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14712                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14713                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14714                            + " requests FLAG_SINGLE_USER, but app does not hold "
14715                            + INTERACT_ACROSS_USERS;
14716                    Slog.w(TAG, msg);
14717                    throw new SecurityException(msg);
14718                }
14719                // Permission passed
14720                result = true;
14721            }
14722        } else if ("system".equals(componentProcessName)) {
14723            result = true;
14724        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14725            // Phone app and persistent apps are allowed to export singleuser providers.
14726            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14727                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14728        }
14729        if (DEBUG_MU) {
14730            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14731                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14732        }
14733        return result;
14734    }
14735
14736    /**
14737     * Checks to see if the caller is in the same app as the singleton
14738     * component, or the component is in a special app. It allows special apps
14739     * to export singleton components but prevents exporting singleton
14740     * components for regular apps.
14741     */
14742    boolean isValidSingletonCall(int callingUid, int componentUid) {
14743        int componentAppId = UserHandle.getAppId(componentUid);
14744        return UserHandle.isSameApp(callingUid, componentUid)
14745                || componentAppId == Process.SYSTEM_UID
14746                || componentAppId == Process.PHONE_UID
14747                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14748                        == PackageManager.PERMISSION_GRANTED;
14749    }
14750
14751    public int bindService(IApplicationThread caller, IBinder token,
14752            Intent service, String resolvedType,
14753            IServiceConnection connection, int flags, int userId) {
14754        enforceNotIsolatedCaller("bindService");
14755
14756        // Refuse possible leaked file descriptors
14757        if (service != null && service.hasFileDescriptors() == true) {
14758            throw new IllegalArgumentException("File descriptors passed in Intent");
14759        }
14760
14761        synchronized(this) {
14762            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14763                    connection, flags, userId);
14764        }
14765    }
14766
14767    public boolean unbindService(IServiceConnection connection) {
14768        synchronized (this) {
14769            return mServices.unbindServiceLocked(connection);
14770        }
14771    }
14772
14773    public void publishService(IBinder token, Intent intent, IBinder service) {
14774        // Refuse possible leaked file descriptors
14775        if (intent != null && intent.hasFileDescriptors() == true) {
14776            throw new IllegalArgumentException("File descriptors passed in Intent");
14777        }
14778
14779        synchronized(this) {
14780            if (!(token instanceof ServiceRecord)) {
14781                throw new IllegalArgumentException("Invalid service token");
14782            }
14783            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14784        }
14785    }
14786
14787    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14788        // Refuse possible leaked file descriptors
14789        if (intent != null && intent.hasFileDescriptors() == true) {
14790            throw new IllegalArgumentException("File descriptors passed in Intent");
14791        }
14792
14793        synchronized(this) {
14794            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14795        }
14796    }
14797
14798    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14799        synchronized(this) {
14800            if (!(token instanceof ServiceRecord)) {
14801                throw new IllegalArgumentException("Invalid service token");
14802            }
14803            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14804        }
14805    }
14806
14807    // =========================================================
14808    // BACKUP AND RESTORE
14809    // =========================================================
14810
14811    // Cause the target app to be launched if necessary and its backup agent
14812    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14813    // activity manager to announce its creation.
14814    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14815        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14816        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14817
14818        synchronized(this) {
14819            // !!! TODO: currently no check here that we're already bound
14820            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14821            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14822            synchronized (stats) {
14823                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14824            }
14825
14826            // Backup agent is now in use, its package can't be stopped.
14827            try {
14828                AppGlobals.getPackageManager().setPackageStoppedState(
14829                        app.packageName, false, UserHandle.getUserId(app.uid));
14830            } catch (RemoteException e) {
14831            } catch (IllegalArgumentException e) {
14832                Slog.w(TAG, "Failed trying to unstop package "
14833                        + app.packageName + ": " + e);
14834            }
14835
14836            BackupRecord r = new BackupRecord(ss, app, backupMode);
14837            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14838                    ? new ComponentName(app.packageName, app.backupAgentName)
14839                    : new ComponentName("android", "FullBackupAgent");
14840            // startProcessLocked() returns existing proc's record if it's already running
14841            ProcessRecord proc = startProcessLocked(app.processName, app,
14842                    false, 0, "backup", hostingName, false, false, false);
14843            if (proc == null) {
14844                Slog.e(TAG, "Unable to start backup agent process " + r);
14845                return false;
14846            }
14847
14848            r.app = proc;
14849            mBackupTarget = r;
14850            mBackupAppName = app.packageName;
14851
14852            // Try not to kill the process during backup
14853            updateOomAdjLocked(proc);
14854
14855            // If the process is already attached, schedule the creation of the backup agent now.
14856            // If it is not yet live, this will be done when it attaches to the framework.
14857            if (proc.thread != null) {
14858                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14859                try {
14860                    proc.thread.scheduleCreateBackupAgent(app,
14861                            compatibilityInfoForPackageLocked(app), backupMode);
14862                } catch (RemoteException e) {
14863                    // Will time out on the backup manager side
14864                }
14865            } else {
14866                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14867            }
14868            // Invariants: at this point, the target app process exists and the application
14869            // is either already running or in the process of coming up.  mBackupTarget and
14870            // mBackupAppName describe the app, so that when it binds back to the AM we
14871            // know that it's scheduled for a backup-agent operation.
14872        }
14873
14874        return true;
14875    }
14876
14877    @Override
14878    public void clearPendingBackup() {
14879        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14880        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14881
14882        synchronized (this) {
14883            mBackupTarget = null;
14884            mBackupAppName = null;
14885        }
14886    }
14887
14888    // A backup agent has just come up
14889    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14890        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14891                + " = " + agent);
14892
14893        synchronized(this) {
14894            if (!agentPackageName.equals(mBackupAppName)) {
14895                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14896                return;
14897            }
14898        }
14899
14900        long oldIdent = Binder.clearCallingIdentity();
14901        try {
14902            IBackupManager bm = IBackupManager.Stub.asInterface(
14903                    ServiceManager.getService(Context.BACKUP_SERVICE));
14904            bm.agentConnected(agentPackageName, agent);
14905        } catch (RemoteException e) {
14906            // can't happen; the backup manager service is local
14907        } catch (Exception e) {
14908            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14909            e.printStackTrace();
14910        } finally {
14911            Binder.restoreCallingIdentity(oldIdent);
14912        }
14913    }
14914
14915    // done with this agent
14916    public void unbindBackupAgent(ApplicationInfo appInfo) {
14917        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14918        if (appInfo == null) {
14919            Slog.w(TAG, "unbind backup agent for null app");
14920            return;
14921        }
14922
14923        synchronized(this) {
14924            try {
14925                if (mBackupAppName == null) {
14926                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14927                    return;
14928                }
14929
14930                if (!mBackupAppName.equals(appInfo.packageName)) {
14931                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14932                    return;
14933                }
14934
14935                // Not backing this app up any more; reset its OOM adjustment
14936                final ProcessRecord proc = mBackupTarget.app;
14937                updateOomAdjLocked(proc);
14938
14939                // If the app crashed during backup, 'thread' will be null here
14940                if (proc.thread != null) {
14941                    try {
14942                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14943                                compatibilityInfoForPackageLocked(appInfo));
14944                    } catch (Exception e) {
14945                        Slog.e(TAG, "Exception when unbinding backup agent:");
14946                        e.printStackTrace();
14947                    }
14948                }
14949            } finally {
14950                mBackupTarget = null;
14951                mBackupAppName = null;
14952            }
14953        }
14954    }
14955    // =========================================================
14956    // BROADCASTS
14957    // =========================================================
14958
14959    private final List getStickiesLocked(String action, IntentFilter filter,
14960            List cur, int userId) {
14961        final ContentResolver resolver = mContext.getContentResolver();
14962        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14963        if (stickies == null) {
14964            return cur;
14965        }
14966        final ArrayList<Intent> list = stickies.get(action);
14967        if (list == null) {
14968            return cur;
14969        }
14970        int N = list.size();
14971        for (int i=0; i<N; i++) {
14972            Intent intent = list.get(i);
14973            if (filter.match(resolver, intent, true, TAG) >= 0) {
14974                if (cur == null) {
14975                    cur = new ArrayList<Intent>();
14976                }
14977                cur.add(intent);
14978            }
14979        }
14980        return cur;
14981    }
14982
14983    boolean isPendingBroadcastProcessLocked(int pid) {
14984        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14985                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14986    }
14987
14988    void skipPendingBroadcastLocked(int pid) {
14989            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14990            for (BroadcastQueue queue : mBroadcastQueues) {
14991                queue.skipPendingBroadcastLocked(pid);
14992            }
14993    }
14994
14995    // The app just attached; send any pending broadcasts that it should receive
14996    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14997        boolean didSomething = false;
14998        for (BroadcastQueue queue : mBroadcastQueues) {
14999            didSomething |= queue.sendPendingBroadcastsLocked(app);
15000        }
15001        return didSomething;
15002    }
15003
15004    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15005            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15006        enforceNotIsolatedCaller("registerReceiver");
15007        int callingUid;
15008        int callingPid;
15009        synchronized(this) {
15010            ProcessRecord callerApp = null;
15011            if (caller != null) {
15012                callerApp = getRecordForAppLocked(caller);
15013                if (callerApp == null) {
15014                    throw new SecurityException(
15015                            "Unable to find app for caller " + caller
15016                            + " (pid=" + Binder.getCallingPid()
15017                            + ") when registering receiver " + receiver);
15018                }
15019                if (callerApp.info.uid != Process.SYSTEM_UID &&
15020                        !callerApp.pkgList.containsKey(callerPackage) &&
15021                        !"android".equals(callerPackage)) {
15022                    throw new SecurityException("Given caller package " + callerPackage
15023                            + " is not running in process " + callerApp);
15024                }
15025                callingUid = callerApp.info.uid;
15026                callingPid = callerApp.pid;
15027            } else {
15028                callerPackage = null;
15029                callingUid = Binder.getCallingUid();
15030                callingPid = Binder.getCallingPid();
15031            }
15032
15033            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15034                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15035
15036            List allSticky = null;
15037
15038            // Look for any matching sticky broadcasts...
15039            Iterator actions = filter.actionsIterator();
15040            if (actions != null) {
15041                while (actions.hasNext()) {
15042                    String action = (String)actions.next();
15043                    allSticky = getStickiesLocked(action, filter, allSticky,
15044                            UserHandle.USER_ALL);
15045                    allSticky = getStickiesLocked(action, filter, allSticky,
15046                            UserHandle.getUserId(callingUid));
15047                }
15048            } else {
15049                allSticky = getStickiesLocked(null, filter, allSticky,
15050                        UserHandle.USER_ALL);
15051                allSticky = getStickiesLocked(null, filter, allSticky,
15052                        UserHandle.getUserId(callingUid));
15053            }
15054
15055            // The first sticky in the list is returned directly back to
15056            // the client.
15057            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15058
15059            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15060                    + ": " + sticky);
15061
15062            if (receiver == null) {
15063                return sticky;
15064            }
15065
15066            ReceiverList rl
15067                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15068            if (rl == null) {
15069                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15070                        userId, receiver);
15071                if (rl.app != null) {
15072                    rl.app.receivers.add(rl);
15073                } else {
15074                    try {
15075                        receiver.asBinder().linkToDeath(rl, 0);
15076                    } catch (RemoteException e) {
15077                        return sticky;
15078                    }
15079                    rl.linkedToDeath = true;
15080                }
15081                mRegisteredReceivers.put(receiver.asBinder(), rl);
15082            } else if (rl.uid != callingUid) {
15083                throw new IllegalArgumentException(
15084                        "Receiver requested to register for uid " + callingUid
15085                        + " was previously registered for uid " + rl.uid);
15086            } else if (rl.pid != callingPid) {
15087                throw new IllegalArgumentException(
15088                        "Receiver requested to register for pid " + callingPid
15089                        + " was previously registered for pid " + rl.pid);
15090            } else if (rl.userId != userId) {
15091                throw new IllegalArgumentException(
15092                        "Receiver requested to register for user " + userId
15093                        + " was previously registered for user " + rl.userId);
15094            }
15095            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15096                    permission, callingUid, userId);
15097            rl.add(bf);
15098            if (!bf.debugCheck()) {
15099                Slog.w(TAG, "==> For Dynamic broadast");
15100            }
15101            mReceiverResolver.addFilter(bf);
15102
15103            // Enqueue broadcasts for all existing stickies that match
15104            // this filter.
15105            if (allSticky != null) {
15106                ArrayList receivers = new ArrayList();
15107                receivers.add(bf);
15108
15109                int N = allSticky.size();
15110                for (int i=0; i<N; i++) {
15111                    Intent intent = (Intent)allSticky.get(i);
15112                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15113                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15114                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15115                            null, null, false, true, true, -1);
15116                    queue.enqueueParallelBroadcastLocked(r);
15117                    queue.scheduleBroadcastsLocked();
15118                }
15119            }
15120
15121            return sticky;
15122        }
15123    }
15124
15125    public void unregisterReceiver(IIntentReceiver receiver) {
15126        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15127
15128        final long origId = Binder.clearCallingIdentity();
15129        try {
15130            boolean doTrim = false;
15131
15132            synchronized(this) {
15133                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15134                if (rl != null) {
15135                    if (rl.curBroadcast != null) {
15136                        BroadcastRecord r = rl.curBroadcast;
15137                        final boolean doNext = finishReceiverLocked(
15138                                receiver.asBinder(), r.resultCode, r.resultData,
15139                                r.resultExtras, r.resultAbort);
15140                        if (doNext) {
15141                            doTrim = true;
15142                            r.queue.processNextBroadcast(false);
15143                        }
15144                    }
15145
15146                    if (rl.app != null) {
15147                        rl.app.receivers.remove(rl);
15148                    }
15149                    removeReceiverLocked(rl);
15150                    if (rl.linkedToDeath) {
15151                        rl.linkedToDeath = false;
15152                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15153                    }
15154                }
15155            }
15156
15157            // If we actually concluded any broadcasts, we might now be able
15158            // to trim the recipients' apps from our working set
15159            if (doTrim) {
15160                trimApplications();
15161                return;
15162            }
15163
15164        } finally {
15165            Binder.restoreCallingIdentity(origId);
15166        }
15167    }
15168
15169    void removeReceiverLocked(ReceiverList rl) {
15170        mRegisteredReceivers.remove(rl.receiver.asBinder());
15171        int N = rl.size();
15172        for (int i=0; i<N; i++) {
15173            mReceiverResolver.removeFilter(rl.get(i));
15174        }
15175    }
15176
15177    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15178        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15179            ProcessRecord r = mLruProcesses.get(i);
15180            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15181                try {
15182                    r.thread.dispatchPackageBroadcast(cmd, packages);
15183                } catch (RemoteException ex) {
15184                }
15185            }
15186        }
15187    }
15188
15189    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15190            int callingUid, int[] users) {
15191        List<ResolveInfo> receivers = null;
15192        try {
15193            HashSet<ComponentName> singleUserReceivers = null;
15194            boolean scannedFirstReceivers = false;
15195            for (int user : users) {
15196                // Skip users that have Shell restrictions
15197                if (callingUid == Process.SHELL_UID
15198                        && getUserManagerLocked().hasUserRestriction(
15199                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15200                    continue;
15201                }
15202                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15203                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15204                if (user != 0 && newReceivers != null) {
15205                    // If this is not the primary user, we need to check for
15206                    // any receivers that should be filtered out.
15207                    for (int i=0; i<newReceivers.size(); i++) {
15208                        ResolveInfo ri = newReceivers.get(i);
15209                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15210                            newReceivers.remove(i);
15211                            i--;
15212                        }
15213                    }
15214                }
15215                if (newReceivers != null && newReceivers.size() == 0) {
15216                    newReceivers = null;
15217                }
15218                if (receivers == null) {
15219                    receivers = newReceivers;
15220                } else if (newReceivers != null) {
15221                    // We need to concatenate the additional receivers
15222                    // found with what we have do far.  This would be easy,
15223                    // but we also need to de-dup any receivers that are
15224                    // singleUser.
15225                    if (!scannedFirstReceivers) {
15226                        // Collect any single user receivers we had already retrieved.
15227                        scannedFirstReceivers = true;
15228                        for (int i=0; i<receivers.size(); i++) {
15229                            ResolveInfo ri = receivers.get(i);
15230                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15231                                ComponentName cn = new ComponentName(
15232                                        ri.activityInfo.packageName, ri.activityInfo.name);
15233                                if (singleUserReceivers == null) {
15234                                    singleUserReceivers = new HashSet<ComponentName>();
15235                                }
15236                                singleUserReceivers.add(cn);
15237                            }
15238                        }
15239                    }
15240                    // Add the new results to the existing results, tracking
15241                    // and de-dupping single user receivers.
15242                    for (int i=0; i<newReceivers.size(); i++) {
15243                        ResolveInfo ri = newReceivers.get(i);
15244                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15245                            ComponentName cn = new ComponentName(
15246                                    ri.activityInfo.packageName, ri.activityInfo.name);
15247                            if (singleUserReceivers == null) {
15248                                singleUserReceivers = new HashSet<ComponentName>();
15249                            }
15250                            if (!singleUserReceivers.contains(cn)) {
15251                                singleUserReceivers.add(cn);
15252                                receivers.add(ri);
15253                            }
15254                        } else {
15255                            receivers.add(ri);
15256                        }
15257                    }
15258                }
15259            }
15260        } catch (RemoteException ex) {
15261            // pm is in same process, this will never happen.
15262        }
15263        return receivers;
15264    }
15265
15266    private final int broadcastIntentLocked(ProcessRecord callerApp,
15267            String callerPackage, Intent intent, String resolvedType,
15268            IIntentReceiver resultTo, int resultCode, String resultData,
15269            Bundle map, String requiredPermission, int appOp,
15270            boolean ordered, boolean sticky, int callingPid, int callingUid,
15271            int userId) {
15272        intent = new Intent(intent);
15273
15274        // By default broadcasts do not go to stopped apps.
15275        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15276
15277        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15278            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15279            + " ordered=" + ordered + " userid=" + userId);
15280        if ((resultTo != null) && !ordered) {
15281            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15282        }
15283
15284        userId = handleIncomingUser(callingPid, callingUid, userId,
15285                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15286
15287        // Make sure that the user who is receiving this broadcast is started.
15288        // If not, we will just skip it.
15289
15290        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15291            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15292                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15293                Slog.w(TAG, "Skipping broadcast of " + intent
15294                        + ": user " + userId + " is stopped");
15295                return ActivityManager.BROADCAST_SUCCESS;
15296            }
15297        }
15298
15299        /*
15300         * Prevent non-system code (defined here to be non-persistent
15301         * processes) from sending protected broadcasts.
15302         */
15303        int callingAppId = UserHandle.getAppId(callingUid);
15304        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15305            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15306            || callingAppId == Process.NFC_UID || callingUid == 0) {
15307            // Always okay.
15308        } else if (callerApp == null || !callerApp.persistent) {
15309            try {
15310                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15311                        intent.getAction())) {
15312                    String msg = "Permission Denial: not allowed to send broadcast "
15313                            + intent.getAction() + " from pid="
15314                            + callingPid + ", uid=" + callingUid;
15315                    Slog.w(TAG, msg);
15316                    throw new SecurityException(msg);
15317                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15318                    // Special case for compatibility: we don't want apps to send this,
15319                    // but historically it has not been protected and apps may be using it
15320                    // to poke their own app widget.  So, instead of making it protected,
15321                    // just limit it to the caller.
15322                    if (callerApp == null) {
15323                        String msg = "Permission Denial: not allowed to send broadcast "
15324                                + intent.getAction() + " from unknown caller.";
15325                        Slog.w(TAG, msg);
15326                        throw new SecurityException(msg);
15327                    } else if (intent.getComponent() != null) {
15328                        // They are good enough to send to an explicit component...  verify
15329                        // it is being sent to the calling app.
15330                        if (!intent.getComponent().getPackageName().equals(
15331                                callerApp.info.packageName)) {
15332                            String msg = "Permission Denial: not allowed to send broadcast "
15333                                    + intent.getAction() + " to "
15334                                    + intent.getComponent().getPackageName() + " from "
15335                                    + callerApp.info.packageName;
15336                            Slog.w(TAG, msg);
15337                            throw new SecurityException(msg);
15338                        }
15339                    } else {
15340                        // Limit broadcast to their own package.
15341                        intent.setPackage(callerApp.info.packageName);
15342                    }
15343                }
15344            } catch (RemoteException e) {
15345                Slog.w(TAG, "Remote exception", e);
15346                return ActivityManager.BROADCAST_SUCCESS;
15347            }
15348        }
15349
15350        // Handle special intents: if this broadcast is from the package
15351        // manager about a package being removed, we need to remove all of
15352        // its activities from the history stack.
15353        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15354                intent.getAction());
15355        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15356                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15357                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15358                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15359                || uidRemoved) {
15360            if (checkComponentPermission(
15361                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15362                    callingPid, callingUid, -1, true)
15363                    == PackageManager.PERMISSION_GRANTED) {
15364                if (uidRemoved) {
15365                    final Bundle intentExtras = intent.getExtras();
15366                    final int uid = intentExtras != null
15367                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15368                    if (uid >= 0) {
15369                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15370                        synchronized (bs) {
15371                            bs.removeUidStatsLocked(uid);
15372                        }
15373                        mAppOpsService.uidRemoved(uid);
15374                    }
15375                } else {
15376                    // If resources are unavailable just force stop all
15377                    // those packages and flush the attribute cache as well.
15378                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15379                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15380                        if (list != null && (list.length > 0)) {
15381                            for (String pkg : list) {
15382                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15383                                        "storage unmount");
15384                            }
15385                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15386                            sendPackageBroadcastLocked(
15387                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15388                        }
15389                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15390                            intent.getAction())) {
15391                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15392                    } else {
15393                        Uri data = intent.getData();
15394                        String ssp;
15395                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15396                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15397                                    intent.getAction());
15398                            boolean fullUninstall = removed &&
15399                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15400                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15401                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15402                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15403                                        false, fullUninstall, userId,
15404                                        removed ? "pkg removed" : "pkg changed");
15405                            }
15406                            if (removed) {
15407                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15408                                        new String[] {ssp}, userId);
15409                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15410                                    mAppOpsService.packageRemoved(
15411                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15412
15413                                    // Remove all permissions granted from/to this package
15414                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15415                                }
15416                            }
15417                        }
15418                    }
15419                }
15420            } else {
15421                String msg = "Permission Denial: " + intent.getAction()
15422                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15423                        + ", uid=" + callingUid + ")"
15424                        + " requires "
15425                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15426                Slog.w(TAG, msg);
15427                throw new SecurityException(msg);
15428            }
15429
15430        // Special case for adding a package: by default turn on compatibility
15431        // mode.
15432        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15433            Uri data = intent.getData();
15434            String ssp;
15435            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15436                mCompatModePackages.handlePackageAddedLocked(ssp,
15437                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15438            }
15439        }
15440
15441        /*
15442         * If this is the time zone changed action, queue up a message that will reset the timezone
15443         * of all currently running processes. This message will get queued up before the broadcast
15444         * happens.
15445         */
15446        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15447            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15448        }
15449
15450        /*
15451         * If the user set the time, let all running processes know.
15452         */
15453        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15454            final int is24Hour = intent.getBooleanExtra(
15455                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15456            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15457            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15458            synchronized (stats) {
15459                stats.noteCurrentTimeChangedLocked();
15460            }
15461        }
15462
15463        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15464            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15465        }
15466
15467        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15468            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15469            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15470        }
15471
15472        // Add to the sticky list if requested.
15473        if (sticky) {
15474            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15475                    callingPid, callingUid)
15476                    != PackageManager.PERMISSION_GRANTED) {
15477                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15478                        + callingPid + ", uid=" + callingUid
15479                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15480                Slog.w(TAG, msg);
15481                throw new SecurityException(msg);
15482            }
15483            if (requiredPermission != null) {
15484                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15485                        + " and enforce permission " + requiredPermission);
15486                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15487            }
15488            if (intent.getComponent() != null) {
15489                throw new SecurityException(
15490                        "Sticky broadcasts can't target a specific component");
15491            }
15492            // We use userId directly here, since the "all" target is maintained
15493            // as a separate set of sticky broadcasts.
15494            if (userId != UserHandle.USER_ALL) {
15495                // But first, if this is not a broadcast to all users, then
15496                // make sure it doesn't conflict with an existing broadcast to
15497                // all users.
15498                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15499                        UserHandle.USER_ALL);
15500                if (stickies != null) {
15501                    ArrayList<Intent> list = stickies.get(intent.getAction());
15502                    if (list != null) {
15503                        int N = list.size();
15504                        int i;
15505                        for (i=0; i<N; i++) {
15506                            if (intent.filterEquals(list.get(i))) {
15507                                throw new IllegalArgumentException(
15508                                        "Sticky broadcast " + intent + " for user "
15509                                        + userId + " conflicts with existing global broadcast");
15510                            }
15511                        }
15512                    }
15513                }
15514            }
15515            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15516            if (stickies == null) {
15517                stickies = new ArrayMap<String, ArrayList<Intent>>();
15518                mStickyBroadcasts.put(userId, stickies);
15519            }
15520            ArrayList<Intent> list = stickies.get(intent.getAction());
15521            if (list == null) {
15522                list = new ArrayList<Intent>();
15523                stickies.put(intent.getAction(), list);
15524            }
15525            int N = list.size();
15526            int i;
15527            for (i=0; i<N; i++) {
15528                if (intent.filterEquals(list.get(i))) {
15529                    // This sticky already exists, replace it.
15530                    list.set(i, new Intent(intent));
15531                    break;
15532                }
15533            }
15534            if (i >= N) {
15535                list.add(new Intent(intent));
15536            }
15537        }
15538
15539        int[] users;
15540        if (userId == UserHandle.USER_ALL) {
15541            // Caller wants broadcast to go to all started users.
15542            users = mStartedUserArray;
15543        } else {
15544            // Caller wants broadcast to go to one specific user.
15545            users = new int[] {userId};
15546        }
15547
15548        // Figure out who all will receive this broadcast.
15549        List receivers = null;
15550        List<BroadcastFilter> registeredReceivers = null;
15551        // Need to resolve the intent to interested receivers...
15552        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15553                 == 0) {
15554            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15555        }
15556        if (intent.getComponent() == null) {
15557            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15558                // Query one target user at a time, excluding shell-restricted users
15559                UserManagerService ums = getUserManagerLocked();
15560                for (int i = 0; i < users.length; i++) {
15561                    if (ums.hasUserRestriction(
15562                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15563                        continue;
15564                    }
15565                    List<BroadcastFilter> registeredReceiversForUser =
15566                            mReceiverResolver.queryIntent(intent,
15567                                    resolvedType, false, users[i]);
15568                    if (registeredReceivers == null) {
15569                        registeredReceivers = registeredReceiversForUser;
15570                    } else if (registeredReceiversForUser != null) {
15571                        registeredReceivers.addAll(registeredReceiversForUser);
15572                    }
15573                }
15574            } else {
15575                registeredReceivers = mReceiverResolver.queryIntent(intent,
15576                        resolvedType, false, userId);
15577            }
15578        }
15579
15580        final boolean replacePending =
15581                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15582
15583        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15584                + " replacePending=" + replacePending);
15585
15586        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15587        if (!ordered && NR > 0) {
15588            // If we are not serializing this broadcast, then send the
15589            // registered receivers separately so they don't wait for the
15590            // components to be launched.
15591            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15592            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15593                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15594                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15595                    ordered, sticky, false, userId);
15596            if (DEBUG_BROADCAST) Slog.v(
15597                    TAG, "Enqueueing parallel broadcast " + r);
15598            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15599            if (!replaced) {
15600                queue.enqueueParallelBroadcastLocked(r);
15601                queue.scheduleBroadcastsLocked();
15602            }
15603            registeredReceivers = null;
15604            NR = 0;
15605        }
15606
15607        // Merge into one list.
15608        int ir = 0;
15609        if (receivers != null) {
15610            // A special case for PACKAGE_ADDED: do not allow the package
15611            // being added to see this broadcast.  This prevents them from
15612            // using this as a back door to get run as soon as they are
15613            // installed.  Maybe in the future we want to have a special install
15614            // broadcast or such for apps, but we'd like to deliberately make
15615            // this decision.
15616            String skipPackages[] = null;
15617            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15618                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15619                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15620                Uri data = intent.getData();
15621                if (data != null) {
15622                    String pkgName = data.getSchemeSpecificPart();
15623                    if (pkgName != null) {
15624                        skipPackages = new String[] { pkgName };
15625                    }
15626                }
15627            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15628                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15629            }
15630            if (skipPackages != null && (skipPackages.length > 0)) {
15631                for (String skipPackage : skipPackages) {
15632                    if (skipPackage != null) {
15633                        int NT = receivers.size();
15634                        for (int it=0; it<NT; it++) {
15635                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15636                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15637                                receivers.remove(it);
15638                                it--;
15639                                NT--;
15640                            }
15641                        }
15642                    }
15643                }
15644            }
15645
15646            int NT = receivers != null ? receivers.size() : 0;
15647            int it = 0;
15648            ResolveInfo curt = null;
15649            BroadcastFilter curr = null;
15650            while (it < NT && ir < NR) {
15651                if (curt == null) {
15652                    curt = (ResolveInfo)receivers.get(it);
15653                }
15654                if (curr == null) {
15655                    curr = registeredReceivers.get(ir);
15656                }
15657                if (curr.getPriority() >= curt.priority) {
15658                    // Insert this broadcast record into the final list.
15659                    receivers.add(it, curr);
15660                    ir++;
15661                    curr = null;
15662                    it++;
15663                    NT++;
15664                } else {
15665                    // Skip to the next ResolveInfo in the final list.
15666                    it++;
15667                    curt = null;
15668                }
15669            }
15670        }
15671        while (ir < NR) {
15672            if (receivers == null) {
15673                receivers = new ArrayList();
15674            }
15675            receivers.add(registeredReceivers.get(ir));
15676            ir++;
15677        }
15678
15679        if ((receivers != null && receivers.size() > 0)
15680                || resultTo != null) {
15681            BroadcastQueue queue = broadcastQueueForIntent(intent);
15682            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15683                    callerPackage, callingPid, callingUid, resolvedType,
15684                    requiredPermission, appOp, receivers, resultTo, resultCode,
15685                    resultData, map, ordered, sticky, false, userId);
15686            if (DEBUG_BROADCAST) Slog.v(
15687                    TAG, "Enqueueing ordered broadcast " + r
15688                    + ": prev had " + queue.mOrderedBroadcasts.size());
15689            if (DEBUG_BROADCAST) {
15690                int seq = r.intent.getIntExtra("seq", -1);
15691                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15692            }
15693            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15694            if (!replaced) {
15695                queue.enqueueOrderedBroadcastLocked(r);
15696                queue.scheduleBroadcastsLocked();
15697            }
15698        }
15699
15700        return ActivityManager.BROADCAST_SUCCESS;
15701    }
15702
15703    final Intent verifyBroadcastLocked(Intent intent) {
15704        // Refuse possible leaked file descriptors
15705        if (intent != null && intent.hasFileDescriptors() == true) {
15706            throw new IllegalArgumentException("File descriptors passed in Intent");
15707        }
15708
15709        int flags = intent.getFlags();
15710
15711        if (!mProcessesReady) {
15712            // if the caller really truly claims to know what they're doing, go
15713            // ahead and allow the broadcast without launching any receivers
15714            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15715                intent = new Intent(intent);
15716                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15717            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15718                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15719                        + " before boot completion");
15720                throw new IllegalStateException("Cannot broadcast before boot completed");
15721            }
15722        }
15723
15724        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15725            throw new IllegalArgumentException(
15726                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15727        }
15728
15729        return intent;
15730    }
15731
15732    public final int broadcastIntent(IApplicationThread caller,
15733            Intent intent, String resolvedType, IIntentReceiver resultTo,
15734            int resultCode, String resultData, Bundle map,
15735            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15736        enforceNotIsolatedCaller("broadcastIntent");
15737        synchronized(this) {
15738            intent = verifyBroadcastLocked(intent);
15739
15740            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15741            final int callingPid = Binder.getCallingPid();
15742            final int callingUid = Binder.getCallingUid();
15743            final long origId = Binder.clearCallingIdentity();
15744            int res = broadcastIntentLocked(callerApp,
15745                    callerApp != null ? callerApp.info.packageName : null,
15746                    intent, resolvedType, resultTo,
15747                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15748                    callingPid, callingUid, userId);
15749            Binder.restoreCallingIdentity(origId);
15750            return res;
15751        }
15752    }
15753
15754    int broadcastIntentInPackage(String packageName, int uid,
15755            Intent intent, String resolvedType, IIntentReceiver resultTo,
15756            int resultCode, String resultData, Bundle map,
15757            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15758        synchronized(this) {
15759            intent = verifyBroadcastLocked(intent);
15760
15761            final long origId = Binder.clearCallingIdentity();
15762            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15763                    resultTo, resultCode, resultData, map, requiredPermission,
15764                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15765            Binder.restoreCallingIdentity(origId);
15766            return res;
15767        }
15768    }
15769
15770    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15771        // Refuse possible leaked file descriptors
15772        if (intent != null && intent.hasFileDescriptors() == true) {
15773            throw new IllegalArgumentException("File descriptors passed in Intent");
15774        }
15775
15776        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15777                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15778
15779        synchronized(this) {
15780            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15781                    != PackageManager.PERMISSION_GRANTED) {
15782                String msg = "Permission Denial: unbroadcastIntent() from pid="
15783                        + Binder.getCallingPid()
15784                        + ", uid=" + Binder.getCallingUid()
15785                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15786                Slog.w(TAG, msg);
15787                throw new SecurityException(msg);
15788            }
15789            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15790            if (stickies != null) {
15791                ArrayList<Intent> list = stickies.get(intent.getAction());
15792                if (list != null) {
15793                    int N = list.size();
15794                    int i;
15795                    for (i=0; i<N; i++) {
15796                        if (intent.filterEquals(list.get(i))) {
15797                            list.remove(i);
15798                            break;
15799                        }
15800                    }
15801                    if (list.size() <= 0) {
15802                        stickies.remove(intent.getAction());
15803                    }
15804                }
15805                if (stickies.size() <= 0) {
15806                    mStickyBroadcasts.remove(userId);
15807                }
15808            }
15809        }
15810    }
15811
15812    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15813            String resultData, Bundle resultExtras, boolean resultAbort) {
15814        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15815        if (r == null) {
15816            Slog.w(TAG, "finishReceiver called but not found on queue");
15817            return false;
15818        }
15819
15820        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15821    }
15822
15823    void backgroundServicesFinishedLocked(int userId) {
15824        for (BroadcastQueue queue : mBroadcastQueues) {
15825            queue.backgroundServicesFinishedLocked(userId);
15826        }
15827    }
15828
15829    public void finishReceiver(IBinder who, int resultCode, String resultData,
15830            Bundle resultExtras, boolean resultAbort) {
15831        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15832
15833        // Refuse possible leaked file descriptors
15834        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15835            throw new IllegalArgumentException("File descriptors passed in Bundle");
15836        }
15837
15838        final long origId = Binder.clearCallingIdentity();
15839        try {
15840            boolean doNext = false;
15841            BroadcastRecord r;
15842
15843            synchronized(this) {
15844                r = broadcastRecordForReceiverLocked(who);
15845                if (r != null) {
15846                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15847                        resultData, resultExtras, resultAbort, true);
15848                }
15849            }
15850
15851            if (doNext) {
15852                r.queue.processNextBroadcast(false);
15853            }
15854            trimApplications();
15855        } finally {
15856            Binder.restoreCallingIdentity(origId);
15857        }
15858    }
15859
15860    // =========================================================
15861    // INSTRUMENTATION
15862    // =========================================================
15863
15864    public boolean startInstrumentation(ComponentName className,
15865            String profileFile, int flags, Bundle arguments,
15866            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15867            int userId, String abiOverride) {
15868        enforceNotIsolatedCaller("startInstrumentation");
15869        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15870                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15871        // Refuse possible leaked file descriptors
15872        if (arguments != null && arguments.hasFileDescriptors()) {
15873            throw new IllegalArgumentException("File descriptors passed in Bundle");
15874        }
15875
15876        synchronized(this) {
15877            InstrumentationInfo ii = null;
15878            ApplicationInfo ai = null;
15879            try {
15880                ii = mContext.getPackageManager().getInstrumentationInfo(
15881                    className, STOCK_PM_FLAGS);
15882                ai = AppGlobals.getPackageManager().getApplicationInfo(
15883                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15884            } catch (PackageManager.NameNotFoundException e) {
15885            } catch (RemoteException e) {
15886            }
15887            if (ii == null) {
15888                reportStartInstrumentationFailure(watcher, className,
15889                        "Unable to find instrumentation info for: " + className);
15890                return false;
15891            }
15892            if (ai == null) {
15893                reportStartInstrumentationFailure(watcher, className,
15894                        "Unable to find instrumentation target package: " + ii.targetPackage);
15895                return false;
15896            }
15897
15898            int match = mContext.getPackageManager().checkSignatures(
15899                    ii.targetPackage, ii.packageName);
15900            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15901                String msg = "Permission Denial: starting instrumentation "
15902                        + className + " from pid="
15903                        + Binder.getCallingPid()
15904                        + ", uid=" + Binder.getCallingPid()
15905                        + " not allowed because package " + ii.packageName
15906                        + " does not have a signature matching the target "
15907                        + ii.targetPackage;
15908                reportStartInstrumentationFailure(watcher, className, msg);
15909                throw new SecurityException(msg);
15910            }
15911
15912            final long origId = Binder.clearCallingIdentity();
15913            // Instrumentation can kill and relaunch even persistent processes
15914            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15915                    "start instr");
15916            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15917            app.instrumentationClass = className;
15918            app.instrumentationInfo = ai;
15919            app.instrumentationProfileFile = profileFile;
15920            app.instrumentationArguments = arguments;
15921            app.instrumentationWatcher = watcher;
15922            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15923            app.instrumentationResultClass = className;
15924            Binder.restoreCallingIdentity(origId);
15925        }
15926
15927        return true;
15928    }
15929
15930    /**
15931     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15932     * error to the logs, but if somebody is watching, send the report there too.  This enables
15933     * the "am" command to report errors with more information.
15934     *
15935     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15936     * @param cn The component name of the instrumentation.
15937     * @param report The error report.
15938     */
15939    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15940            ComponentName cn, String report) {
15941        Slog.w(TAG, report);
15942        try {
15943            if (watcher != null) {
15944                Bundle results = new Bundle();
15945                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15946                results.putString("Error", report);
15947                watcher.instrumentationStatus(cn, -1, results);
15948            }
15949        } catch (RemoteException e) {
15950            Slog.w(TAG, e);
15951        }
15952    }
15953
15954    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15955        if (app.instrumentationWatcher != null) {
15956            try {
15957                // NOTE:  IInstrumentationWatcher *must* be oneway here
15958                app.instrumentationWatcher.instrumentationFinished(
15959                    app.instrumentationClass,
15960                    resultCode,
15961                    results);
15962            } catch (RemoteException e) {
15963            }
15964        }
15965        if (app.instrumentationUiAutomationConnection != null) {
15966            try {
15967                app.instrumentationUiAutomationConnection.shutdown();
15968            } catch (RemoteException re) {
15969                /* ignore */
15970            }
15971            // Only a UiAutomation can set this flag and now that
15972            // it is finished we make sure it is reset to its default.
15973            mUserIsMonkey = false;
15974        }
15975        app.instrumentationWatcher = null;
15976        app.instrumentationUiAutomationConnection = null;
15977        app.instrumentationClass = null;
15978        app.instrumentationInfo = null;
15979        app.instrumentationProfileFile = null;
15980        app.instrumentationArguments = null;
15981
15982        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15983                "finished inst");
15984    }
15985
15986    public void finishInstrumentation(IApplicationThread target,
15987            int resultCode, Bundle results) {
15988        int userId = UserHandle.getCallingUserId();
15989        // Refuse possible leaked file descriptors
15990        if (results != null && results.hasFileDescriptors()) {
15991            throw new IllegalArgumentException("File descriptors passed in Intent");
15992        }
15993
15994        synchronized(this) {
15995            ProcessRecord app = getRecordForAppLocked(target);
15996            if (app == null) {
15997                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15998                return;
15999            }
16000            final long origId = Binder.clearCallingIdentity();
16001            finishInstrumentationLocked(app, resultCode, results);
16002            Binder.restoreCallingIdentity(origId);
16003        }
16004    }
16005
16006    // =========================================================
16007    // CONFIGURATION
16008    // =========================================================
16009
16010    public ConfigurationInfo getDeviceConfigurationInfo() {
16011        ConfigurationInfo config = new ConfigurationInfo();
16012        synchronized (this) {
16013            config.reqTouchScreen = mConfiguration.touchscreen;
16014            config.reqKeyboardType = mConfiguration.keyboard;
16015            config.reqNavigation = mConfiguration.navigation;
16016            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16017                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16018                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16019            }
16020            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16021                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16022                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16023            }
16024            config.reqGlEsVersion = GL_ES_VERSION;
16025        }
16026        return config;
16027    }
16028
16029    ActivityStack getFocusedStack() {
16030        return mStackSupervisor.getFocusedStack();
16031    }
16032
16033    public Configuration getConfiguration() {
16034        Configuration ci;
16035        synchronized(this) {
16036            ci = new Configuration(mConfiguration);
16037        }
16038        return ci;
16039    }
16040
16041    public void updatePersistentConfiguration(Configuration values) {
16042        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16043                "updateConfiguration()");
16044        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16045                "updateConfiguration()");
16046        if (values == null) {
16047            throw new NullPointerException("Configuration must not be null");
16048        }
16049
16050        synchronized(this) {
16051            final long origId = Binder.clearCallingIdentity();
16052            updateConfigurationLocked(values, null, true, false);
16053            Binder.restoreCallingIdentity(origId);
16054        }
16055    }
16056
16057    public void updateConfiguration(Configuration values) {
16058        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16059                "updateConfiguration()");
16060
16061        synchronized(this) {
16062            if (values == null && mWindowManager != null) {
16063                // sentinel: fetch the current configuration from the window manager
16064                values = mWindowManager.computeNewConfiguration();
16065            }
16066
16067            if (mWindowManager != null) {
16068                mProcessList.applyDisplaySize(mWindowManager);
16069            }
16070
16071            final long origId = Binder.clearCallingIdentity();
16072            if (values != null) {
16073                Settings.System.clearConfiguration(values);
16074            }
16075            updateConfigurationLocked(values, null, false, false);
16076            Binder.restoreCallingIdentity(origId);
16077        }
16078    }
16079
16080    /**
16081     * Do either or both things: (1) change the current configuration, and (2)
16082     * make sure the given activity is running with the (now) current
16083     * configuration.  Returns true if the activity has been left running, or
16084     * false if <var>starting</var> is being destroyed to match the new
16085     * configuration.
16086     * @param persistent TODO
16087     */
16088    boolean updateConfigurationLocked(Configuration values,
16089            ActivityRecord starting, boolean persistent, boolean initLocale) {
16090        int changes = 0;
16091
16092        if (values != null) {
16093            Configuration newConfig = new Configuration(mConfiguration);
16094            changes = newConfig.updateFrom(values);
16095            if (changes != 0) {
16096                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16097                    Slog.i(TAG, "Updating configuration to: " + values);
16098                }
16099
16100                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16101
16102                if (values.locale != null && !initLocale) {
16103                    saveLocaleLocked(values.locale,
16104                                     !values.locale.equals(mConfiguration.locale),
16105                                     values.userSetLocale);
16106                }
16107
16108                mConfigurationSeq++;
16109                if (mConfigurationSeq <= 0) {
16110                    mConfigurationSeq = 1;
16111                }
16112                newConfig.seq = mConfigurationSeq;
16113                mConfiguration = newConfig;
16114                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16115                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16116                //mUsageStatsService.noteStartConfig(newConfig);
16117
16118                final Configuration configCopy = new Configuration(mConfiguration);
16119
16120                // TODO: If our config changes, should we auto dismiss any currently
16121                // showing dialogs?
16122                mShowDialogs = shouldShowDialogs(newConfig);
16123
16124                AttributeCache ac = AttributeCache.instance();
16125                if (ac != null) {
16126                    ac.updateConfiguration(configCopy);
16127                }
16128
16129                // Make sure all resources in our process are updated
16130                // right now, so that anyone who is going to retrieve
16131                // resource values after we return will be sure to get
16132                // the new ones.  This is especially important during
16133                // boot, where the first config change needs to guarantee
16134                // all resources have that config before following boot
16135                // code is executed.
16136                mSystemThread.applyConfigurationToResources(configCopy);
16137
16138                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16139                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16140                    msg.obj = new Configuration(configCopy);
16141                    mHandler.sendMessage(msg);
16142                }
16143
16144                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16145                    ProcessRecord app = mLruProcesses.get(i);
16146                    try {
16147                        if (app.thread != null) {
16148                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16149                                    + app.processName + " new config " + mConfiguration);
16150                            app.thread.scheduleConfigurationChanged(configCopy);
16151                        }
16152                    } catch (Exception e) {
16153                    }
16154                }
16155                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16156                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16157                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16158                        | Intent.FLAG_RECEIVER_FOREGROUND);
16159                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16160                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16161                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16162                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16163                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16164                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16165                    broadcastIntentLocked(null, null, intent,
16166                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16167                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16168                }
16169            }
16170        }
16171
16172        boolean kept = true;
16173        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16174        // mainStack is null during startup.
16175        if (mainStack != null) {
16176            if (changes != 0 && starting == null) {
16177                // If the configuration changed, and the caller is not already
16178                // in the process of starting an activity, then find the top
16179                // activity to check if its configuration needs to change.
16180                starting = mainStack.topRunningActivityLocked(null);
16181            }
16182
16183            if (starting != null) {
16184                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16185                // And we need to make sure at this point that all other activities
16186                // are made visible with the correct configuration.
16187                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16188            }
16189        }
16190
16191        if (values != null && mWindowManager != null) {
16192            mWindowManager.setNewConfiguration(mConfiguration);
16193        }
16194
16195        return kept;
16196    }
16197
16198    /**
16199     * Decide based on the configuration whether we should shouw the ANR,
16200     * crash, etc dialogs.  The idea is that if there is no affordnace to
16201     * press the on-screen buttons, we shouldn't show the dialog.
16202     *
16203     * A thought: SystemUI might also want to get told about this, the Power
16204     * dialog / global actions also might want different behaviors.
16205     */
16206    private static final boolean shouldShowDialogs(Configuration config) {
16207        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16208                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16209    }
16210
16211    /**
16212     * Save the locale.  You must be inside a synchronized (this) block.
16213     */
16214    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16215        if(isDiff) {
16216            SystemProperties.set("user.language", l.getLanguage());
16217            SystemProperties.set("user.region", l.getCountry());
16218        }
16219
16220        if(isPersist) {
16221            SystemProperties.set("persist.sys.language", l.getLanguage());
16222            SystemProperties.set("persist.sys.country", l.getCountry());
16223            SystemProperties.set("persist.sys.localevar", l.getVariant());
16224        }
16225    }
16226
16227    @Override
16228    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16229        synchronized (this) {
16230            ActivityRecord srec = ActivityRecord.forToken(token);
16231            if (srec.task != null && srec.task.stack != null) {
16232                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16233            }
16234        }
16235        return false;
16236    }
16237
16238    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16239            Intent resultData) {
16240
16241        synchronized (this) {
16242            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16243            if (stack != null) {
16244                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16245            }
16246            return false;
16247        }
16248    }
16249
16250    public int getLaunchedFromUid(IBinder activityToken) {
16251        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16252        if (srec == null) {
16253            return -1;
16254        }
16255        return srec.launchedFromUid;
16256    }
16257
16258    public String getLaunchedFromPackage(IBinder activityToken) {
16259        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16260        if (srec == null) {
16261            return null;
16262        }
16263        return srec.launchedFromPackage;
16264    }
16265
16266    // =========================================================
16267    // LIFETIME MANAGEMENT
16268    // =========================================================
16269
16270    // Returns which broadcast queue the app is the current [or imminent] receiver
16271    // on, or 'null' if the app is not an active broadcast recipient.
16272    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16273        BroadcastRecord r = app.curReceiver;
16274        if (r != null) {
16275            return r.queue;
16276        }
16277
16278        // It's not the current receiver, but it might be starting up to become one
16279        synchronized (this) {
16280            for (BroadcastQueue queue : mBroadcastQueues) {
16281                r = queue.mPendingBroadcast;
16282                if (r != null && r.curApp == app) {
16283                    // found it; report which queue it's in
16284                    return queue;
16285                }
16286            }
16287        }
16288
16289        return null;
16290    }
16291
16292    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16293            boolean doingAll, long now) {
16294        if (mAdjSeq == app.adjSeq) {
16295            // This adjustment has already been computed.
16296            return app.curRawAdj;
16297        }
16298
16299        if (app.thread == null) {
16300            app.adjSeq = mAdjSeq;
16301            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16302            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16303            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16304        }
16305
16306        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16307        app.adjSource = null;
16308        app.adjTarget = null;
16309        app.empty = false;
16310        app.cached = false;
16311
16312        final int activitiesSize = app.activities.size();
16313
16314        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16315            // The max adjustment doesn't allow this app to be anything
16316            // below foreground, so it is not worth doing work for it.
16317            app.adjType = "fixed";
16318            app.adjSeq = mAdjSeq;
16319            app.curRawAdj = app.maxAdj;
16320            app.foregroundActivities = false;
16321            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16322            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16323            // System processes can do UI, and when they do we want to have
16324            // them trim their memory after the user leaves the UI.  To
16325            // facilitate this, here we need to determine whether or not it
16326            // is currently showing UI.
16327            app.systemNoUi = true;
16328            if (app == TOP_APP) {
16329                app.systemNoUi = false;
16330            } else if (activitiesSize > 0) {
16331                for (int j = 0; j < activitiesSize; j++) {
16332                    final ActivityRecord r = app.activities.get(j);
16333                    if (r.visible) {
16334                        app.systemNoUi = false;
16335                    }
16336                }
16337            }
16338            if (!app.systemNoUi) {
16339                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16340            }
16341            return (app.curAdj=app.maxAdj);
16342        }
16343
16344        app.systemNoUi = false;
16345
16346        // Determine the importance of the process, starting with most
16347        // important to least, and assign an appropriate OOM adjustment.
16348        int adj;
16349        int schedGroup;
16350        int procState;
16351        boolean foregroundActivities = false;
16352        BroadcastQueue queue;
16353        if (app == TOP_APP) {
16354            // The last app on the list is the foreground app.
16355            adj = ProcessList.FOREGROUND_APP_ADJ;
16356            schedGroup = Process.THREAD_GROUP_DEFAULT;
16357            app.adjType = "top-activity";
16358            foregroundActivities = true;
16359            procState = ActivityManager.PROCESS_STATE_TOP;
16360        } else if (app.instrumentationClass != null) {
16361            // Don't want to kill running instrumentation.
16362            adj = ProcessList.FOREGROUND_APP_ADJ;
16363            schedGroup = Process.THREAD_GROUP_DEFAULT;
16364            app.adjType = "instrumentation";
16365            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16366        } else if ((queue = isReceivingBroadcast(app)) != null) {
16367            // An app that is currently receiving a broadcast also
16368            // counts as being in the foreground for OOM killer purposes.
16369            // It's placed in a sched group based on the nature of the
16370            // broadcast as reflected by which queue it's active in.
16371            adj = ProcessList.FOREGROUND_APP_ADJ;
16372            schedGroup = (queue == mFgBroadcastQueue)
16373                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16374            app.adjType = "broadcast";
16375            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16376        } else if (app.executingServices.size() > 0) {
16377            // An app that is currently executing a service callback also
16378            // counts as being in the foreground.
16379            adj = ProcessList.FOREGROUND_APP_ADJ;
16380            schedGroup = app.execServicesFg ?
16381                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16382            app.adjType = "exec-service";
16383            procState = ActivityManager.PROCESS_STATE_SERVICE;
16384            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16385        } else {
16386            // As far as we know the process is empty.  We may change our mind later.
16387            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16388            // At this point we don't actually know the adjustment.  Use the cached adj
16389            // value that the caller wants us to.
16390            adj = cachedAdj;
16391            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16392            app.cached = true;
16393            app.empty = true;
16394            app.adjType = "cch-empty";
16395        }
16396
16397        // Examine all activities if not already foreground.
16398        if (!foregroundActivities && activitiesSize > 0) {
16399            for (int j = 0; j < activitiesSize; j++) {
16400                final ActivityRecord r = app.activities.get(j);
16401                if (r.app != app) {
16402                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16403                            + app + "?!?");
16404                    continue;
16405                }
16406                if (r.visible) {
16407                    // App has a visible activity; only upgrade adjustment.
16408                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16409                        adj = ProcessList.VISIBLE_APP_ADJ;
16410                        app.adjType = "visible";
16411                    }
16412                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16413                        procState = ActivityManager.PROCESS_STATE_TOP;
16414                    }
16415                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16416                    app.cached = false;
16417                    app.empty = false;
16418                    foregroundActivities = true;
16419                    break;
16420                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16421                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16422                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16423                        app.adjType = "pausing";
16424                    }
16425                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16426                        procState = ActivityManager.PROCESS_STATE_TOP;
16427                    }
16428                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16429                    app.cached = false;
16430                    app.empty = false;
16431                    foregroundActivities = true;
16432                } else if (r.state == ActivityState.STOPPING) {
16433                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16434                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16435                        app.adjType = "stopping";
16436                    }
16437                    // For the process state, we will at this point consider the
16438                    // process to be cached.  It will be cached either as an activity
16439                    // or empty depending on whether the activity is finishing.  We do
16440                    // this so that we can treat the process as cached for purposes of
16441                    // memory trimming (determing current memory level, trim command to
16442                    // send to process) since there can be an arbitrary number of stopping
16443                    // processes and they should soon all go into the cached state.
16444                    if (!r.finishing) {
16445                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16446                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16447                        }
16448                    }
16449                    app.cached = false;
16450                    app.empty = false;
16451                    foregroundActivities = true;
16452                } else {
16453                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16454                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16455                        app.adjType = "cch-act";
16456                    }
16457                }
16458            }
16459        }
16460
16461        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16462            if (app.foregroundServices) {
16463                // The user is aware of this app, so make it visible.
16464                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16465                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16466                app.cached = false;
16467                app.adjType = "fg-service";
16468                schedGroup = Process.THREAD_GROUP_DEFAULT;
16469            } else if (app.forcingToForeground != null) {
16470                // The user is aware of this app, so make it visible.
16471                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16472                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16473                app.cached = false;
16474                app.adjType = "force-fg";
16475                app.adjSource = app.forcingToForeground;
16476                schedGroup = Process.THREAD_GROUP_DEFAULT;
16477            }
16478        }
16479
16480        if (app == mHeavyWeightProcess) {
16481            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16482                // We don't want to kill the current heavy-weight process.
16483                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16484                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16485                app.cached = false;
16486                app.adjType = "heavy";
16487            }
16488            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16489                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16490            }
16491        }
16492
16493        if (app == mHomeProcess) {
16494            if (adj > ProcessList.HOME_APP_ADJ) {
16495                // This process is hosting what we currently consider to be the
16496                // home app, so we don't want to let it go into the background.
16497                adj = ProcessList.HOME_APP_ADJ;
16498                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16499                app.cached = false;
16500                app.adjType = "home";
16501            }
16502            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16503                procState = ActivityManager.PROCESS_STATE_HOME;
16504            }
16505        }
16506
16507        if (app == mPreviousProcess && app.activities.size() > 0) {
16508            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16509                // This was the previous process that showed UI to the user.
16510                // We want to try to keep it around more aggressively, to give
16511                // a good experience around switching between two apps.
16512                adj = ProcessList.PREVIOUS_APP_ADJ;
16513                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16514                app.cached = false;
16515                app.adjType = "previous";
16516            }
16517            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16518                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16519            }
16520        }
16521
16522        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16523                + " reason=" + app.adjType);
16524
16525        // By default, we use the computed adjustment.  It may be changed if
16526        // there are applications dependent on our services or providers, but
16527        // this gives us a baseline and makes sure we don't get into an
16528        // infinite recursion.
16529        app.adjSeq = mAdjSeq;
16530        app.curRawAdj = adj;
16531        app.hasStartedServices = false;
16532
16533        if (mBackupTarget != null && app == mBackupTarget.app) {
16534            // If possible we want to avoid killing apps while they're being backed up
16535            if (adj > ProcessList.BACKUP_APP_ADJ) {
16536                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16537                adj = ProcessList.BACKUP_APP_ADJ;
16538                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16539                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16540                }
16541                app.adjType = "backup";
16542                app.cached = false;
16543            }
16544            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16545                procState = ActivityManager.PROCESS_STATE_BACKUP;
16546            }
16547        }
16548
16549        boolean mayBeTop = false;
16550
16551        for (int is = app.services.size()-1;
16552                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16553                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16554                        || procState > ActivityManager.PROCESS_STATE_TOP);
16555                is--) {
16556            ServiceRecord s = app.services.valueAt(is);
16557            if (s.startRequested) {
16558                app.hasStartedServices = true;
16559                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16560                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16561                }
16562                if (app.hasShownUi && app != mHomeProcess) {
16563                    // If this process has shown some UI, let it immediately
16564                    // go to the LRU list because it may be pretty heavy with
16565                    // UI stuff.  We'll tag it with a label just to help
16566                    // debug and understand what is going on.
16567                    if (adj > ProcessList.SERVICE_ADJ) {
16568                        app.adjType = "cch-started-ui-services";
16569                    }
16570                } else {
16571                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16572                        // This service has seen some activity within
16573                        // recent memory, so we will keep its process ahead
16574                        // of the background processes.
16575                        if (adj > ProcessList.SERVICE_ADJ) {
16576                            adj = ProcessList.SERVICE_ADJ;
16577                            app.adjType = "started-services";
16578                            app.cached = false;
16579                        }
16580                    }
16581                    // If we have let the service slide into the background
16582                    // state, still have some text describing what it is doing
16583                    // even though the service no longer has an impact.
16584                    if (adj > ProcessList.SERVICE_ADJ) {
16585                        app.adjType = "cch-started-services";
16586                    }
16587                }
16588            }
16589            for (int conni = s.connections.size()-1;
16590                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16591                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16592                            || procState > ActivityManager.PROCESS_STATE_TOP);
16593                    conni--) {
16594                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16595                for (int i = 0;
16596                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16597                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16598                                || procState > ActivityManager.PROCESS_STATE_TOP);
16599                        i++) {
16600                    // XXX should compute this based on the max of
16601                    // all connected clients.
16602                    ConnectionRecord cr = clist.get(i);
16603                    if (cr.binding.client == app) {
16604                        // Binding to ourself is not interesting.
16605                        continue;
16606                    }
16607                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16608                        ProcessRecord client = cr.binding.client;
16609                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16610                                TOP_APP, doingAll, now);
16611                        int clientProcState = client.curProcState;
16612                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16613                            // If the other app is cached for any reason, for purposes here
16614                            // we are going to consider it empty.  The specific cached state
16615                            // doesn't propagate except under certain conditions.
16616                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16617                        }
16618                        String adjType = null;
16619                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16620                            // Not doing bind OOM management, so treat
16621                            // this guy more like a started service.
16622                            if (app.hasShownUi && app != mHomeProcess) {
16623                                // If this process has shown some UI, let it immediately
16624                                // go to the LRU list because it may be pretty heavy with
16625                                // UI stuff.  We'll tag it with a label just to help
16626                                // debug and understand what is going on.
16627                                if (adj > clientAdj) {
16628                                    adjType = "cch-bound-ui-services";
16629                                }
16630                                app.cached = false;
16631                                clientAdj = adj;
16632                                clientProcState = procState;
16633                            } else {
16634                                if (now >= (s.lastActivity
16635                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16636                                    // This service has not seen activity within
16637                                    // recent memory, so allow it to drop to the
16638                                    // LRU list if there is no other reason to keep
16639                                    // it around.  We'll also tag it with a label just
16640                                    // to help debug and undertand what is going on.
16641                                    if (adj > clientAdj) {
16642                                        adjType = "cch-bound-services";
16643                                    }
16644                                    clientAdj = adj;
16645                                }
16646                            }
16647                        }
16648                        if (adj > clientAdj) {
16649                            // If this process has recently shown UI, and
16650                            // the process that is binding to it is less
16651                            // important than being visible, then we don't
16652                            // care about the binding as much as we care
16653                            // about letting this process get into the LRU
16654                            // list to be killed and restarted if needed for
16655                            // memory.
16656                            if (app.hasShownUi && app != mHomeProcess
16657                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16658                                adjType = "cch-bound-ui-services";
16659                            } else {
16660                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16661                                        |Context.BIND_IMPORTANT)) != 0) {
16662                                    adj = clientAdj;
16663                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16664                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16665                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16666                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16667                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16668                                    adj = clientAdj;
16669                                } else {
16670                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16671                                        adj = ProcessList.VISIBLE_APP_ADJ;
16672                                    }
16673                                }
16674                                if (!client.cached) {
16675                                    app.cached = false;
16676                                }
16677                                adjType = "service";
16678                            }
16679                        }
16680                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16681                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16682                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16683                            }
16684                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16685                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16686                                    // Special handling of clients who are in the top state.
16687                                    // We *may* want to consider this process to be in the
16688                                    // top state as well, but only if there is not another
16689                                    // reason for it to be running.  Being on the top is a
16690                                    // special state, meaning you are specifically running
16691                                    // for the current top app.  If the process is already
16692                                    // running in the background for some other reason, it
16693                                    // is more important to continue considering it to be
16694                                    // in the background state.
16695                                    mayBeTop = true;
16696                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16697                                } else {
16698                                    // Special handling for above-top states (persistent
16699                                    // processes).  These should not bring the current process
16700                                    // into the top state, since they are not on top.  Instead
16701                                    // give them the best state after that.
16702                                    clientProcState =
16703                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16704                                }
16705                            }
16706                        } else {
16707                            if (clientProcState <
16708                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16709                                clientProcState =
16710                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16711                            }
16712                        }
16713                        if (procState > clientProcState) {
16714                            procState = clientProcState;
16715                        }
16716                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16717                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16718                            app.pendingUiClean = true;
16719                        }
16720                        if (adjType != null) {
16721                            app.adjType = adjType;
16722                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16723                                    .REASON_SERVICE_IN_USE;
16724                            app.adjSource = cr.binding.client;
16725                            app.adjSourceProcState = clientProcState;
16726                            app.adjTarget = s.name;
16727                        }
16728                    }
16729                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16730                        app.treatLikeActivity = true;
16731                    }
16732                    final ActivityRecord a = cr.activity;
16733                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16734                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16735                                (a.visible || a.state == ActivityState.RESUMED
16736                                 || a.state == ActivityState.PAUSING)) {
16737                            adj = ProcessList.FOREGROUND_APP_ADJ;
16738                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16739                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16740                            }
16741                            app.cached = false;
16742                            app.adjType = "service";
16743                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16744                                    .REASON_SERVICE_IN_USE;
16745                            app.adjSource = a;
16746                            app.adjSourceProcState = procState;
16747                            app.adjTarget = s.name;
16748                        }
16749                    }
16750                }
16751            }
16752        }
16753
16754        for (int provi = app.pubProviders.size()-1;
16755                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16756                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16757                        || procState > ActivityManager.PROCESS_STATE_TOP);
16758                provi--) {
16759            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16760            for (int i = cpr.connections.size()-1;
16761                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16762                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16763                            || procState > ActivityManager.PROCESS_STATE_TOP);
16764                    i--) {
16765                ContentProviderConnection conn = cpr.connections.get(i);
16766                ProcessRecord client = conn.client;
16767                if (client == app) {
16768                    // Being our own client is not interesting.
16769                    continue;
16770                }
16771                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16772                int clientProcState = client.curProcState;
16773                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16774                    // If the other app is cached for any reason, for purposes here
16775                    // we are going to consider it empty.
16776                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16777                }
16778                if (adj > clientAdj) {
16779                    if (app.hasShownUi && app != mHomeProcess
16780                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16781                        app.adjType = "cch-ui-provider";
16782                    } else {
16783                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16784                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16785                        app.adjType = "provider";
16786                    }
16787                    app.cached &= client.cached;
16788                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16789                            .REASON_PROVIDER_IN_USE;
16790                    app.adjSource = client;
16791                    app.adjSourceProcState = clientProcState;
16792                    app.adjTarget = cpr.name;
16793                }
16794                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16795                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16796                        // Special handling of clients who are in the top state.
16797                        // We *may* want to consider this process to be in the
16798                        // top state as well, but only if there is not another
16799                        // reason for it to be running.  Being on the top is a
16800                        // special state, meaning you are specifically running
16801                        // for the current top app.  If the process is already
16802                        // running in the background for some other reason, it
16803                        // is more important to continue considering it to be
16804                        // in the background state.
16805                        mayBeTop = true;
16806                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16807                    } else {
16808                        // Special handling for above-top states (persistent
16809                        // processes).  These should not bring the current process
16810                        // into the top state, since they are not on top.  Instead
16811                        // give them the best state after that.
16812                        clientProcState =
16813                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16814                    }
16815                }
16816                if (procState > clientProcState) {
16817                    procState = clientProcState;
16818                }
16819                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16820                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16821                }
16822            }
16823            // If the provider has external (non-framework) process
16824            // dependencies, ensure that its adjustment is at least
16825            // FOREGROUND_APP_ADJ.
16826            if (cpr.hasExternalProcessHandles()) {
16827                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16828                    adj = ProcessList.FOREGROUND_APP_ADJ;
16829                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16830                    app.cached = false;
16831                    app.adjType = "provider";
16832                    app.adjTarget = cpr.name;
16833                }
16834                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16835                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16836                }
16837            }
16838        }
16839
16840        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16841            // A client of one of our services or providers is in the top state.  We
16842            // *may* want to be in the top state, but not if we are already running in
16843            // the background for some other reason.  For the decision here, we are going
16844            // to pick out a few specific states that we want to remain in when a client
16845            // is top (states that tend to be longer-term) and otherwise allow it to go
16846            // to the top state.
16847            switch (procState) {
16848                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16849                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16850                case ActivityManager.PROCESS_STATE_SERVICE:
16851                    // These all are longer-term states, so pull them up to the top
16852                    // of the background states, but not all the way to the top state.
16853                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16854                    break;
16855                default:
16856                    // Otherwise, top is a better choice, so take it.
16857                    procState = ActivityManager.PROCESS_STATE_TOP;
16858                    break;
16859            }
16860        }
16861
16862        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16863            if (app.hasClientActivities) {
16864                // This is a cached process, but with client activities.  Mark it so.
16865                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16866                app.adjType = "cch-client-act";
16867            } else if (app.treatLikeActivity) {
16868                // This is a cached process, but somebody wants us to treat it like it has
16869                // an activity, okay!
16870                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16871                app.adjType = "cch-as-act";
16872            }
16873        }
16874
16875        if (adj == ProcessList.SERVICE_ADJ) {
16876            if (doingAll) {
16877                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16878                mNewNumServiceProcs++;
16879                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16880                if (!app.serviceb) {
16881                    // This service isn't far enough down on the LRU list to
16882                    // normally be a B service, but if we are low on RAM and it
16883                    // is large we want to force it down since we would prefer to
16884                    // keep launcher over it.
16885                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16886                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16887                        app.serviceHighRam = true;
16888                        app.serviceb = true;
16889                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16890                    } else {
16891                        mNewNumAServiceProcs++;
16892                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16893                    }
16894                } else {
16895                    app.serviceHighRam = false;
16896                }
16897            }
16898            if (app.serviceb) {
16899                adj = ProcessList.SERVICE_B_ADJ;
16900            }
16901        }
16902
16903        app.curRawAdj = adj;
16904
16905        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16906        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16907        if (adj > app.maxAdj) {
16908            adj = app.maxAdj;
16909            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16910                schedGroup = Process.THREAD_GROUP_DEFAULT;
16911            }
16912        }
16913
16914        // Do final modification to adj.  Everything we do between here and applying
16915        // the final setAdj must be done in this function, because we will also use
16916        // it when computing the final cached adj later.  Note that we don't need to
16917        // worry about this for max adj above, since max adj will always be used to
16918        // keep it out of the cached vaues.
16919        app.curAdj = app.modifyRawOomAdj(adj);
16920        app.curSchedGroup = schedGroup;
16921        app.curProcState = procState;
16922        app.foregroundActivities = foregroundActivities;
16923
16924        return app.curRawAdj;
16925    }
16926
16927    /**
16928     * Schedule PSS collection of a process.
16929     */
16930    void requestPssLocked(ProcessRecord proc, int procState) {
16931        if (mPendingPssProcesses.contains(proc)) {
16932            return;
16933        }
16934        if (mPendingPssProcesses.size() == 0) {
16935            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16936        }
16937        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16938        proc.pssProcState = procState;
16939        mPendingPssProcesses.add(proc);
16940    }
16941
16942    /**
16943     * Schedule PSS collection of all processes.
16944     */
16945    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16946        if (!always) {
16947            if (now < (mLastFullPssTime +
16948                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16949                return;
16950            }
16951        }
16952        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16953        mLastFullPssTime = now;
16954        mFullPssPending = true;
16955        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16956        mPendingPssProcesses.clear();
16957        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16958            ProcessRecord app = mLruProcesses.get(i);
16959            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16960                app.pssProcState = app.setProcState;
16961                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16962                        isSleeping(), now);
16963                mPendingPssProcesses.add(app);
16964            }
16965        }
16966        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16967    }
16968
16969    /**
16970     * Ask a given process to GC right now.
16971     */
16972    final void performAppGcLocked(ProcessRecord app) {
16973        try {
16974            app.lastRequestedGc = SystemClock.uptimeMillis();
16975            if (app.thread != null) {
16976                if (app.reportLowMemory) {
16977                    app.reportLowMemory = false;
16978                    app.thread.scheduleLowMemory();
16979                } else {
16980                    app.thread.processInBackground();
16981                }
16982            }
16983        } catch (Exception e) {
16984            // whatever.
16985        }
16986    }
16987
16988    /**
16989     * Returns true if things are idle enough to perform GCs.
16990     */
16991    private final boolean canGcNowLocked() {
16992        boolean processingBroadcasts = false;
16993        for (BroadcastQueue q : mBroadcastQueues) {
16994            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16995                processingBroadcasts = true;
16996            }
16997        }
16998        return !processingBroadcasts
16999                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17000    }
17001
17002    /**
17003     * Perform GCs on all processes that are waiting for it, but only
17004     * if things are idle.
17005     */
17006    final void performAppGcsLocked() {
17007        final int N = mProcessesToGc.size();
17008        if (N <= 0) {
17009            return;
17010        }
17011        if (canGcNowLocked()) {
17012            while (mProcessesToGc.size() > 0) {
17013                ProcessRecord proc = mProcessesToGc.remove(0);
17014                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17015                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17016                            <= SystemClock.uptimeMillis()) {
17017                        // To avoid spamming the system, we will GC processes one
17018                        // at a time, waiting a few seconds between each.
17019                        performAppGcLocked(proc);
17020                        scheduleAppGcsLocked();
17021                        return;
17022                    } else {
17023                        // It hasn't been long enough since we last GCed this
17024                        // process...  put it in the list to wait for its time.
17025                        addProcessToGcListLocked(proc);
17026                        break;
17027                    }
17028                }
17029            }
17030
17031            scheduleAppGcsLocked();
17032        }
17033    }
17034
17035    /**
17036     * If all looks good, perform GCs on all processes waiting for them.
17037     */
17038    final void performAppGcsIfAppropriateLocked() {
17039        if (canGcNowLocked()) {
17040            performAppGcsLocked();
17041            return;
17042        }
17043        // Still not idle, wait some more.
17044        scheduleAppGcsLocked();
17045    }
17046
17047    /**
17048     * Schedule the execution of all pending app GCs.
17049     */
17050    final void scheduleAppGcsLocked() {
17051        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17052
17053        if (mProcessesToGc.size() > 0) {
17054            // Schedule a GC for the time to the next process.
17055            ProcessRecord proc = mProcessesToGc.get(0);
17056            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17057
17058            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17059            long now = SystemClock.uptimeMillis();
17060            if (when < (now+GC_TIMEOUT)) {
17061                when = now + GC_TIMEOUT;
17062            }
17063            mHandler.sendMessageAtTime(msg, when);
17064        }
17065    }
17066
17067    /**
17068     * Add a process to the array of processes waiting to be GCed.  Keeps the
17069     * list in sorted order by the last GC time.  The process can't already be
17070     * on the list.
17071     */
17072    final void addProcessToGcListLocked(ProcessRecord proc) {
17073        boolean added = false;
17074        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17075            if (mProcessesToGc.get(i).lastRequestedGc <
17076                    proc.lastRequestedGc) {
17077                added = true;
17078                mProcessesToGc.add(i+1, proc);
17079                break;
17080            }
17081        }
17082        if (!added) {
17083            mProcessesToGc.add(0, proc);
17084        }
17085    }
17086
17087    /**
17088     * Set up to ask a process to GC itself.  This will either do it
17089     * immediately, or put it on the list of processes to gc the next
17090     * time things are idle.
17091     */
17092    final void scheduleAppGcLocked(ProcessRecord app) {
17093        long now = SystemClock.uptimeMillis();
17094        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17095            return;
17096        }
17097        if (!mProcessesToGc.contains(app)) {
17098            addProcessToGcListLocked(app);
17099            scheduleAppGcsLocked();
17100        }
17101    }
17102
17103    final void checkExcessivePowerUsageLocked(boolean doKills) {
17104        updateCpuStatsNow();
17105
17106        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17107        boolean doWakeKills = doKills;
17108        boolean doCpuKills = doKills;
17109        if (mLastPowerCheckRealtime == 0) {
17110            doWakeKills = false;
17111        }
17112        if (mLastPowerCheckUptime == 0) {
17113            doCpuKills = false;
17114        }
17115        if (stats.isScreenOn()) {
17116            doWakeKills = false;
17117        }
17118        final long curRealtime = SystemClock.elapsedRealtime();
17119        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17120        final long curUptime = SystemClock.uptimeMillis();
17121        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17122        mLastPowerCheckRealtime = curRealtime;
17123        mLastPowerCheckUptime = curUptime;
17124        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17125            doWakeKills = false;
17126        }
17127        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17128            doCpuKills = false;
17129        }
17130        int i = mLruProcesses.size();
17131        while (i > 0) {
17132            i--;
17133            ProcessRecord app = mLruProcesses.get(i);
17134            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17135                long wtime;
17136                synchronized (stats) {
17137                    wtime = stats.getProcessWakeTime(app.info.uid,
17138                            app.pid, curRealtime);
17139                }
17140                long wtimeUsed = wtime - app.lastWakeTime;
17141                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17142                if (DEBUG_POWER) {
17143                    StringBuilder sb = new StringBuilder(128);
17144                    sb.append("Wake for ");
17145                    app.toShortString(sb);
17146                    sb.append(": over ");
17147                    TimeUtils.formatDuration(realtimeSince, sb);
17148                    sb.append(" used ");
17149                    TimeUtils.formatDuration(wtimeUsed, sb);
17150                    sb.append(" (");
17151                    sb.append((wtimeUsed*100)/realtimeSince);
17152                    sb.append("%)");
17153                    Slog.i(TAG, sb.toString());
17154                    sb.setLength(0);
17155                    sb.append("CPU for ");
17156                    app.toShortString(sb);
17157                    sb.append(": over ");
17158                    TimeUtils.formatDuration(uptimeSince, sb);
17159                    sb.append(" used ");
17160                    TimeUtils.formatDuration(cputimeUsed, sb);
17161                    sb.append(" (");
17162                    sb.append((cputimeUsed*100)/uptimeSince);
17163                    sb.append("%)");
17164                    Slog.i(TAG, sb.toString());
17165                }
17166                // If a process has held a wake lock for more
17167                // than 50% of the time during this period,
17168                // that sounds bad.  Kill!
17169                if (doWakeKills && realtimeSince > 0
17170                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17171                    synchronized (stats) {
17172                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17173                                realtimeSince, wtimeUsed);
17174                    }
17175                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17176                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17177                } else if (doCpuKills && uptimeSince > 0
17178                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17179                    synchronized (stats) {
17180                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17181                                uptimeSince, cputimeUsed);
17182                    }
17183                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17184                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17185                } else {
17186                    app.lastWakeTime = wtime;
17187                    app.lastCpuTime = app.curCpuTime;
17188                }
17189            }
17190        }
17191    }
17192
17193    private final boolean applyOomAdjLocked(ProcessRecord app,
17194            ProcessRecord TOP_APP, boolean doingAll, long now) {
17195        boolean success = true;
17196
17197        if (app.curRawAdj != app.setRawAdj) {
17198            app.setRawAdj = app.curRawAdj;
17199        }
17200
17201        int changes = 0;
17202
17203        if (app.curAdj != app.setAdj) {
17204            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17205            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17206                TAG, "Set " + app.pid + " " + app.processName +
17207                " adj " + app.curAdj + ": " + app.adjType);
17208            app.setAdj = app.curAdj;
17209        }
17210
17211        if (app.setSchedGroup != app.curSchedGroup) {
17212            app.setSchedGroup = app.curSchedGroup;
17213            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17214                    "Setting process group of " + app.processName
17215                    + " to " + app.curSchedGroup);
17216            if (app.waitingToKill != null &&
17217                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17218                app.kill(app.waitingToKill, true);
17219                success = false;
17220            } else {
17221                if (true) {
17222                    long oldId = Binder.clearCallingIdentity();
17223                    try {
17224                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17225                    } catch (Exception e) {
17226                        Slog.w(TAG, "Failed setting process group of " + app.pid
17227                                + " to " + app.curSchedGroup);
17228                        e.printStackTrace();
17229                    } finally {
17230                        Binder.restoreCallingIdentity(oldId);
17231                    }
17232                } else {
17233                    if (app.thread != null) {
17234                        try {
17235                            app.thread.setSchedulingGroup(app.curSchedGroup);
17236                        } catch (RemoteException e) {
17237                        }
17238                    }
17239                }
17240                Process.setSwappiness(app.pid,
17241                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17242            }
17243        }
17244        if (app.repForegroundActivities != app.foregroundActivities) {
17245            app.repForegroundActivities = app.foregroundActivities;
17246            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17247        }
17248        if (app.repProcState != app.curProcState) {
17249            app.repProcState = app.curProcState;
17250            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17251            if (app.thread != null) {
17252                try {
17253                    if (false) {
17254                        //RuntimeException h = new RuntimeException("here");
17255                        Slog.i(TAG, "Sending new process state " + app.repProcState
17256                                + " to " + app /*, h*/);
17257                    }
17258                    app.thread.setProcessState(app.repProcState);
17259                } catch (RemoteException e) {
17260                }
17261            }
17262        }
17263        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17264                app.setProcState)) {
17265            app.lastStateTime = now;
17266            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17267                    isSleeping(), now);
17268            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17269                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17270                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17271                    + (app.nextPssTime-now) + ": " + app);
17272        } else {
17273            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17274                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17275                requestPssLocked(app, app.setProcState);
17276                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17277                        isSleeping(), now);
17278            } else if (false && DEBUG_PSS) {
17279                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17280            }
17281        }
17282        if (app.setProcState != app.curProcState) {
17283            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17284                    "Proc state change of " + app.processName
17285                    + " to " + app.curProcState);
17286            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17287            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17288            if (setImportant && !curImportant) {
17289                // This app is no longer something we consider important enough to allow to
17290                // use arbitrary amounts of battery power.  Note
17291                // its current wake lock time to later know to kill it if
17292                // it is not behaving well.
17293                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17294                synchronized (stats) {
17295                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17296                            app.pid, SystemClock.elapsedRealtime());
17297                }
17298                app.lastCpuTime = app.curCpuTime;
17299
17300            }
17301            app.setProcState = app.curProcState;
17302            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17303                app.notCachedSinceIdle = false;
17304            }
17305            if (!doingAll) {
17306                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17307            } else {
17308                app.procStateChanged = true;
17309            }
17310        }
17311
17312        if (changes != 0) {
17313            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17314            int i = mPendingProcessChanges.size()-1;
17315            ProcessChangeItem item = null;
17316            while (i >= 0) {
17317                item = mPendingProcessChanges.get(i);
17318                if (item.pid == app.pid) {
17319                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17320                    break;
17321                }
17322                i--;
17323            }
17324            if (i < 0) {
17325                // No existing item in pending changes; need a new one.
17326                final int NA = mAvailProcessChanges.size();
17327                if (NA > 0) {
17328                    item = mAvailProcessChanges.remove(NA-1);
17329                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17330                } else {
17331                    item = new ProcessChangeItem();
17332                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17333                }
17334                item.changes = 0;
17335                item.pid = app.pid;
17336                item.uid = app.info.uid;
17337                if (mPendingProcessChanges.size() == 0) {
17338                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17339                            "*** Enqueueing dispatch processes changed!");
17340                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17341                }
17342                mPendingProcessChanges.add(item);
17343            }
17344            item.changes |= changes;
17345            item.processState = app.repProcState;
17346            item.foregroundActivities = app.repForegroundActivities;
17347            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17348                    + Integer.toHexString(System.identityHashCode(item))
17349                    + " " + app.toShortString() + ": changes=" + item.changes
17350                    + " procState=" + item.processState
17351                    + " foreground=" + item.foregroundActivities
17352                    + " type=" + app.adjType + " source=" + app.adjSource
17353                    + " target=" + app.adjTarget);
17354        }
17355
17356        return success;
17357    }
17358
17359    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17360        if (proc.thread != null) {
17361            if (proc.baseProcessTracker != null) {
17362                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17363            }
17364            if (proc.repProcState >= 0) {
17365                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17366                        proc.repProcState);
17367            }
17368        }
17369    }
17370
17371    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17372            ProcessRecord TOP_APP, boolean doingAll, long now) {
17373        if (app.thread == null) {
17374            return false;
17375        }
17376
17377        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17378
17379        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17380    }
17381
17382    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17383            boolean oomAdj) {
17384        if (isForeground != proc.foregroundServices) {
17385            proc.foregroundServices = isForeground;
17386            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17387                    proc.info.uid);
17388            if (isForeground) {
17389                if (curProcs == null) {
17390                    curProcs = new ArrayList<ProcessRecord>();
17391                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17392                }
17393                if (!curProcs.contains(proc)) {
17394                    curProcs.add(proc);
17395                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17396                            proc.info.packageName, proc.info.uid);
17397                }
17398            } else {
17399                if (curProcs != null) {
17400                    if (curProcs.remove(proc)) {
17401                        mBatteryStatsService.noteEvent(
17402                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17403                                proc.info.packageName, proc.info.uid);
17404                        if (curProcs.size() <= 0) {
17405                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17406                        }
17407                    }
17408                }
17409            }
17410            if (oomAdj) {
17411                updateOomAdjLocked();
17412            }
17413        }
17414    }
17415
17416    private final ActivityRecord resumedAppLocked() {
17417        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17418        String pkg;
17419        int uid;
17420        if (act != null) {
17421            pkg = act.packageName;
17422            uid = act.info.applicationInfo.uid;
17423        } else {
17424            pkg = null;
17425            uid = -1;
17426        }
17427        // Has the UID or resumed package name changed?
17428        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17429                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17430            if (mCurResumedPackage != null) {
17431                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17432                        mCurResumedPackage, mCurResumedUid);
17433            }
17434            mCurResumedPackage = pkg;
17435            mCurResumedUid = uid;
17436            if (mCurResumedPackage != null) {
17437                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17438                        mCurResumedPackage, mCurResumedUid);
17439            }
17440        }
17441        return act;
17442    }
17443
17444    final boolean updateOomAdjLocked(ProcessRecord app) {
17445        final ActivityRecord TOP_ACT = resumedAppLocked();
17446        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17447        final boolean wasCached = app.cached;
17448
17449        mAdjSeq++;
17450
17451        // This is the desired cached adjusment we want to tell it to use.
17452        // If our app is currently cached, we know it, and that is it.  Otherwise,
17453        // we don't know it yet, and it needs to now be cached we will then
17454        // need to do a complete oom adj.
17455        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17456                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17457        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17458                SystemClock.uptimeMillis());
17459        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17460            // Changed to/from cached state, so apps after it in the LRU
17461            // list may also be changed.
17462            updateOomAdjLocked();
17463        }
17464        return success;
17465    }
17466
17467    final void updateOomAdjLocked() {
17468        final ActivityRecord TOP_ACT = resumedAppLocked();
17469        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17470        final long now = SystemClock.uptimeMillis();
17471        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17472        final int N = mLruProcesses.size();
17473
17474        if (false) {
17475            RuntimeException e = new RuntimeException();
17476            e.fillInStackTrace();
17477            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17478        }
17479
17480        mAdjSeq++;
17481        mNewNumServiceProcs = 0;
17482        mNewNumAServiceProcs = 0;
17483
17484        final int emptyProcessLimit;
17485        final int cachedProcessLimit;
17486        if (mProcessLimit <= 0) {
17487            emptyProcessLimit = cachedProcessLimit = 0;
17488        } else if (mProcessLimit == 1) {
17489            emptyProcessLimit = 1;
17490            cachedProcessLimit = 0;
17491        } else {
17492            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17493            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17494        }
17495
17496        // Let's determine how many processes we have running vs.
17497        // how many slots we have for background processes; we may want
17498        // to put multiple processes in a slot of there are enough of
17499        // them.
17500        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17501                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17502        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17503        if (numEmptyProcs > cachedProcessLimit) {
17504            // If there are more empty processes than our limit on cached
17505            // processes, then use the cached process limit for the factor.
17506            // This ensures that the really old empty processes get pushed
17507            // down to the bottom, so if we are running low on memory we will
17508            // have a better chance at keeping around more cached processes
17509            // instead of a gazillion empty processes.
17510            numEmptyProcs = cachedProcessLimit;
17511        }
17512        int emptyFactor = numEmptyProcs/numSlots;
17513        if (emptyFactor < 1) emptyFactor = 1;
17514        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17515        if (cachedFactor < 1) cachedFactor = 1;
17516        int stepCached = 0;
17517        int stepEmpty = 0;
17518        int numCached = 0;
17519        int numEmpty = 0;
17520        int numTrimming = 0;
17521
17522        mNumNonCachedProcs = 0;
17523        mNumCachedHiddenProcs = 0;
17524
17525        // First update the OOM adjustment for each of the
17526        // application processes based on their current state.
17527        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17528        int nextCachedAdj = curCachedAdj+1;
17529        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17530        int nextEmptyAdj = curEmptyAdj+2;
17531        for (int i=N-1; i>=0; i--) {
17532            ProcessRecord app = mLruProcesses.get(i);
17533            if (!app.killedByAm && app.thread != null) {
17534                app.procStateChanged = false;
17535                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17536
17537                // If we haven't yet assigned the final cached adj
17538                // to the process, do that now.
17539                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17540                    switch (app.curProcState) {
17541                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17542                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17543                            // This process is a cached process holding activities...
17544                            // assign it the next cached value for that type, and then
17545                            // step that cached level.
17546                            app.curRawAdj = curCachedAdj;
17547                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17548                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17549                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17550                                    + ")");
17551                            if (curCachedAdj != nextCachedAdj) {
17552                                stepCached++;
17553                                if (stepCached >= cachedFactor) {
17554                                    stepCached = 0;
17555                                    curCachedAdj = nextCachedAdj;
17556                                    nextCachedAdj += 2;
17557                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17558                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17559                                    }
17560                                }
17561                            }
17562                            break;
17563                        default:
17564                            // For everything else, assign next empty cached process
17565                            // level and bump that up.  Note that this means that
17566                            // long-running services that have dropped down to the
17567                            // cached level will be treated as empty (since their process
17568                            // state is still as a service), which is what we want.
17569                            app.curRawAdj = curEmptyAdj;
17570                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17571                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17572                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17573                                    + ")");
17574                            if (curEmptyAdj != nextEmptyAdj) {
17575                                stepEmpty++;
17576                                if (stepEmpty >= emptyFactor) {
17577                                    stepEmpty = 0;
17578                                    curEmptyAdj = nextEmptyAdj;
17579                                    nextEmptyAdj += 2;
17580                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17581                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17582                                    }
17583                                }
17584                            }
17585                            break;
17586                    }
17587                }
17588
17589                applyOomAdjLocked(app, TOP_APP, true, now);
17590
17591                // Count the number of process types.
17592                switch (app.curProcState) {
17593                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17594                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17595                        mNumCachedHiddenProcs++;
17596                        numCached++;
17597                        if (numCached > cachedProcessLimit) {
17598                            app.kill("cached #" + numCached, true);
17599                        }
17600                        break;
17601                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17602                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17603                                && app.lastActivityTime < oldTime) {
17604                            app.kill("empty for "
17605                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17606                                    / 1000) + "s", true);
17607                        } else {
17608                            numEmpty++;
17609                            if (numEmpty > emptyProcessLimit) {
17610                                app.kill("empty #" + numEmpty, true);
17611                            }
17612                        }
17613                        break;
17614                    default:
17615                        mNumNonCachedProcs++;
17616                        break;
17617                }
17618
17619                if (app.isolated && app.services.size() <= 0) {
17620                    // If this is an isolated process, and there are no
17621                    // services running in it, then the process is no longer
17622                    // needed.  We agressively kill these because we can by
17623                    // definition not re-use the same process again, and it is
17624                    // good to avoid having whatever code was running in them
17625                    // left sitting around after no longer needed.
17626                    app.kill("isolated not needed", true);
17627                }
17628
17629                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17630                        && !app.killedByAm) {
17631                    numTrimming++;
17632                }
17633            }
17634        }
17635
17636        mNumServiceProcs = mNewNumServiceProcs;
17637
17638        // Now determine the memory trimming level of background processes.
17639        // Unfortunately we need to start at the back of the list to do this
17640        // properly.  We only do this if the number of background apps we
17641        // are managing to keep around is less than half the maximum we desire;
17642        // if we are keeping a good number around, we'll let them use whatever
17643        // memory they want.
17644        final int numCachedAndEmpty = numCached + numEmpty;
17645        int memFactor;
17646        if (numCached <= ProcessList.TRIM_CACHED_APPS
17647                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17648            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17649                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17650            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17651                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17652            } else {
17653                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17654            }
17655        } else {
17656            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17657        }
17658        // We always allow the memory level to go up (better).  We only allow it to go
17659        // down if we are in a state where that is allowed, *and* the total number of processes
17660        // has gone down since last time.
17661        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17662                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17663                + " last=" + mLastNumProcesses);
17664        if (memFactor > mLastMemoryLevel) {
17665            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17666                memFactor = mLastMemoryLevel;
17667                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17668            }
17669        }
17670        mLastMemoryLevel = memFactor;
17671        mLastNumProcesses = mLruProcesses.size();
17672        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17673        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17674        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17675            if (mLowRamStartTime == 0) {
17676                mLowRamStartTime = now;
17677            }
17678            int step = 0;
17679            int fgTrimLevel;
17680            switch (memFactor) {
17681                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17682                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17683                    break;
17684                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17685                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17686                    break;
17687                default:
17688                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17689                    break;
17690            }
17691            int factor = numTrimming/3;
17692            int minFactor = 2;
17693            if (mHomeProcess != null) minFactor++;
17694            if (mPreviousProcess != null) minFactor++;
17695            if (factor < minFactor) factor = minFactor;
17696            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17697            for (int i=N-1; i>=0; i--) {
17698                ProcessRecord app = mLruProcesses.get(i);
17699                if (allChanged || app.procStateChanged) {
17700                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17701                    app.procStateChanged = false;
17702                }
17703                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17704                        && !app.killedByAm) {
17705                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17706                        try {
17707                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17708                                    "Trimming memory of " + app.processName
17709                                    + " to " + curLevel);
17710                            app.thread.scheduleTrimMemory(curLevel);
17711                        } catch (RemoteException e) {
17712                        }
17713                        if (false) {
17714                            // For now we won't do this; our memory trimming seems
17715                            // to be good enough at this point that destroying
17716                            // activities causes more harm than good.
17717                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17718                                    && app != mHomeProcess && app != mPreviousProcess) {
17719                                // Need to do this on its own message because the stack may not
17720                                // be in a consistent state at this point.
17721                                // For these apps we will also finish their activities
17722                                // to help them free memory.
17723                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17724                            }
17725                        }
17726                    }
17727                    app.trimMemoryLevel = curLevel;
17728                    step++;
17729                    if (step >= factor) {
17730                        step = 0;
17731                        switch (curLevel) {
17732                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17733                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17734                                break;
17735                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17736                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17737                                break;
17738                        }
17739                    }
17740                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17741                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17742                            && app.thread != null) {
17743                        try {
17744                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17745                                    "Trimming memory of heavy-weight " + app.processName
17746                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17747                            app.thread.scheduleTrimMemory(
17748                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17749                        } catch (RemoteException e) {
17750                        }
17751                    }
17752                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17753                } else {
17754                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17755                            || app.systemNoUi) && app.pendingUiClean) {
17756                        // If this application is now in the background and it
17757                        // had done UI, then give it the special trim level to
17758                        // have it free UI resources.
17759                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17760                        if (app.trimMemoryLevel < level && app.thread != null) {
17761                            try {
17762                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17763                                        "Trimming memory of bg-ui " + app.processName
17764                                        + " to " + level);
17765                                app.thread.scheduleTrimMemory(level);
17766                            } catch (RemoteException e) {
17767                            }
17768                        }
17769                        app.pendingUiClean = false;
17770                    }
17771                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17772                        try {
17773                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17774                                    "Trimming memory of fg " + app.processName
17775                                    + " to " + fgTrimLevel);
17776                            app.thread.scheduleTrimMemory(fgTrimLevel);
17777                        } catch (RemoteException e) {
17778                        }
17779                    }
17780                    app.trimMemoryLevel = fgTrimLevel;
17781                }
17782            }
17783        } else {
17784            if (mLowRamStartTime != 0) {
17785                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17786                mLowRamStartTime = 0;
17787            }
17788            for (int i=N-1; i>=0; i--) {
17789                ProcessRecord app = mLruProcesses.get(i);
17790                if (allChanged || app.procStateChanged) {
17791                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17792                    app.procStateChanged = false;
17793                }
17794                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17795                        || app.systemNoUi) && app.pendingUiClean) {
17796                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17797                            && app.thread != null) {
17798                        try {
17799                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17800                                    "Trimming memory of ui hidden " + app.processName
17801                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17802                            app.thread.scheduleTrimMemory(
17803                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17804                        } catch (RemoteException e) {
17805                        }
17806                    }
17807                    app.pendingUiClean = false;
17808                }
17809                app.trimMemoryLevel = 0;
17810            }
17811        }
17812
17813        if (mAlwaysFinishActivities) {
17814            // Need to do this on its own message because the stack may not
17815            // be in a consistent state at this point.
17816            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17817        }
17818
17819        if (allChanged) {
17820            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17821        }
17822
17823        if (mProcessStats.shouldWriteNowLocked(now)) {
17824            mHandler.post(new Runnable() {
17825                @Override public void run() {
17826                    synchronized (ActivityManagerService.this) {
17827                        mProcessStats.writeStateAsyncLocked();
17828                    }
17829                }
17830            });
17831        }
17832
17833        if (DEBUG_OOM_ADJ) {
17834            if (false) {
17835                RuntimeException here = new RuntimeException("here");
17836                here.fillInStackTrace();
17837                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
17838            } else {
17839                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17840            }
17841        }
17842    }
17843
17844    final void trimApplications() {
17845        synchronized (this) {
17846            int i;
17847
17848            // First remove any unused application processes whose package
17849            // has been removed.
17850            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17851                final ProcessRecord app = mRemovedProcesses.get(i);
17852                if (app.activities.size() == 0
17853                        && app.curReceiver == null && app.services.size() == 0) {
17854                    Slog.i(
17855                        TAG, "Exiting empty application process "
17856                        + app.processName + " ("
17857                        + (app.thread != null ? app.thread.asBinder() : null)
17858                        + ")\n");
17859                    if (app.pid > 0 && app.pid != MY_PID) {
17860                        app.kill("empty", false);
17861                    } else {
17862                        try {
17863                            app.thread.scheduleExit();
17864                        } catch (Exception e) {
17865                            // Ignore exceptions.
17866                        }
17867                    }
17868                    cleanUpApplicationRecordLocked(app, false, true, -1);
17869                    mRemovedProcesses.remove(i);
17870
17871                    if (app.persistent) {
17872                        addAppLocked(app.info, false, null /* ABI override */);
17873                    }
17874                }
17875            }
17876
17877            // Now update the oom adj for all processes.
17878            updateOomAdjLocked();
17879        }
17880    }
17881
17882    /** This method sends the specified signal to each of the persistent apps */
17883    public void signalPersistentProcesses(int sig) throws RemoteException {
17884        if (sig != Process.SIGNAL_USR1) {
17885            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17886        }
17887
17888        synchronized (this) {
17889            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17890                    != PackageManager.PERMISSION_GRANTED) {
17891                throw new SecurityException("Requires permission "
17892                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17893            }
17894
17895            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17896                ProcessRecord r = mLruProcesses.get(i);
17897                if (r.thread != null && r.persistent) {
17898                    Process.sendSignal(r.pid, sig);
17899                }
17900            }
17901        }
17902    }
17903
17904    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17905        if (proc == null || proc == mProfileProc) {
17906            proc = mProfileProc;
17907            profileType = mProfileType;
17908            clearProfilerLocked();
17909        }
17910        if (proc == null) {
17911            return;
17912        }
17913        try {
17914            proc.thread.profilerControl(false, null, profileType);
17915        } catch (RemoteException e) {
17916            throw new IllegalStateException("Process disappeared");
17917        }
17918    }
17919
17920    private void clearProfilerLocked() {
17921        if (mProfileFd != null) {
17922            try {
17923                mProfileFd.close();
17924            } catch (IOException e) {
17925            }
17926        }
17927        mProfileApp = null;
17928        mProfileProc = null;
17929        mProfileFile = null;
17930        mProfileType = 0;
17931        mAutoStopProfiler = false;
17932        mSamplingInterval = 0;
17933    }
17934
17935    public boolean profileControl(String process, int userId, boolean start,
17936            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17937
17938        try {
17939            synchronized (this) {
17940                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17941                // its own permission.
17942                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17943                        != PackageManager.PERMISSION_GRANTED) {
17944                    throw new SecurityException("Requires permission "
17945                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17946                }
17947
17948                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17949                    throw new IllegalArgumentException("null profile info or fd");
17950                }
17951
17952                ProcessRecord proc = null;
17953                if (process != null) {
17954                    proc = findProcessLocked(process, userId, "profileControl");
17955                }
17956
17957                if (start && (proc == null || proc.thread == null)) {
17958                    throw new IllegalArgumentException("Unknown process: " + process);
17959                }
17960
17961                if (start) {
17962                    stopProfilerLocked(null, 0);
17963                    setProfileApp(proc.info, proc.processName, profilerInfo);
17964                    mProfileProc = proc;
17965                    mProfileType = profileType;
17966                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17967                    try {
17968                        fd = fd.dup();
17969                    } catch (IOException e) {
17970                        fd = null;
17971                    }
17972                    profilerInfo.profileFd = fd;
17973                    proc.thread.profilerControl(start, profilerInfo, profileType);
17974                    fd = null;
17975                    mProfileFd = null;
17976                } else {
17977                    stopProfilerLocked(proc, profileType);
17978                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17979                        try {
17980                            profilerInfo.profileFd.close();
17981                        } catch (IOException e) {
17982                        }
17983                    }
17984                }
17985
17986                return true;
17987            }
17988        } catch (RemoteException e) {
17989            throw new IllegalStateException("Process disappeared");
17990        } finally {
17991            if (profilerInfo != null && profilerInfo.profileFd != null) {
17992                try {
17993                    profilerInfo.profileFd.close();
17994                } catch (IOException e) {
17995                }
17996            }
17997        }
17998    }
17999
18000    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18001        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18002                userId, true, ALLOW_FULL_ONLY, callName, null);
18003        ProcessRecord proc = null;
18004        try {
18005            int pid = Integer.parseInt(process);
18006            synchronized (mPidsSelfLocked) {
18007                proc = mPidsSelfLocked.get(pid);
18008            }
18009        } catch (NumberFormatException e) {
18010        }
18011
18012        if (proc == null) {
18013            ArrayMap<String, SparseArray<ProcessRecord>> all
18014                    = mProcessNames.getMap();
18015            SparseArray<ProcessRecord> procs = all.get(process);
18016            if (procs != null && procs.size() > 0) {
18017                proc = procs.valueAt(0);
18018                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18019                    for (int i=1; i<procs.size(); i++) {
18020                        ProcessRecord thisProc = procs.valueAt(i);
18021                        if (thisProc.userId == userId) {
18022                            proc = thisProc;
18023                            break;
18024                        }
18025                    }
18026                }
18027            }
18028        }
18029
18030        return proc;
18031    }
18032
18033    public boolean dumpHeap(String process, int userId, boolean managed,
18034            String path, ParcelFileDescriptor fd) throws RemoteException {
18035
18036        try {
18037            synchronized (this) {
18038                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18039                // its own permission (same as profileControl).
18040                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18041                        != PackageManager.PERMISSION_GRANTED) {
18042                    throw new SecurityException("Requires permission "
18043                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18044                }
18045
18046                if (fd == null) {
18047                    throw new IllegalArgumentException("null fd");
18048                }
18049
18050                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18051                if (proc == null || proc.thread == null) {
18052                    throw new IllegalArgumentException("Unknown process: " + process);
18053                }
18054
18055                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18056                if (!isDebuggable) {
18057                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18058                        throw new SecurityException("Process not debuggable: " + proc);
18059                    }
18060                }
18061
18062                proc.thread.dumpHeap(managed, path, fd);
18063                fd = null;
18064                return true;
18065            }
18066        } catch (RemoteException e) {
18067            throw new IllegalStateException("Process disappeared");
18068        } finally {
18069            if (fd != null) {
18070                try {
18071                    fd.close();
18072                } catch (IOException e) {
18073                }
18074            }
18075        }
18076    }
18077
18078    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18079    public void monitor() {
18080        synchronized (this) { }
18081    }
18082
18083    void onCoreSettingsChange(Bundle settings) {
18084        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18085            ProcessRecord processRecord = mLruProcesses.get(i);
18086            try {
18087                if (processRecord.thread != null) {
18088                    processRecord.thread.setCoreSettings(settings);
18089                }
18090            } catch (RemoteException re) {
18091                /* ignore */
18092            }
18093        }
18094    }
18095
18096    // Multi-user methods
18097
18098    /**
18099     * Start user, if its not already running, but don't bring it to foreground.
18100     */
18101    @Override
18102    public boolean startUserInBackground(final int userId) {
18103        return startUser(userId, /* foreground */ false);
18104    }
18105
18106    /**
18107     * Start user, if its not already running, and bring it to foreground.
18108     */
18109    boolean startUserInForeground(final int userId, Dialog dlg) {
18110        boolean result = startUser(userId, /* foreground */ true);
18111        dlg.dismiss();
18112        return result;
18113    }
18114
18115    /**
18116     * Refreshes the list of users related to the current user when either a
18117     * user switch happens or when a new related user is started in the
18118     * background.
18119     */
18120    private void updateCurrentProfileIdsLocked() {
18121        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18122                mCurrentUserId, false /* enabledOnly */);
18123        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18124        for (int i = 0; i < currentProfileIds.length; i++) {
18125            currentProfileIds[i] = profiles.get(i).id;
18126        }
18127        mCurrentProfileIds = currentProfileIds;
18128
18129        synchronized (mUserProfileGroupIdsSelfLocked) {
18130            mUserProfileGroupIdsSelfLocked.clear();
18131            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18132            for (int i = 0; i < users.size(); i++) {
18133                UserInfo user = users.get(i);
18134                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18135                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18136                }
18137            }
18138        }
18139    }
18140
18141    private Set getProfileIdsLocked(int userId) {
18142        Set userIds = new HashSet<Integer>();
18143        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18144                userId, false /* enabledOnly */);
18145        for (UserInfo user : profiles) {
18146            userIds.add(Integer.valueOf(user.id));
18147        }
18148        return userIds;
18149    }
18150
18151    @Override
18152    public boolean switchUser(final int userId) {
18153        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18154        String userName;
18155        synchronized (this) {
18156            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18157            if (userInfo == null) {
18158                Slog.w(TAG, "No user info for user #" + userId);
18159                return false;
18160            }
18161            if (userInfo.isManagedProfile()) {
18162                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18163                return false;
18164            }
18165            userName = userInfo.name;
18166            mTargetUserId = userId;
18167        }
18168        mHandler.removeMessages(START_USER_SWITCH_MSG);
18169        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18170        return true;
18171    }
18172
18173    private void showUserSwitchDialog(int userId, String userName) {
18174        // The dialog will show and then initiate the user switch by calling startUserInForeground
18175        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18176                true /* above system */);
18177        d.show();
18178    }
18179
18180    private boolean startUser(final int userId, final boolean foreground) {
18181        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18182                != PackageManager.PERMISSION_GRANTED) {
18183            String msg = "Permission Denial: switchUser() from pid="
18184                    + Binder.getCallingPid()
18185                    + ", uid=" + Binder.getCallingUid()
18186                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18187            Slog.w(TAG, msg);
18188            throw new SecurityException(msg);
18189        }
18190
18191        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18192
18193        final long ident = Binder.clearCallingIdentity();
18194        try {
18195            synchronized (this) {
18196                final int oldUserId = mCurrentUserId;
18197                if (oldUserId == userId) {
18198                    return true;
18199                }
18200
18201                mStackSupervisor.setLockTaskModeLocked(null, false);
18202
18203                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18204                if (userInfo == null) {
18205                    Slog.w(TAG, "No user info for user #" + userId);
18206                    return false;
18207                }
18208                if (foreground && userInfo.isManagedProfile()) {
18209                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18210                    return false;
18211                }
18212
18213                if (foreground) {
18214                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18215                            R.anim.screen_user_enter);
18216                }
18217
18218                boolean needStart = false;
18219
18220                // If the user we are switching to is not currently started, then
18221                // we need to start it now.
18222                if (mStartedUsers.get(userId) == null) {
18223                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18224                    updateStartedUserArrayLocked();
18225                    needStart = true;
18226                }
18227
18228                final Integer userIdInt = Integer.valueOf(userId);
18229                mUserLru.remove(userIdInt);
18230                mUserLru.add(userIdInt);
18231
18232                if (foreground) {
18233                    mCurrentUserId = userId;
18234                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18235                    updateCurrentProfileIdsLocked();
18236                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18237                    // Once the internal notion of the active user has switched, we lock the device
18238                    // with the option to show the user switcher on the keyguard.
18239                    mWindowManager.lockNow(null);
18240                } else {
18241                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18242                    updateCurrentProfileIdsLocked();
18243                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18244                    mUserLru.remove(currentUserIdInt);
18245                    mUserLru.add(currentUserIdInt);
18246                }
18247
18248                final UserStartedState uss = mStartedUsers.get(userId);
18249
18250                // Make sure user is in the started state.  If it is currently
18251                // stopping, we need to knock that off.
18252                if (uss.mState == UserStartedState.STATE_STOPPING) {
18253                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18254                    // so we can just fairly silently bring the user back from
18255                    // the almost-dead.
18256                    uss.mState = UserStartedState.STATE_RUNNING;
18257                    updateStartedUserArrayLocked();
18258                    needStart = true;
18259                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18260                    // This means ACTION_SHUTDOWN has been sent, so we will
18261                    // need to treat this as a new boot of the user.
18262                    uss.mState = UserStartedState.STATE_BOOTING;
18263                    updateStartedUserArrayLocked();
18264                    needStart = true;
18265                }
18266
18267                if (uss.mState == UserStartedState.STATE_BOOTING) {
18268                    // Booting up a new user, need to tell system services about it.
18269                    // Note that this is on the same handler as scheduling of broadcasts,
18270                    // which is important because it needs to go first.
18271                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18272                }
18273
18274                if (foreground) {
18275                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18276                            oldUserId));
18277                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18278                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18279                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18280                            oldUserId, userId, uss));
18281                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18282                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18283                }
18284
18285                if (needStart) {
18286                    // Send USER_STARTED broadcast
18287                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18288                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18289                            | Intent.FLAG_RECEIVER_FOREGROUND);
18290                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18291                    broadcastIntentLocked(null, null, intent,
18292                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18293                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18294                }
18295
18296                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18297                    if (userId != UserHandle.USER_OWNER) {
18298                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18299                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18300                        broadcastIntentLocked(null, null, intent, null,
18301                                new IIntentReceiver.Stub() {
18302                                    public void performReceive(Intent intent, int resultCode,
18303                                            String data, Bundle extras, boolean ordered,
18304                                            boolean sticky, int sendingUser) {
18305                                        onUserInitialized(uss, foreground, oldUserId, userId);
18306                                    }
18307                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18308                                true, false, MY_PID, Process.SYSTEM_UID,
18309                                userId);
18310                        uss.initializing = true;
18311                    } else {
18312                        getUserManagerLocked().makeInitialized(userInfo.id);
18313                    }
18314                }
18315
18316                if (foreground) {
18317                    if (!uss.initializing) {
18318                        moveUserToForeground(uss, oldUserId, userId);
18319                    }
18320                } else {
18321                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18322                }
18323
18324                if (needStart) {
18325                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18326                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18327                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18328                    broadcastIntentLocked(null, null, intent,
18329                            null, new IIntentReceiver.Stub() {
18330                                @Override
18331                                public void performReceive(Intent intent, int resultCode, String data,
18332                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18333                                        throws RemoteException {
18334                                }
18335                            }, 0, null, null,
18336                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18337                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18338                }
18339            }
18340        } finally {
18341            Binder.restoreCallingIdentity(ident);
18342        }
18343
18344        return true;
18345    }
18346
18347    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18348        long ident = Binder.clearCallingIdentity();
18349        try {
18350            Intent intent;
18351            if (oldUserId >= 0) {
18352                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18353                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18354                int count = profiles.size();
18355                for (int i = 0; i < count; i++) {
18356                    int profileUserId = profiles.get(i).id;
18357                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18358                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18359                            | Intent.FLAG_RECEIVER_FOREGROUND);
18360                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18361                    broadcastIntentLocked(null, null, intent,
18362                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18363                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18364                }
18365            }
18366            if (newUserId >= 0) {
18367                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18368                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18369                int count = profiles.size();
18370                for (int i = 0; i < count; i++) {
18371                    int profileUserId = profiles.get(i).id;
18372                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18373                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18374                            | Intent.FLAG_RECEIVER_FOREGROUND);
18375                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18376                    broadcastIntentLocked(null, null, intent,
18377                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18378                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18379                }
18380                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18381                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18382                        | Intent.FLAG_RECEIVER_FOREGROUND);
18383                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18384                broadcastIntentLocked(null, null, intent,
18385                        null, null, 0, null, null,
18386                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18387                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18388            }
18389        } finally {
18390            Binder.restoreCallingIdentity(ident);
18391        }
18392    }
18393
18394    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18395            final int newUserId) {
18396        final int N = mUserSwitchObservers.beginBroadcast();
18397        if (N > 0) {
18398            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18399                int mCount = 0;
18400                @Override
18401                public void sendResult(Bundle data) throws RemoteException {
18402                    synchronized (ActivityManagerService.this) {
18403                        if (mCurUserSwitchCallback == this) {
18404                            mCount++;
18405                            if (mCount == N) {
18406                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18407                            }
18408                        }
18409                    }
18410                }
18411            };
18412            synchronized (this) {
18413                uss.switching = true;
18414                mCurUserSwitchCallback = callback;
18415            }
18416            for (int i=0; i<N; i++) {
18417                try {
18418                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18419                            newUserId, callback);
18420                } catch (RemoteException e) {
18421                }
18422            }
18423        } else {
18424            synchronized (this) {
18425                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18426            }
18427        }
18428        mUserSwitchObservers.finishBroadcast();
18429    }
18430
18431    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18432        synchronized (this) {
18433            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18434            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18435        }
18436    }
18437
18438    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18439        mCurUserSwitchCallback = null;
18440        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18441        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18442                oldUserId, newUserId, uss));
18443    }
18444
18445    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18446        synchronized (this) {
18447            if (foreground) {
18448                moveUserToForeground(uss, oldUserId, newUserId);
18449            }
18450        }
18451
18452        completeSwitchAndInitalize(uss, newUserId, true, false);
18453    }
18454
18455    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18456        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18457        if (homeInFront) {
18458            startHomeActivityLocked(newUserId);
18459        } else {
18460            mStackSupervisor.resumeTopActivitiesLocked();
18461        }
18462        EventLogTags.writeAmSwitchUser(newUserId);
18463        getUserManagerLocked().userForeground(newUserId);
18464        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18465    }
18466
18467    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18468        completeSwitchAndInitalize(uss, newUserId, false, true);
18469    }
18470
18471    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18472            boolean clearInitializing, boolean clearSwitching) {
18473        boolean unfrozen = false;
18474        synchronized (this) {
18475            if (clearInitializing) {
18476                uss.initializing = false;
18477                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18478            }
18479            if (clearSwitching) {
18480                uss.switching = false;
18481            }
18482            if (!uss.switching && !uss.initializing) {
18483                mWindowManager.stopFreezingScreen();
18484                unfrozen = true;
18485            }
18486        }
18487        if (unfrozen) {
18488            final int N = mUserSwitchObservers.beginBroadcast();
18489            for (int i=0; i<N; i++) {
18490                try {
18491                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18492                } catch (RemoteException e) {
18493                }
18494            }
18495            mUserSwitchObservers.finishBroadcast();
18496        }
18497    }
18498
18499    void scheduleStartProfilesLocked() {
18500        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18501            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18502                    DateUtils.SECOND_IN_MILLIS);
18503        }
18504    }
18505
18506    void startProfilesLocked() {
18507        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18508        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18509                mCurrentUserId, false /* enabledOnly */);
18510        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18511        for (UserInfo user : profiles) {
18512            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18513                    && user.id != mCurrentUserId) {
18514                toStart.add(user);
18515            }
18516        }
18517        final int n = toStart.size();
18518        int i = 0;
18519        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18520            startUserInBackground(toStart.get(i).id);
18521        }
18522        if (i < n) {
18523            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18524        }
18525    }
18526
18527    void finishUserBoot(UserStartedState uss) {
18528        synchronized (this) {
18529            if (uss.mState == UserStartedState.STATE_BOOTING
18530                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18531                uss.mState = UserStartedState.STATE_RUNNING;
18532                final int userId = uss.mHandle.getIdentifier();
18533                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18534                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18535                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18536                broadcastIntentLocked(null, null, intent,
18537                        null, null, 0, null, null,
18538                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18539                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18540            }
18541        }
18542    }
18543
18544    void finishUserSwitch(UserStartedState uss) {
18545        synchronized (this) {
18546            finishUserBoot(uss);
18547
18548            startProfilesLocked();
18549
18550            int num = mUserLru.size();
18551            int i = 0;
18552            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18553                Integer oldUserId = mUserLru.get(i);
18554                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18555                if (oldUss == null) {
18556                    // Shouldn't happen, but be sane if it does.
18557                    mUserLru.remove(i);
18558                    num--;
18559                    continue;
18560                }
18561                if (oldUss.mState == UserStartedState.STATE_STOPPING
18562                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18563                    // This user is already stopping, doesn't count.
18564                    num--;
18565                    i++;
18566                    continue;
18567                }
18568                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18569                    // Owner and current can't be stopped, but count as running.
18570                    i++;
18571                    continue;
18572                }
18573                // This is a user to be stopped.
18574                stopUserLocked(oldUserId, null);
18575                num--;
18576                i++;
18577            }
18578        }
18579    }
18580
18581    @Override
18582    public int stopUser(final int userId, final IStopUserCallback callback) {
18583        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18584                != PackageManager.PERMISSION_GRANTED) {
18585            String msg = "Permission Denial: switchUser() from pid="
18586                    + Binder.getCallingPid()
18587                    + ", uid=" + Binder.getCallingUid()
18588                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18589            Slog.w(TAG, msg);
18590            throw new SecurityException(msg);
18591        }
18592        if (userId <= 0) {
18593            throw new IllegalArgumentException("Can't stop primary user " + userId);
18594        }
18595        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18596        synchronized (this) {
18597            return stopUserLocked(userId, callback);
18598        }
18599    }
18600
18601    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18602        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18603        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18604            return ActivityManager.USER_OP_IS_CURRENT;
18605        }
18606
18607        final UserStartedState uss = mStartedUsers.get(userId);
18608        if (uss == null) {
18609            // User is not started, nothing to do...  but we do need to
18610            // callback if requested.
18611            if (callback != null) {
18612                mHandler.post(new Runnable() {
18613                    @Override
18614                    public void run() {
18615                        try {
18616                            callback.userStopped(userId);
18617                        } catch (RemoteException e) {
18618                        }
18619                    }
18620                });
18621            }
18622            return ActivityManager.USER_OP_SUCCESS;
18623        }
18624
18625        if (callback != null) {
18626            uss.mStopCallbacks.add(callback);
18627        }
18628
18629        if (uss.mState != UserStartedState.STATE_STOPPING
18630                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18631            uss.mState = UserStartedState.STATE_STOPPING;
18632            updateStartedUserArrayLocked();
18633
18634            long ident = Binder.clearCallingIdentity();
18635            try {
18636                // We are going to broadcast ACTION_USER_STOPPING and then
18637                // once that is done send a final ACTION_SHUTDOWN and then
18638                // stop the user.
18639                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18640                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18641                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18642                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18643                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18644                // This is the result receiver for the final shutdown broadcast.
18645                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18646                    @Override
18647                    public void performReceive(Intent intent, int resultCode, String data,
18648                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18649                        finishUserStop(uss);
18650                    }
18651                };
18652                // This is the result receiver for the initial stopping broadcast.
18653                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18654                    @Override
18655                    public void performReceive(Intent intent, int resultCode, String data,
18656                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18657                        // On to the next.
18658                        synchronized (ActivityManagerService.this) {
18659                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18660                                // Whoops, we are being started back up.  Abort, abort!
18661                                return;
18662                            }
18663                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18664                        }
18665                        mBatteryStatsService.noteEvent(
18666                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18667                                Integer.toString(userId), userId);
18668                        mSystemServiceManager.stopUser(userId);
18669                        broadcastIntentLocked(null, null, shutdownIntent,
18670                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18671                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18672                    }
18673                };
18674                // Kick things off.
18675                broadcastIntentLocked(null, null, stoppingIntent,
18676                        null, stoppingReceiver, 0, null, null,
18677                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18678                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18679            } finally {
18680                Binder.restoreCallingIdentity(ident);
18681            }
18682        }
18683
18684        return ActivityManager.USER_OP_SUCCESS;
18685    }
18686
18687    void finishUserStop(UserStartedState uss) {
18688        final int userId = uss.mHandle.getIdentifier();
18689        boolean stopped;
18690        ArrayList<IStopUserCallback> callbacks;
18691        synchronized (this) {
18692            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18693            if (mStartedUsers.get(userId) != uss) {
18694                stopped = false;
18695            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18696                stopped = false;
18697            } else {
18698                stopped = true;
18699                // User can no longer run.
18700                mStartedUsers.remove(userId);
18701                mUserLru.remove(Integer.valueOf(userId));
18702                updateStartedUserArrayLocked();
18703
18704                // Clean up all state and processes associated with the user.
18705                // Kill all the processes for the user.
18706                forceStopUserLocked(userId, "finish user");
18707            }
18708
18709            // Explicitly remove the old information in mRecentTasks.
18710            removeRecentTasksForUserLocked(userId);
18711        }
18712
18713        for (int i=0; i<callbacks.size(); i++) {
18714            try {
18715                if (stopped) callbacks.get(i).userStopped(userId);
18716                else callbacks.get(i).userStopAborted(userId);
18717            } catch (RemoteException e) {
18718            }
18719        }
18720
18721        if (stopped) {
18722            mSystemServiceManager.cleanupUser(userId);
18723            synchronized (this) {
18724                mStackSupervisor.removeUserLocked(userId);
18725            }
18726        }
18727    }
18728
18729    @Override
18730    public UserInfo getCurrentUser() {
18731        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18732                != PackageManager.PERMISSION_GRANTED) && (
18733                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18734                != PackageManager.PERMISSION_GRANTED)) {
18735            String msg = "Permission Denial: getCurrentUser() from pid="
18736                    + Binder.getCallingPid()
18737                    + ", uid=" + Binder.getCallingUid()
18738                    + " requires " + INTERACT_ACROSS_USERS;
18739            Slog.w(TAG, msg);
18740            throw new SecurityException(msg);
18741        }
18742        synchronized (this) {
18743            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18744            return getUserManagerLocked().getUserInfo(userId);
18745        }
18746    }
18747
18748    int getCurrentUserIdLocked() {
18749        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18750    }
18751
18752    @Override
18753    public boolean isUserRunning(int userId, boolean orStopped) {
18754        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18755                != PackageManager.PERMISSION_GRANTED) {
18756            String msg = "Permission Denial: isUserRunning() from pid="
18757                    + Binder.getCallingPid()
18758                    + ", uid=" + Binder.getCallingUid()
18759                    + " requires " + INTERACT_ACROSS_USERS;
18760            Slog.w(TAG, msg);
18761            throw new SecurityException(msg);
18762        }
18763        synchronized (this) {
18764            return isUserRunningLocked(userId, orStopped);
18765        }
18766    }
18767
18768    boolean isUserRunningLocked(int userId, boolean orStopped) {
18769        UserStartedState state = mStartedUsers.get(userId);
18770        if (state == null) {
18771            return false;
18772        }
18773        if (orStopped) {
18774            return true;
18775        }
18776        return state.mState != UserStartedState.STATE_STOPPING
18777                && state.mState != UserStartedState.STATE_SHUTDOWN;
18778    }
18779
18780    @Override
18781    public int[] getRunningUserIds() {
18782        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18783                != PackageManager.PERMISSION_GRANTED) {
18784            String msg = "Permission Denial: isUserRunning() from pid="
18785                    + Binder.getCallingPid()
18786                    + ", uid=" + Binder.getCallingUid()
18787                    + " requires " + INTERACT_ACROSS_USERS;
18788            Slog.w(TAG, msg);
18789            throw new SecurityException(msg);
18790        }
18791        synchronized (this) {
18792            return mStartedUserArray;
18793        }
18794    }
18795
18796    private void updateStartedUserArrayLocked() {
18797        int num = 0;
18798        for (int i=0; i<mStartedUsers.size();  i++) {
18799            UserStartedState uss = mStartedUsers.valueAt(i);
18800            // This list does not include stopping users.
18801            if (uss.mState != UserStartedState.STATE_STOPPING
18802                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18803                num++;
18804            }
18805        }
18806        mStartedUserArray = new int[num];
18807        num = 0;
18808        for (int i=0; i<mStartedUsers.size();  i++) {
18809            UserStartedState uss = mStartedUsers.valueAt(i);
18810            if (uss.mState != UserStartedState.STATE_STOPPING
18811                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18812                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18813                num++;
18814            }
18815        }
18816    }
18817
18818    @Override
18819    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18820        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18821                != PackageManager.PERMISSION_GRANTED) {
18822            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18823                    + Binder.getCallingPid()
18824                    + ", uid=" + Binder.getCallingUid()
18825                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18826            Slog.w(TAG, msg);
18827            throw new SecurityException(msg);
18828        }
18829
18830        mUserSwitchObservers.register(observer);
18831    }
18832
18833    @Override
18834    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18835        mUserSwitchObservers.unregister(observer);
18836    }
18837
18838    private boolean userExists(int userId) {
18839        if (userId == 0) {
18840            return true;
18841        }
18842        UserManagerService ums = getUserManagerLocked();
18843        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18844    }
18845
18846    int[] getUsersLocked() {
18847        UserManagerService ums = getUserManagerLocked();
18848        return ums != null ? ums.getUserIds() : new int[] { 0 };
18849    }
18850
18851    UserManagerService getUserManagerLocked() {
18852        if (mUserManager == null) {
18853            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18854            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18855        }
18856        return mUserManager;
18857    }
18858
18859    private int applyUserId(int uid, int userId) {
18860        return UserHandle.getUid(userId, uid);
18861    }
18862
18863    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18864        if (info == null) return null;
18865        ApplicationInfo newInfo = new ApplicationInfo(info);
18866        newInfo.uid = applyUserId(info.uid, userId);
18867        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18868                + info.packageName;
18869        return newInfo;
18870    }
18871
18872    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18873        if (aInfo == null
18874                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18875            return aInfo;
18876        }
18877
18878        ActivityInfo info = new ActivityInfo(aInfo);
18879        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18880        return info;
18881    }
18882
18883    private final class LocalService extends ActivityManagerInternal {
18884        @Override
18885        public void goingToSleep() {
18886            ActivityManagerService.this.goingToSleep();
18887        }
18888
18889        @Override
18890        public void wakingUp() {
18891            ActivityManagerService.this.wakingUp();
18892        }
18893
18894        @Override
18895        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18896                String processName, String abiOverride, int uid, Runnable crashHandler) {
18897            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18898                    processName, abiOverride, uid, crashHandler);
18899        }
18900    }
18901
18902    /**
18903     * An implementation of IAppTask, that allows an app to manage its own tasks via
18904     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18905     * only the process that calls getAppTasks() can call the AppTask methods.
18906     */
18907    class AppTaskImpl extends IAppTask.Stub {
18908        private int mTaskId;
18909        private int mCallingUid;
18910
18911        public AppTaskImpl(int taskId, int callingUid) {
18912            mTaskId = taskId;
18913            mCallingUid = callingUid;
18914        }
18915
18916        private void checkCaller() {
18917            if (mCallingUid != Binder.getCallingUid()) {
18918                throw new SecurityException("Caller " + mCallingUid
18919                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18920            }
18921        }
18922
18923        @Override
18924        public void finishAndRemoveTask() {
18925            checkCaller();
18926
18927            synchronized (ActivityManagerService.this) {
18928                long origId = Binder.clearCallingIdentity();
18929                try {
18930                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18931                    if (tr == null) {
18932                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18933                    }
18934                    // Only kill the process if we are not a new document
18935                    int flags = tr.getBaseIntent().getFlags();
18936                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18937                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18938                    removeTaskByIdLocked(mTaskId,
18939                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18940                } finally {
18941                    Binder.restoreCallingIdentity(origId);
18942                }
18943            }
18944        }
18945
18946        @Override
18947        public ActivityManager.RecentTaskInfo getTaskInfo() {
18948            checkCaller();
18949
18950            synchronized (ActivityManagerService.this) {
18951                long origId = Binder.clearCallingIdentity();
18952                try {
18953                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18954                    if (tr == null) {
18955                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18956                    }
18957                    return createRecentTaskInfoFromTaskRecord(tr);
18958                } finally {
18959                    Binder.restoreCallingIdentity(origId);
18960                }
18961            }
18962        }
18963
18964        @Override
18965        public void moveToFront() {
18966            checkCaller();
18967
18968            final TaskRecord tr;
18969            synchronized (ActivityManagerService.this) {
18970                tr = recentTaskForIdLocked(mTaskId);
18971                if (tr == null) {
18972                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18973                }
18974                if (tr.getRootActivity() != null) {
18975                    moveTaskToFrontLocked(tr.taskId, 0, null);
18976                }
18977            }
18978
18979            startActivityFromRecentsInner(tr.taskId, null);
18980        }
18981
18982        @Override
18983        public int startActivity(IBinder whoThread, String callingPackage,
18984                Intent intent, String resolvedType, Bundle options) {
18985            checkCaller();
18986
18987            int callingUser = UserHandle.getCallingUserId();
18988            TaskRecord tr;
18989            IApplicationThread appThread;
18990            synchronized (ActivityManagerService.this) {
18991                tr = recentTaskForIdLocked(mTaskId);
18992                if (tr == null) {
18993                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18994                }
18995                appThread = ApplicationThreadNative.asInterface(whoThread);
18996                if (appThread == null) {
18997                    throw new IllegalArgumentException("Bad app thread " + appThread);
18998                }
18999            }
19000            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19001                    resolvedType, null, null, null, null, 0, 0, null, null,
19002                    null, options, callingUser, null, tr);
19003        }
19004
19005        @Override
19006        public void setExcludeFromRecents(boolean exclude) {
19007            checkCaller();
19008
19009            synchronized (ActivityManagerService.this) {
19010                long origId = Binder.clearCallingIdentity();
19011                try {
19012                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19013                    if (tr == null) {
19014                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19015                    }
19016                    Intent intent = tr.getBaseIntent();
19017                    if (exclude) {
19018                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19019                    } else {
19020                        intent.setFlags(intent.getFlags()
19021                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19022                    }
19023                } finally {
19024                    Binder.restoreCallingIdentity(origId);
19025                }
19026            }
19027        }
19028    }
19029}
19030